January 14, 2007

sftp with chroot

Filed under: tech — Ernest Hymel @ 8:51 pm

Yesterday and today I tackled this beast and finally got it working. Here’s what I did:

I had openssh installed via yum, so first I had to uninstall that, along with it’s dependencies:

yum uninstall openssh

Erased: netdump
Erased: openssh-server
Erased: openssh
Erased: openssh-clients
Erased: openssh-askpass

After lots of reading through google post and trying various methods, I went to http://chrootssh.sourceforge.net/. In their downloads section, they now have patched source files for openssh with the ability for chroot already patched. For my server, I used this one. Here are the steps, including the config options I used.

After lots of reading through google post and trying various methods, I went to . In their downloads section, they now have patched source files for openssh with the ability for chroot already patched. For my server, I used . Here are the steps, including the config options I used.

cd /usr/local/src
wget http://chrootssh.sourceforge.net/download/openssh-4.5p1-chroot.tar.bz2
tar xjf openssh-4.5p1-chroot.tar.bz2
cd openssh-4.5p1-chroot
./configure \
       –prefix=/usr \
       –sysconfdir=/etc/ssh \
       –with-pam \
       –with-tcp-wrappers \
       –with-md5-passwords \
       –with-pid-dir=/var/run
make
make install

The install script copies default config files (according to the options I used above) to /etc/ssh directory. Within that directory, I tightened down things slightly by adding these lines to sshd_config:

AllowUsers user1 user2 user3 etc
PermitRootLogin no

This install also doesn’t come with a startup script, so I pulled one over from backup of the yum/rpm install of openssh. My /etc/init.d/sshd looks like this:

#!/bin/bash
#
# Init file for OpenSSH server daemon
#
# chkconfig: 2345 55 25
# description: OpenSSH server daemon
#
# processname: sshd
# config: /etc/ssh/ssh_host_key
# config: /etc/ssh/ssh_host_key.pub
# config: /etc/ssh/ssh_random_seed
# config: /etc/ssh/sshd_config
# pidfile: /var/run/sshd.pid

# source function library
. /etc/rc.d/init.d/functions

# pull in sysconfig settings
[ -f /etc/sysconfig/sshd ] && . /etc/sysconfig/sshd

RETVAL=0
prog=”sshd”

# Some functions to make the below more readable
KEYGEN=/usr/bin/ssh-keygen
SSHD=/usr/sbin/sshd
RSA1_KEY=/etc/ssh/ssh_host_key
RSA_KEY=/etc/ssh/ssh_host_rsa_key
DSA_KEY=/etc/ssh/ssh_host_dsa_key
PID_FILE=/var/run/sshd.pid

