Why do we want SFTP? In my case, I wanted a friend of mine to be able to upload some web pages onto my web server without giving him full shell access. I didn't want to install any extra services, possibly opening my system up for attack. I like having as few number of services running as possible. You should too.
There have been a number of solutions for having users only capable of SFTP. scponly is one example, which have been subject for a number of exploits in the last couple of years, and is required to run setuid root. I don't need to tell you why this is bad.
With OpenSSH 4.9 we now have support for a chroot jail by default. This article describes how I configured it. Nothing particularly hard, but I did have to do some research to get it working. There are a few caveats but it's pretty straightforward. When we're done we'll have our users chrooted into /home/user with SFTP only access. Ok, lets go!
First, we want to add a group which will contain all users that will be chrooted:
sudo addgroup sftponly
Next, add all users you want chrooted to this group:
sudo adduser user sftponly
Add this last in your /etc/ssh/sshd_config:
Match group sftponly
ChrootDirectory /home/%u
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
You also need to find and change the line in sshd_config indicated below so it reads like the uncommented line below:
#Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem sftp internal-sftp
The target chroot directory needs to be owned by root:root and be read-only by everyone except root. (More about WHY this is can be found here.) In a default Debian GNU/Linux install, if you want to chroot the user to a path below /home, you first need to remove the setgid bit from /home (if you're like me, you're wondering why /home is setgid in the first place)
sudo chmod g-s /home
Next, create the user directory and set up permissions as such:
sudo mkdir -p /home/user/incoming
sudo chown root:root /home
sudo chown root:root /home/user/
sudo chown user:user /home/user/incoming
Set the users home directory to be /incoming inside the chroot.
sudo usermod -d /incoming user
DONE! You should restart your sshd and confirm the result:
sudo /etc/init.d/ssh restart
sftp user@host