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 $