CHRoot Jail on CentOS & RedHat

Another geeky “unloading the brain” post.

Setting Up chroot jail for SFTP on CentOS 5.x

Update: While these instructions were intended originally for RedHat-based flavors of Linux, I found that it could also be used with Debian-based Linuxes and even OSX. For OSX, skip all of the compiling information and go right to the sshd_config section below.

FTP is insecure in that the data sent over it is not encrypted. Login IDs, passwords, commands, and the raw data could be intercepted by malicious third parties through whom the traffic travels.

The solution is to use a natively secure protocol, like SSH. Or, more specifically SFTP, which is a subprotocol of the SSH encryption suite. The benefit of SSH is that at no time is data sent in an unencrypted manner. There are also built-in provisions to detect potentially malicious attacks. And as a fringe benefit, only one port needs to be open instead of FTP, which may require several.

There are drawbacks, though. By default, a user who has an SSH account, which is required for SFTP to function, can also run commands on your server. Also, any SSH user will, by default, have visibility to your entire filesystem.

Those issuse are by default. We can change those defaults by locking them in their own home folder and jailing them to the SFTP protocol only.

Here’s how to do it in RedHat and CentOS versions 5.x

First, become root — everything you’ll do for the next few minutes will be as root.

sudo su –

Now, install the GCC compiler:

yum -y install gcc

We’ll need newer versions of ZLIB, OpenSSH, and OpenSSL. We’ll be compiling these from source.

cd /tmp

Now, build some target directories and temporary directories:

mkdir -p /{opt,tmp}/{zlib,openssl,openssh}

Fetch all of the needed source packages.

wget -o /tmp/zlib/zlib125.zip http://www.zlib.net/zlib125.zip

wget -o /tmp/openssl/openssl-0.9.8k.tar.gz http://www.openssl.org/source/openssl-0.9.8k.tar.gz

wget -o /tmp/openssh/openssh-5.3p1.tar.gz ftp://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-5.3p1.tar.gz

Decompress the packages:

cd /tmp/zlib

unzip zlib125.zip

cd /tmp/openssl

tar xfvz openssl-0.9.8k.tar.gz

cd /tmp/openssh

tar xfvz openssh-5.3p1.tar.gz

Now, we drop into each source directory to configure, compile, and install each package to a new destination:

cd /tmp/zlib/zlib-1.2.5

We’ll just use all of the defaults for configuration — so just do:

./configure

And compile:

make

Then install. Here, though, we’re telling it to install to /opt/zlib/

make install prefix=/opt/zlib/

Now OpenSSL, the encryption suite:

cd /tmp/openssl/openssl-0.9.8k

For OpenSSL, we need to specify at configuration that it will live in /opt/openssl:

./config –prefix=/opt/openssl –openssldir=/opt/openssl

Compile, test, and install:

make

make test

make install

Be sure to wait for each command to finish before moving on to the next.

And, finally, OpenSSH, which is the SSH suite:

cd /tmp/openssh/openssh-5.3p1

With OpenSSH, we need to define several items at configuration: Installation directory, location of the new SSL libraries to use, where xauth lives, and where our new zlib libraries are:

./configure –prefix=/opt/openssh –with-ssl-dir=/opt/openssl –with-xauth=/usr/bin/xauth –with-zlib=/opt/zlib

Make and install:

make

make install

Now that it’s installed, we need to edit our existing SSH startup script in /etc/init.d/sshd to point to the new binaries. Edit /etc/init.d/sshd with your favorite editor and replace the following variables with the values shown:

KEYGEN=/opt/openssh/bin/ssh-keygen 

SSHD=/opt/openssh/sbin/sshd

RSA1_KEY=/opt/openssh/etc/ssh_host_key

RSA_KEY=/opt/openssh/etc/ssh_host_rsa_key

DSA_KEY=/opt/openssh/etc/ssh_host_dsa_key

Edit /opt/openssh/etc/sshd_config — the new configuration file for SSH — and throw out anything starting with “^Subsystem” then add a new Subsystem section to the end of the file. Here’s one way:

cat /opt/openssh/etc/sshd_config | grep -v “^Subsystem” > /opt/openssh/etc/sshd_config.new

cat <> /opt/openssh/etc/sshd_config.new

#

#–BEGIN CHROOT JAIL ADDITIONS

Subsystem sftp internal-sftp

Match Group jailedsftp

  ChrootDirectory /var/sftp/%u

  ForceCommand internal-sftp

  AllowTcpForwarding no

#–END CHROOT JAIL ADDITIONS

EOF

cat /opt/openssh/etc/sshd_config.new > /opt/openssh/etc/sshd_config

rm -f /opt/openssh/etc/sshd_config.new

Restart the SSH daemon to make sure it starts up correctly:

