Chrooted sftp with key authorization

This post will show you how to set-up chrooted sftp for a set defintion of users. These users can only sftp to this chroot, no scp, ssh, ftp, x11 or portforwarding. We assume here that selinux is enabled, if you don’t run selinux you can skip the section for setting the right context.

Change SSHD configuration
On your sftp server add the following at the bottom of your sshd config

Subsystem sftp internal-sftp
#match block needs to be at the end of the sshd config, block will end at the following match or end of config file
Match group sftponly
ChrootDirectory /sftp/home/%u
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp

It’s possible you have ‘Subsystem sftp /usr/libexec/openssh/sftp-server’ in your config, you can comment or delete this.

Reload sshd
systemctl reload sshd

Set-up directories with correct permissions and add user
Create a group for the sftp only users
groupadd sftponly

If it doesn’t exist create a dir holding the homedirs and one holding the public ssh keys
mkdir -p /sftp/{home,ssh}

Create the user which is allowed to use sftp, important is to change the shell to false, add the account to the sftponly group and set the homedir to the ssh dir
useradd -s /bin/false -G sftponly -d /sftp/ssh/foo foo

The homedir needs to be owned by root for the chroot environment. The user is not allowed to write in the root of the chroot, but another seperate dir. In this example the upload dir. Permissions are important here for the sftp chroot to work and security reasons.
chown root:foo /sftp/home/foo
chmod 750 /sftp/home/foo
mkdir /sftp/home/foo/upload
chmod 700 /sftp/home/foo/upload
chown foo:foo /sftp/home/upload

Set up ssh public keys
The homedir in /etc/passwd will direct to /sftp/ssh/%u , while the chroot in the sshd config will direct to /sftp/home/%u. This way the user is not able to change his own keys as they are stored out of the chroot homedir and server admin will stay in control of which keys are allowed, since the user can’t modify his ‘own’ authorized_keys file
Create .ssh dir
mkdir /sftp/ssh/foo/.ssh

Add the public key generated for this purpose to the authorized_keys
vi /sftp/ssh/foo/.ssh/authorized_keys

Set correct permissions on the directory and file
chown -R foo:foo /sftp/home/foo/.ssh
chmod 700 /sftp/ssh/foo/.ssh
chmod 600 /sftp/ssh/foo/.ssh/authorized_keys

Set selinux context which will survive a relabel
semanage fcontext -a -t ssh_home_t "/sftp/ssh/.*/.ssh(/.*)?"

Restore the context on the files
restorecon -Rv /sftp/ssh/foo

Leave a comment

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