chrooted SFTP access with OpenSSH
chroot jails ring-fence users, files, & processes. While the theory – privilege isolation for damage limitation – is singular, the practice has many techniques and purposes. Cue SSH+SFTP …
Let’s employ OpenSSH‘s advanced functionality to limit an SFTP area that can be used to share files, for example to offer a developer safe access to our web files, complete with logging, and allowing us to disable the insecure FTP service and close its port. (That bit’s for another guide, another time.)
You’ll need OpenSSH 5.2+ to gain from all the features used here.
Hey vpsBabes! Please excuse the relatively shoddy formatting of this piece …
As you may know, I’m rebuilding vpsBible to improve usability for noobs and, because I’m busy remastering (every last inch of) vpsB content in the process, I’ve kind of thrown together this tut for this site’s doomed old skin.
This ultra-tested Debian-based guide is a section from my book WordPress 3 Ultimate Security. Hands up, I’ve copy/pasted it pretty much in its entirety.
The theory, at least, works for any Tux box and the practice with any content platform, not just the mighty WP which is exampled.
Want more on chroots, privilege isolation, secure protocols like SFTP? Course you do. Hang about. Grab a feed.
guv
Setup the SFTP User, the SFTP Group & SSH
Assuming root – so that’s with sudo -i – for this first section, we swap the export value, someuser, for some username of the newly invited user, then paste the four lines of code to create a group, add the new user with a regular home directory (which he’ll never see, but which will contain a public authentication key) and add the user to both his and the new sftpusers groups. We’ll also neuter the user’s functionality with the /bin/false shell. If you don’t want the user to use authentication keys, which is inadvisable, then create a password too:
export USER=someuser groupadd sftpusers useradd -d /home/$USER -G sftpusers -s /bin/false $USER passwd $USER
Now for the jail and permissions. The chroot, or what for the new user changes to root – aka, the Linux file system root aka / – is the chroot-sftp directory and inside we have the dev folder that we need for logging and the home directory to contain any SFTP users and their respective folders. More fun theory another day. Paste this:
mkdir -m 751 /home/chroot-sftp /home/chroot-sftp/{dev,home}
mkdir -m 770 /home/chroot-sftp/home/$USER
chown root:$USER /home/chroot-sftp/home/$USER
We need to enable logging in the isolated chroot …
echo '$AddUnixListenSocket /home/chroot-sftp/dev/log :programname, isequal, "internal-sftp" -/var/log/sftpusers.log :programname, isequal, "internal-sftp" ~ ' > /etc/rsyslog.d/chroot-sftp.conf
… to restart the logging service …
service rsyslog restart
… and add a logrotate entry to keep the logs at a fair size:
echo '/var/log/sftpusers.log {
weekly
missingok
rotate 52
compress
delaycompress
postrotate
invoke-rc.d rsyslog reload > /dev/null
endscript
}' > /etc/logrotate.d/chroot-sftp
Now for the safer alternative to a password, authentication keys. (Search this site for the setup guides and lengthy explanation.) With your public key at the ready, create the SSH folders, set some rights, and add the public key into a new file. Be lazy, just paste this:
mkdir -m 750 /home/$USER /home/$USER/.ssh chown root:$USER /home/$USER /home/$USER/.ssh nano /home/$USER/.ssh/authorized_keys
… and add the key, saving the file.
Now open the OpenSSH configuration file:
nano /etc/ssh/sshd_config
Look for Subsystem sftp /usr/lib/openssh/sftp-server, #comment it out and replace with Subsystem sftp internal-sftp -l VERBOSE. Just ‘cos I’m nice, the edit looks like this:
#Subsystem sftp /usr/lib/openssh/sftp-server Subsystem sftp internal-sftp -l VERBOSE
Below that, add a match block to apply to all new members of the sftpusers group:
Match group sftpusers ChrootDirectory /home/chroot-sftp ForceCommand internal-sftp -l VERBOSE AllowTcpForwarding no AllowAgentForwarding no X11Forwarding no
And restart the ssh service:
/etc/init.d/ssh restart
SFTP users need their private key, which you provide to them as the partner to the public key, linking it with their SFTP client. Again, this site’s SSH docs more than explain this so no excuses! To test the jail, you can also enter it, using a terminal, like this:
sftp someuser@123.45.67.890
Or if you’re using a non-standard SSH port, swapping the port, here’s the command:
sftp -oPort=54321 someuser@123.45.67.890
Bin the Insecure FTP Service & Firewall the Port
Neither the service nor the open port are needed now. In fact they remain a liability.
You can use a tool such as sysv-rc-conf to disable the FTP daemon (or service or whatever else its called). Then again, you’d do better to uninstall the program. Neither will you want its port, 21, to remain open so add a rule to your firewall. This is also detailed here at vpsBible so have a look for that.
Providing a Secure Workspace
One good use for this system is to provide a user with a secure mount of whatever files. This is ideal, for example, for that colleague or web developer who needs access purely to, say, the wp-content/themes folder in a WordPress installation.
Just as you edited the username at the top of the tut, now edit the value of the path to share in this first export value command, then paste the following commands (which I guess I’ll explain as we go along):
export SHARE_PATH=/example/path/to/wp-content/themes
Now to ensure Apache’s group ownership of the source files, the ones to be shared. Swap the group as needed, for example if you use something like webmasters rather than www-data. (HINT: vpsBible tends to use webmasters):
chown -R :www-data $SHARE_PATH && chmod -R g+s $SHARE_PATH
Now create a SHARE directory in the user’s file path and mount the web files there:
mkdir /home/chroot-sftp/home/$USER/SHARE mount --bind $SHARE_PATH /home/chroot-sftp/home/$USER/SHARE
Being super-cautious, the new user can only read the content of the share. We’ll be generous and make one exception, a development folder owned by the new user yet which our Apache group, in this scenario, can also work with:
mkdir /home/chroot-sftp/home/$USER/SHARE/devTheme chown $USER:www-data /home/chroot-sftp/home/$USER/SHARE/devTheme
Now then. Listen up …
Do not delete the SHARE without first unmounting it or the source, your original files, will be deleted.
More about that in a tick.
chrooted SFTP: from Theory to Practice
With this system, our new user can download the original web files, edit them locally before uploading them to the development folder from where, due to the mount, they can be directly tested. This is super-sodding-secure and cool-as-cats for any site development work but, for WordPress theme files, for example, you could use a plugin such as Theme Test Drive to swap to the development theme without affecting the live theme.
Geddit? Have a smile!
Deleting SFTP Users Safely
As I said, if you’ve mounted anything, then you must unmount before deleting the user, else your source content is deleted. You can check your mounts with the command mount -l. Then swap the user and path here, copy-pasting:
export USER=someuser umount /home/chroot-sftp/home/$USER/SHARE userdel $USER && rm -R /home/chroot-sftp/home/$USER /home/$USER
OK. Bit of a palaver but we got there. Have a cigar.


Got a Question? Want to Comment?
This site has no comments system. We've got a better system!
Please use the link at the top of the post and goto this topic's forum thread:-
For those posts ported from Guvnr.com (pre-Feb/2010), archive comments remain.
Handy info from these comments is in the process of being ported to the forum and attributed to the original author.
If you think this idea sucks, let me know.
Thank you.