/etc/init.d/sshd restart

You’ll notice in our chroot jail additions that we specify a ChrootDirectory of /var/sftp/%u, so let’s create that now and assign permissions to it.

mkdir -p /var/sftp

chown root:root /var/sftp 

chmod 755 /var/sftp

We’re limiting access through SSH to SFTP only for users that are members of a local group called jailedsftp:

groupadd jailedsftp

Because of the way the sftp jail works, we need to adjust our skel so the user has a couple of important directories. First is the .ssh directory so the user can drop off his own authorized_keys file:
mkdir /etc/skel/.ssh

It needs particular permissions:

chmod 700 /etc/skel/.ssh

And, we’ll need a data directory in the user’s home directory so they have somewhere to work. The reason for this is because with this method, the user’s home directory is owned by root, not the user himself. Because of that, the user can’t, by default, create any objects. You could call this anything — public_html for example. I use ‘data’.

mkdir /etc/skel/data

That’s it. SSH will now limit user access to SFTP for anyone in the jailedsftp group.

Adding New Users

Collect some important information to drop into some variables.

fullname=”Full Name Here”

username=usernamegoeshere

useremail=email@domain.com

userpass=PassWordHere

You may want to wrap that collection in some appropriate scripting to validate all of the inputs. For example, a password should not have !, \, or spaces unless you know how to delimit those. A username cannot have any spaces. An email address should have an “@” and a valid domain, etc. Standard Unix rules apply — and, on that note, Full Name and UserEmail are entirely optional.

Now, we add the user:

useradd -c “${fullname} (${useremail})” -b /var/sftp -g jailedsftp -p `perl -e ‘print crypt(“${userpass}”,”FF”),”\n”‘` ${username}

Look up the man page for useradd to understand what’s going on there. Essentially, we’re specifying where home should be, what the user’s primary group is, the password, and actual login ID.

And, finally, we need to change ownership of the user’s home directory to root with correct permissions:

chmod 755 /var/sftp/${username} && chown root:root /var/sftp/${username}

Don’t propogate those permissions though. The .ssh and data directories in the user’s home need to be owned by the user and need to have the permissions we built into the skel.

Test:

Grab your favorite SSH program and try to connect as a user that is not a member of jailedsftp. It should work fine. If it doesn’t something is broken.

Now, try your new user through SSH. It should fail.

Try your regular user through SFTP. It should work fine with the regular user’s real home directory.

Now try your jailedsftp user through SFTP only. It should log in and you should see the appropriate directories. The user should not be able to change to any parent directories, nor create (or delete) any objects in his home directory except for those that we create for him. In this case, .ssh and data.

Let’s Think About This…

I don’t get too involved in Interstate politics — we have enough local problems to keep us quite busy — but this just stands out as a head-scratcher.

I’ll quote the same paragraph as the story, but… must… correct… teh… stoopid. So we’ll do this one sentence at a time:

The presumption that someone who carries a gun is safer is false.

So armed law enforcement aren’t safer? Think about it: let’s say you’re a crook and you’re going to rob someone at knifepoint (or gunpoint) — are you going to choose somebody who you know is armed? Of course not. You’re looking for a victim — not a fight.

A study by the University of Pennsylvania School of Medicine found that those without guns are four times safer than those with guns when confronted by an armed assailant.

Because, hey, I always go to a doctor for expert advice about firearms. Just like I go to an airline mechanic for help with my computer, a dentist for service on my truck, and to the kid at the counter at McDonalds for help with my taxes.

Having and wearing a gun comes with heavy responsibilities and risks.

Yes, it does. But, telling people that they can’t handle the responsibility to defend themselves is a bit like telling them, “Don’t worry, Bobby… mommy will always be here to protect you…”

The most well trained people in the United States with guns are your police, and yet we are still targets of those who would commit crimes.

Um, no, they aren’t. There are several cases where police officers have made extraordinarily stupid moves with firearms. There are many military units and even run of the mill civilians who are far better trained than law enforcement in the use of firearms. The reason police are targets of those who commit crimes is, hey, because you’re cops! It’s your job to intervene when a crime is in progress. Have you ever wondered why so many people that the police interact with are criminals?

We are also very aware that every physical confrontation we have involves at least one gun.

Emphasis mine. No fucking kidding. That your own duty weapon that’s involved. Sure, it may be holstered, but it’s still involved.

Please do not be naïve about guns.

Pot? Meet Kettle.

If you are extremely not well trained and capable of retraining a weapon while under physical assault, you are much more likely to be shot or killed by the very gun you carry.

Okay, that sentence makes even less sense.

Bottom line is that these people are essentially telling you: We know there’s crime — and we want to make it easier for criminals to do and get what they want. Just lie back and think of England.