HOWTO: chroot SFTP (only) - OpenSSH up to Version 4.7

[Return to index]

Last updated: 22 July 2008
Version of OpenSSH to which this page relates: 4.7
Version of sftp-server.c to which this page relates: 1.73

The Method

Many thanks to Bryan Irvine for putting together the OpenBSD instructions, and to a wide variety of different people that have helped me tune the generic instructions.

Step Generic Instructions OpenBSD 4.0 Instructions
1 Download the latest OpenSSH 'portable' source tarball from Download the source from CVS following OpenBSD instructions. You'll end up with the source tree in /usr/src
2 Extract the source files to a directory somewhere. Included in Step 1
3 In the source directory, replace sftp-server.c with my modified version - my changes are commented within the file itself (search for 'Minstrel') so you can see what I'm up to.
Note: another change I make before compilation is to change version.h so that OpenSSH no longer provides detailed version information, but then I'm just paranoid!
Replace /usr/src/usr.bin/ssh/sftp-server.c with the OpenBSD variant from Bryan, instead of mine (which is based on the 'portable' code).
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) CD to /usr/src/usr.bin/ssh - ./configure is not required, unless you want to add switches
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.
CD to /usr/src/usr.bin/ssh/sftp-server/ and then make install
7 'chroot' can only be executed by the root account, so sftp-server needs to run with root privileges - therefore use chmod +s /usr/local/libexec/sftp-server (unless your system places the sftp-server binary somewhere else).
Hoorah! You now have an sftp-server executable capable of chroot'ing users. If you previously had SSH installed on your system, you might also want to double-check at this point that the path to sftp-server in your sshd_config file is correct.

The main SSH shell program is not jailed, so next we need next to restrict the users to SFTP only. I did this using a simple C program to create a new shell that 'wraps' sftp-server and nothing else. An alternative is to use sftp-server itself as the user's shell, but I understand there are ways a user could execute arbitrary commands if this was the case.

8 Download sftpsh.c to your system - this is the program I originally found, and I haven't altered it in any way, other than the required modifications mentioned below.
9 Edit sftpsh.c and modify the following lines to fit your environment (see the comments in the file itself):
#define SFTP_BINARY "/usr/local/libexec/sftp-server"
#define SFTP_EXNAME "sftp-server"
#define SFTP_ARGS   ""
10 Compile this program using the command gcc -O2 sftpsh.c -o sftpsh
11 Copy the new shell to your system path, using the command cp sftpsh /bin
12 Make sure the new shell is recognised by the system, by adding it to /etc/shells - use the command echo /bin/sftpsh >> /etc/shells
13 Now, configure your users' accounts as follows (don't forget to do this with new users as well):
  • Set their shell to /bin/sftpsh
  • Use the chroot 'magic token' (a full stop) in their home directory setting, e.g. /home/username/./ - the path before the '.' becomes the user's root directory once they connect using SFTP, whilst the path after the '.' defines the directory they are initially dropped into once logged in.
  • Set the permissions on /home/username/ so that they can modify their files (e.g. chown -R username:users /home/username).
  • 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
14 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!


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.
  2. Check the version of sftp-server.c against the information at the top of this page - if it's the same, use mine again, otherwise make similar modifications or wait until I update this page again!
    If you also make modifications to version.h as I do, don't forget to do so again
  3. Compile and install as before.
  4. chmod +s /usr/local/libexec/sftp-server.
  5. Test the setup thoroughly again.

There's no need to recreate the sftpsh shell, as this is independent of the SSH version in use. Your user accounts also don't need to be modified.

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