Chrooted SFTP for Linux

I had a few problems recently when I was trying to set up chrooted SFTP for a single user on a CentOS6 server. Whichever set of instructions I followed, I couldn’t get it to work for me. Eventually, combining information from a number of sources, I got it to work. Here’s how.

First create the user account. You can use /sbin/nologin for their shell as they’re never actually going to log in. Install the ssh keys and check that everything works as normal. I’ll assume that the user in this instance is called import and their group is named the same.

Edit /etc/ssh/sshd_config. I added to the end:

Match User import
    ChrootDirectory /srv/chroot/%u
    AllowTCPForwarding no
    X11Forwarding no
    ForceCommand internal-sftp

You can match more than one user, or a group if need more than one SFTP account. The %u here is replaced by the username. If you want to restrict people to their home directories use %h. I also had to change this line in the same
file:

Subsystem  sftp  /usr/libexec/openssh/sftp-server

to read:

Subsystem sftp  internal-sftp

Restart ssh using service sshd restart.

Create the chroot directory. In this case /srv/chroot/import. Make sure this and all parent directories are owned by root and not writeable by “group” or “other”. For example:

# mkdir -p /srv/chroot/import
# chown root:root /srv
# chown root:root /srv/chroot
# chown root:root /srv/chroot/import
# chmod 755 /srv
# chmod 755 /srv/chroot
# chmod 755 /srv/chroot/import

If you see an error in the logs relating to the permissions on the chroot directory later when you’re testing, it’s probably because you’ve gone wrong here. The ssh server checks the ownership and access rights for all the components of the chroot path.

Obviously there’s going to be a bit of trouble when our import user tries to upload their files here, because their chroot directory is only writeable by root. sshd won’t let you get away with changing this though, so create a subdirectory for uploads and allow the import user to write to it:

# mkdir /srv/chroot/import/upload
# chown import:import /srv/chroot/import/upload
# chmod 700 /srv/chroot/import/upload

At this point it should all work. SELinux can interfere with things, but that’s a whole different bag of oysters:

$ sftp import@10.20.30.40
Connected to 10.20.30.40.
sftp> ls
upload  
sftp> cd upload
sftp> pwd
Remote working directory: /upload
sftp> put testfile 
Uploading testfile to /upload/testfile
testfile                                  100% 2180     2.1KB/s   00:00    
sftp> ls
testfile
sftp> quit
$ 

This entry was posted in Computing, Linux. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *