HOWTO: chroot SFTP (only) - OpenSSH 4.9+ Built-in Version

[Return to main index]

Last updated: 23 February 2009
Current version of OpenSSH: 5.2

The Method

Note that on this page, only my Solaris instructions are included, but this should now be sufficiently generic to apply to other platforms.

Step Instructions
1 Download the latest OpenSSH 'portable' source tarball from
2 Extract the source files to a directory somewhere.
3 If, like me, you prefer OpenSSH not to tell the world its make/version, change version.h to your requirements.
4 Do the usual ./configure with the relevant switches for your environment (for example, I use --with-tcp-wrappers - see the note at the end of the page)
5 make
6 make install

Note to Solaris users: I have had the odd problem at this step in the past, which seems to be down to the usual Solaris conflicts between Sun and Gnu binaries. If you get an error in the last stages of the 'install' process, ending with the word 'Killed', try the following:

PATH=/usr/ccs/bin:$PATH ; export PATH

Then make install again.
7 Modify /usr/local/etc/sshd_config to include the following lines (your environment may vary):
# Use the following line to *replace* any existing 'Subsystem' line
Subsystem       sftp    internal-sftp

# These lines must appear at the *end* of sshd_config
Match Group sftponly
        ChrootDirectory %h
        ForceCommand internal-sftp
	AllowTcpForwarding no

This means that all users you add to the 'sftponly' group will be chroot'd to their home directory, and will only be able to run the internal SFTP process.

8 Create a new user group to add users to (this determines whether they are chroot'd or not), using groupadd sftponly.

Now, configure your users' accounts as follows (don't forget to do this with new users as well):

  • Set their group (usermod -g) to sftponly (the group you created in the previous step)
  • Set their shell (usermod -s) to /bin/false (to deny them shell access)
  • Set their home directory (usermod -d) as you prefer
  • Important (OpenSSH tests for this condition): ensure their home directory is owned by root, and is not writable by any other user or group. This must also be the case for each directory in the path up to the root of your system.
  • Ensure the default UMASK is set appropriately - I found my users got confused if their files didn't automatically set themselves to rwxr-xr-x (755), so I added CMASK=022 to /etc/default/login
9 Test the setup (you will probably need to HUP your SSH daemon first, or start it up if it isn't already). Use sftp and make sure you can't change directory out of the chroot'd environment. Also check access is denied when using ssh

Finished! You should now have a tidy, restricted environment for those pesky users that will insist on uploading files to their Web sites!

One difference to note between this solution and my original one is that since users no longer own their home directory, they will be unable to create new files and directories directly within it. In my environment, this is not a problem, as I set up their top-level directories for them in any case.


Remember to watch out for updates to OpenSSH - they come out fairly regularly, so it's worth subscribing to the openssh-unix-announce list. When a new version is released, you'll need to follow most (but not all) of the instructions above - in summary:

  1. Download and extract the latest source tarball. If you also make modifications to version.h as I do, don't forget to do so again
  2. Compile and install as before.
  3. Test the setup thoroughly again.

There's no need to do anything else, which makes the entire system even more easily managed than my previous solution!

And finally...

If there are any errors or omissions in the above, or you have suggestions about making it more helpful, please do contact me. I'm also happy to help troubleshoot, although I can't guarantee I'd be any use!

Final note on SSH: exposing any interactive login to the Internet is a bad idea, but circumstances dictate that I have to. For SSH/SFTP protection, since there are so many brute-forcing bots out there, I would strongly recommend using DenyHosts or similar, hence the --with-tcp-wrappers switch mentioned earlier

PGP/GPG Public Key [4096/4096 RSA]
Contact The Minstrel
Web The Minstrel's Showcase