runlevel=$(set — $(runlevel); eval “echo \$$#” )

do_rsa1_keygen() {
        if [ ! -s $RSA1_KEY ]; then
                echo -n $”Generating SSH1 RSA host key: ”
                if $KEYGEN -q -t rsa1 -f $RSA1_KEY -C ” -N ” >&/dev/null; then
                        chmod 600 $RSA1_KEY
                        chmod 644 $RSA1_KEY.pub
                        if [ -x /sbin/restorecon ]; then
                            /sbin/restorecon $RSA1_KEY.pub
                        fi
                        success $”RSA1 key generation”
                        echo
                else
                        failure $”RSA1 key generation”
                        echo
                        exit 1
                fi
        fi
}

do_rsa_keygen() {
        if [ ! -s $RSA_KEY ]; then
                echo -n $”Generating SSH2 RSA host key: ”
                if $KEYGEN -q -t rsa -f $RSA_KEY -C ” -N ” >&/dev/null; then
                        chmod 600 $RSA_KEY
                        chmod 644 $RSA_KEY.pub
                        if [ -x /sbin/restorecon ]; then
                            /sbin/restorecon $RSA_KEY.pub
                        fi
                        success $”RSA key generation”
                        echo
                else
                        failure $”RSA key generation”
                        echo
                        exit 1
                fi
        fi
}

do_dsa_keygen() {
        if [ ! -s $DSA_KEY ]; then
                echo -n $”Generating SSH2 DSA host key: ”
                if $KEYGEN -q -t dsa -f $DSA_KEY -C ” -N ” >&/dev/null; then
                        chmod 600 $DSA_KEY
                        chmod 644 $DSA_KEY.pub
                        if [ -x /sbin/restorecon ]; then
                            /sbin/restorecon $DSA_KEY.pub
                        fi
                        success $”DSA key generation”
                        echo
                else
                        failure $”DSA key generation”
                        echo
                        exit 1
                fi
        fi
}

do_restart_sanity_check()
{
        $SSHD -t
        RETVAL=$?
        if [ ! “$RETVAL” = 0 ]; then
                failure $”Configuration file or keys are invalid”
                echo
        fi
}

start()
{
        # Create keys if necessary
        do_rsa1_keygen
        do_rsa_keygen
        do_dsa_keygen

        cp -af /etc/localtime /var/empty/sshd/etc

        echo -n $”Starting $prog: ”
        $SSHD $OPTIONS && success || failure
        RETVAL=$?
        [ “$RETVAL” = 0 ] && touch /var/lock/subsys/sshd
        echo
}

stop()
{
        echo -n $”Stopping $prog: ”
        if [ -n “`pidfileofproc $SSHD`” ] ; then
            killproc $SSHD
        else
            failure $”Stopping $prog”
        fi
        RETVAL=$?
        # if we are in halt or reboot runlevel kill all running sessions
        # so the TCP connections are closed cleanly
        if [ “x$runlevel” = x0 -o “x$runlevel” = x6 ] ; then
            killall $prog 2>/dev/null
        fi
        [ “$RETVAL” = 0 ] && rm -f /var/lock/subsys/sshd
        echo
}

reload()
{
        echo -n $”Reloading $prog: ”
        if [ -n “`pidfileofproc $SSHD`” ] ; then
            killproc $SSHD -HUP
        else
            failure $”Reloading $prog”
        fi
        RETVAL=$?
        echo
}

case “$1” in
        start)
                start
                ;;
        stop)
                stop
                ;;
        restart)
                stop
                start
                ;;
        reload)
                reload
                ;;
        condrestart)
                if [ -f /var/lock/subsys/sshd ] ; then
                        do_restart_sanity_check
                        if [ “$RETVAL” = 0 ] ; then
                                stop
                                # avoid race
                                sleep 3
                                start
                        fi
                fi
                ;;
        status)
                status $SSHD
                RETVAL=$?
                ;;
        *)
                echo $”Usage: $0 {start|stop|restart|reload|condrestart|status}”
                RETVAL=1
esac
exit $RETVAL

I was getting an error message using this startup script. I’m not sure what it’s for, but this script wants to copy /etc/localtime to /var/empty/sshd/etc/. Make sure this directory exists:

mkdir /var/empty/sshd
mkdir /var/empty/sshd/etc
cp -af /etc/localtime /var/empty/sshd/etc/

With the above, all the usual ssh stuff works, including sftp without chroot. 

OK, now to set up chroot. This took me forever to figure out, though as listed here it is simple.

First, set the user’s home directory in /etc/passwd. The key is to use a ‘.’ where you want the user’s root directory to be. For example, change the user’s home directory to something like:

/path/to/chroot_dir/./home/user

of course, create the /path/to/chroot_dir/home/user directory first. When the user logs in via ssh (or sftp, etc), he/she will see their home directory only as /home/user, and will be in “jail” within that directory structure. The rest of the system will be off limits.

Sounds easy enough. The problem is that it takes a lot more. Once the user logs in, they have to have access to system commands (like ls, mkdir, etc., as well as a shell like bash). There are several google references to how to do this, including (in no specific order):

The bottom line on all of these is that you have to create /bin, /dev, /etc/, /lib, /usr, and within the new jail, then these should be populated with the appropriate files.

cd /path/to/chroot
mkdir bin dev etc lib usr
mkdir usr/bin usr/lib usr/libexec
cd /bin
cp -a bash cp ls mkdir mv rm rmdir /path/to/chroot/bin
cp -a /usr/bin/ldd /path/to/chroot/usr/bin/
cp -a /usr/libexec/sftp-server /path/to/chroot/usr/libexec/

All web pages now talk about making sure all the appropriate library files are copied over. ldd can tell you which ones you need for each executable (e.g., ‘ldd /bin/cp’ will tell you the libraries needed) for the cp command. These need to be copied to the appropriate directory with the jail. The problem is that ldd apparently doesn’t always tell the whole story, and others are sometimes needed. Symptoms would be that once a connection is made, it immediately drops with an error “Connection closed” with no further explanation, even in the log files. The solution suggested by many is to simply copy over all the lib files:

cp -a /lib/lib*.* /path/to/chroot/lib/
cp -a /usr/lib/lib*.* /path/to/chroot/usr/lib/

On my system, the above steps allow a chroot login to occur via ssh with everything working correctly. Unfortunately, this doesn’t work with sftp, and attempts to connect via sftp with a user in chroot fails with the “Connection closed” error. The secret for me, after a LOT of reading through google posts, was to copy over /etc/passwd to the jail.

cp -a /etc/passwd /path/to/chroot/etc/

