Chroot SFTP users

OpenSSH supports jailing SFTP users to a directory (using chroot) just by changing its configuration file:

Basically you add the users you want to jail to a linux user group (sftp) and add the following lines to /etc/ssh/sshd_config:

### Comment out the following line:
#Subsystem sftp /usr/lib/openssh/sftp-server
### and replace with:
Subsystem sftp internal-sftp

### And add this "Match" rule to chroot users in the sftp group:
Match group sftp
    X11Forwarding no
    ChrootDirectory %h
    AllowTcpForwarding no
    ForceCommand internal-sftp

Just to be complete, here are the lines to add a new user and add it to the group and set up the permissions for chroot:

addgroup sftp
# fix ownership:
chmod 750 /home/$NEWUSERNAME
# create a writable folder
mkdir /home/$NEWUSERNAME/files
chown $NEWUSERNAME: /home/$NEWUSERNAME/files
# add the user to the group sftp:
adduser $NEWUSERNAME sftp

The reason why you need to set the permissions that way is that if you don't, the chroot will fail. The message for the sftp/ssh user after trying to connect is:

Write failed: Broken pipe
Couldn't read packet: Connection reset by peer

And in the /var/log/auth.log you find an entry like this:

May 20 11:43:59 lion sshd[15393]: pam_unix(sshd:session): session opened for user sftpuser by (uid=0)
May 20 11:43:59 lion sshd[15395]: fatal: bad ownership or modes for chroot directory "/home/sftpuser"
May 20 11:43:59 lion sshd[15393]: pam_unix(sshd:session): session closed for user sftpuser

The reason for this behaviour is that a chroot needs some requirements:

  • root must be the owner of the new user's home directory
  • The group and the others must not have write permissions
  • You can't chroot into a file ^^

Disabling SSH access for those users

This is not needed if you set the setting ForceCommand internal-sftp. But if you are paranoid, you can also disable real shell access for the user by setting the terminal to /bin/false:

usermod -s /bin/false $NEWUSERNAME

Adding basic SSH access again

Remove ForceCommand internal-sftp in the sshd_config to allow other than sftp commands.

To be able to user a shell, it must be available from the inside of the chroot directory. In addition you need to bind some device files in /dev. This is well explained in the section Shell-User on (German).