scp in a chroot jail
This guide is for allowing a user to login via SSH and/or use scp to copy files to a system. I’m on CentOS 7 and most of the documentation I found does not address this particular situation. They either use jailkit, which is not available in the stock repository for CentOS 7, or incorrectly declare that SSH’s internal-sftp allows scp, even rsync.
This is a manual recipe for making a chroot jail that allows scp and ssh login that requires nothing beyond the base install of a CentOS 7. This is derived from a good article by Allan Feid.
Add a user that will be allowed to ssh/scp into the system. In our example we’ll use “vagabond”. Be sure to set a sensible password:
sudo useradd vagabond
sudo passwd vagabond
With useradd there will be a home directory for vagabond, but the permissions are setup wrong for this use case. Ownership needs to be root and permissions 755:
sudo chown root.root /home/vagabond
sudo chmod 755 /home/vagabond
Setup all the directories needed. This needs to emulate the / directory to a bare minimum. We need a dev, etc, lib, usr, and bin directory as well as /usr/bin/.
sudo mkdir -p /home/vagabond/{dev,etc,lib,lib64,usr,bin,home/vagabond}
sudo mkdir -p /home/vagabond/usr/bin
With above we also created a home directory for vagabond which we need to allow vagabond to actually write to:
sudo chown vagabond.vagabond /home/vagabond/home/vagabond
You also need the /dev/null file:
sudo mknod -m 666 /home/vagabond/dev/null c 1 3
Fill up the etc directory with a few minimum files:
sudo cp /etc/ld.so.cache /etc/ld.so.conf /etc/nsswitch.conf /etc/hosts /home/vagabond/etc
Once this is done you need to figure out what commands you want accessible by the limited users. In this case I only want the users to be able to get into bash, use ssh, scp, ls, cp, rm, mkdir and rmdir. So you must copy the needed binaries to the jail.
sudo cp /usr/bin/bash /usr/bin/ls /usr/bin/ssh /usr/bin/scp /usr/bin/cp /usr/bin/rm /usr/bin/mkdir /usr/bin/rmdir /home/vagabond/usr/bin
Now that you’ve got all the binaries in place, you need to add the proper shared libraries. To find out what libraries are needed you can run ldd /path/to/bin. The output looks similar to this:
[user@host ~]$ ldd /usr/bin/ls
linux-vdso.so.1 => (0x00007fff349f3000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f21de29d000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007f21de098000)
libacl.so.1 => /lib64/libacl.so.1 (0x00007f21dde8e000)
libc.so.6 => /lib64/libc.so.6 (0x00007f21ddacd000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f21dd86c000)
liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f21dd646000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f21dd442000)
/lib64/ld-linux-x86-64.so.2 (0x00007f21de4c8000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007f21dd23d000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f21dd020000)
You have to manually copy each file to the lib or lib64 directory in your jail. Doing things manually is pretty error prone, but given that I don’t want to download anything or run scripts, I use this long shell one-liner:
ldd /usr/bin/bash /usr/bin/ls /usr/bin/ssh /usr/bin/scp /usr/bin/cp /usr/bin/rm /usr/bin/mkdir /usr/bin/rmdir | awk ‘{ print $3 }’ | egrep -v ^’\(‘ | sort | uniq | xargs -I files sudo cp files /home/vagabond/lib64/
Be sure to adjust the list of files you want to run ldd on to match the files you decided to copy and to adjust the path of the lib or lib64 directory where you are copying them.
Then manually copy ld-linux library, which is not referenced by ldd:
sudo cp /lib64/ld-linux* /home/vagabond/lib64/
Now we edit SSH “/etc/ssh/sshd_config” file to allow the user to login and to automatically jail them:
Subsystem sftp internal-sftp
Match Group sftp
ChrootDirectory %h
ForceCommand internal-sftp
AllowTcpForwarding no
service sshd restart
su vi /etc/ssh/sshd_config
Add the following at the end:
Match User vagabond
X11Forwarding no
AllowTcpForwarding no
ChrootDirectory %h
PasswordAuthentication yes
The key line here is ChrootDirectory; this is what will place the user in the chroot jail.
On top of that I allow PasswordAuthentication for this special user because I typically do all my SSH authentication with PubkeyAuthentication and ban PasswordAuthentication.
Save the file and restart the SSH server:
sudo service sshd restart