Make sure that file is not world-readable:

chmod 640 /path/to/chroot/etc/passwd

OK! Now all seems to work. Hope this helps someone (or me in the future).

December 27, 2006

My wife is a superhero

Filed under: Amy — Ernest Hymel @ 4:30 pm

I know that most husbands believe their wife is the best there is (or at least they should believe that!), but for me it’s pretty much true. That she loves me deeply is obvious, and I am blessed to have her in my life. Besides caring for me, she spends her minutes and days thinking about and caring for animals, dogs and cats in particular.  We long ago lost count of how many she has helped, and to list everything she does would take me a long time, but I’ll list a few here. Why do this? Well, this blog is for me and more than likely no one else will ever read it. But my “job”, as Amy’s husband, is to love her above all else. As we all know, marriage is work, and part of that work is continuously reminding myself just how blessed I am to have a partner in life like Amy.

Every day, Amy cares for our 7 dogs and 10 cats by feeding them twice, scooping litter at least twice, and continuously talking and singing and loving them. They are spoiled much more than most people in the world, and it truly shows. They love it and we have wonderful companions in our home as a result.

Every day, Amy also goes into our garage where she currently has 18 foster cats. She feeds them, scoops litter, and of course talks and sings and loves them warmly. Even living in the garage, they are also spoiled more than most people. One of them has a broken front left with a cast, so she patiently lifts him into a freshly-cleaned litter box, lays him down, waits for him to do his business, then she cleans him off and holds him for a while before continuing her cleaning and caring.

Every day, Amy screens people that contact her wanting to adopt one of the foster cats. She turns away those undeserving of the privilege (“I want the cat to live outside only,” or “I will mutilate… I mean declaw… to save my furniture.”). Too often the potential adopters themselves fall through when they get down to the adoption stage (“I wanted a kitten, but this cat is already 8 months old,” or “I wanted an all black cat, and this one has 5 white hairs on it’s underside!”… true stories). As Amy works so hard to locate a safe new home for the foster cats, shrugging off each adoption that falls through and continuing the search gets tough to do.

Every week, sometimes a few times per week, Amy goes up to the Humane Society of Southeast Texas and photographs all the new dogs and cats that have come in during the week. This is no easy task, photographing nervous, energetic, sometimes sad animals that have often been dumped by their prior owners. She wants to bring most of the home, but she sets aside this strong urge (usually 🙂 ) and dutifully photographs and jots a note about their history. Then she comes home and uploads this information to PetFinder (using a painfully slow server on their end) so that these animals can find a new family to care for them.

Every week, Amy travels to the Vidor Animal Control and rescues as many dogs (and sometimes cats) as she can. She drives those animals back to Beaumont and gives them to me before my drive to Houston to pick up Peter. In Houston, a rescue organization meets me before taking the dogs for grooming, shots, a vet visit, then adoption events at PetSmart so they may also find a new family.

Most days, Amy scours our community website (southeasttexas.com) looking for dogs and cats that seem to be in a dangerous situation (and so need rescuing) or for owners who have lost a pet. She helps everyone she can.

Amy runs the feral cat program within the Humane Society. This amounts to several phone calls every day, even early in the morning or late at night, from people that have contacted the Humane Society for help regarding one or more feral cats. The Humane Society passes Amy’s name and number on, and Amy screens each and every one of these. Those who truly need assistance (and most do) are mailed certificates for free spays or neuters at the Humane Society. Amy’s job is tedious and amounts to secretarial work, but she happily and voluntarily does this job as yet another way to help the animals around us.

Once a month, Amy joins the Humane Society at PetSmart, volunteering her time at adoption events to help get one pet at a time find a new home.

Occasionally, Amy fills in for a regular person on the local TV network news segment called Pet of the Week. Bascially she selects one or two dogs or cats in need of a home and she talks about them for a few minutes live on the evening news.

Very often Amy can be found cleaning cages and walking dogs at the Humane Society. Once while we were driving down Calder Avenue (a very busy street) on our way to a formal dinner, she spotted a mother dog and her puppy dodging traffic. She screamed for me to pull over, and the car was still rolling as she jumped out in her formal gown and high heals, yelled at oncoming traffic to stop and chased after the dogs. When she couldn’t catch them, we drove around a few blocks looking for them. Although we could not find them, I have little doubt that she drove around there for days to come (and asked all of her friends to do the same!!) looking for those dogs.

Once, I was telling my son a story about Amy saving a dog or a cat. He cut me off and yelled, “Super Amy!” He equates Amy to a superhero. Is there any doubt?

Hello world

Filed under: Uncategorized — Ernest Hymel @ 1:32 pm

Does every blog have to start with this one?