sftp on an ubuntu server with “chroot jail”
November 9th, 2008SSH is a wonderful thing.
If you you want to securely log into a remote machine there is nothing better but ssh has few other useful tricks up it’s well encrypted sleeves. You can tunnel TCP traffic, forward an X11 session and transfer files with sftp.
In Ubuntu by default any user who can login via ssh can also sftp and transfer files to an from the machine according to their permissions on that machine. Most graphical ftp clients support sftp these days and it can be very useful.
However what if you want someone to be able to securely transfer files to and/or from your machine but you don’t want them to be able to login or see any other part of the file system but their own personal directory? By default any user who can log in can seeother parts of the file system; in order to stop this we need a chroot jail.
The current implementation of ssh in use on Ubuntu (and just about everywhere else) is OpensSSH which is part of the OpenBSD project. The latest version as of writing is 5.1 and this ships in the repos for intrepid ibex.
In version 5.1 of OpenSSH setting up an chroot jail is much easier.
Hardy, on the other hand, ships with version 4.7 and this is not nearly as easy.
There is a good tutorial here that explains how to do this by compiling everything from source but this is not necessary on intrepid. All that is needed is a few small edits to a config file and some playing with directories.
Here’s how it works:
First, if it’s not installed already install openssh-server.
sudo apt-get install openssh-server
Next edit /etc/ssh/sshd_config (sudo with your favourite editor)
Change the line
Subsystem sftp /usr/lib/openssh/sftp-server
to
Subsystem sftp internal-sftp
next add the following to the end of the file
Match Group sftponly
ChrootDirectory %h
ForceCommand internal-sftp
AllowTcpForwarding no
What does this do?
In simple terms it causes the three options (ChrootDirectory, ForceCommand and AllowTcpForwardinf) to be set to the vaules given for any user that belongs to the group sftponly. Other users are are not affected.
There are a few more things that will need to be done.
First, users need to be created and added to the sftponly group:
sudo groupadd sftponly
sudo useradd joe
sudo usermod -s /bin/false
sudo usermod -d /home/joe
sudo usermod -g sftponly
Here we have added the group; added a user, joe; stopped him from logging in normally by setting his shell to false with -s; set his home directory with -d; and added him to the group sftponly.
Next set a password
passwd joe
One final thing we need to do to allow chroot sftp access for joe is to set him home directroy as owned by root. A condition of the chroot jail is that all directories in the path to the jail must be owned by root. The /home directory should already be owned by root but now set the user’s home directory as owned by root and create another directory inside it, owned by the user, to allow uploading.
sudo chown root:root /home/joe
sudo mkdir -p /home/joe/upload
sudo chown joe:sftponly /home/joe/upload
Now if joe will not be able to login via ssh but if he logs in via sftp all he will see is an upload directory he will not be able to navigate up through the filesystem.
Summary:
- Make a few changes to /etc/ssh/sshd_config
- Create a group for sftp only users
- Create user and set group, home directory, shell & password
- Make root the owner of the user’s home director.
- Create an upload directory owned by the user.




















