July 25, 2004

Updated: chrooted SFTP account recipes

This is an update on the earlier entry about chrooted SFTP-only accounts.

When reading the material at http://chrootssh.sourceforge.net/ I realized that it was actually applying to sshd, not to sftp-server, which I wasn’t overly fond of for whatever reason.

One note: I’m installing this on a RH 7.2 box, and I don’t believe I’m using an OpenSSH version with privilege separation (I’m using 3.1 patched against some bugs, probably whatever Fedora Legacy hands out). If you’re using privilege separation I’d look at a recent version of OpenSSH, as I read that in versions prior to around October 2003’s (probably, based on the date of the post) don’t call PAM session modules as root so chroot is impossible. Disabling privilege separation is always an option too, of course, just not one I’m fond of.

Also, side note: for my clients to use this, they’re going to need an SFTP client program. PSFTP, PuTTY’s SFTP client, is CLI. No good: clients need GUI, I’m sure. WinSCP, despite its name, seems to fit the bill: SFTP and public key authentication support. Decent interface too I think, though I’ve used it for all of two minutes.

From observing some debug output, I think that even if a service like SFTP is requested, any command= option for a key used to authenticate the user will override the request. In other words, even if the user is trying to use SFTP, any command specified in command= will get executed instead of sftp-server. I am pleased.

After talking with Andy for a bit, I decided I should patch sftp-server to know how to chroot itself. Patches like http://mail.incredimail.com/howto/openssh/addons/sftp-chroot.diff and http://www.coding-zone.com/chroot+sftp-server.patch have some ideas, but nothing quite exactly what I was looking for.

So I wrote a patch for a chrooting sftp-server. This patch is, as the name implies, made against OpenSSH 3.8.1p1. I hope it’s simple enough that it’ll be applicable to other versions without change, but I haven’t tested that. This makes an sftp-server that’ll chroot to whatever is given as its first argument (if anything; if no first argument, no chroot) then drop privileges. Basically what I do is build sftp-server with this patch, then install it setuid root as /usr/libexec/openssh/chroot-sftp-server. For each user: create an account, put no password on it (user can’t log in), create the SSH keys, use command=/usr/libexec/openssh/chroot-sftp-server /foo/bar where /foo/bar is where I want the user to be chrooted to, and voila. No chroot jail creation necessary. Do remember to make sure ~user/.ssh and all files contained within aren’t writable by the user (I make mine owned by root; but remember the user will probably need access to read the files).

One idea I had for modifying the patch is to make it ignore any arguments that match argv<> or -c. By doing this you could set the user’s shell to /usr/libexec/openssh/chroot-sftp-server, then I think OpenSSH will run the command= with that, yielding something like: /usr/libexec/openssh/chroot-sftp-server -c /usr/libexec/openssh/chroot-sftp-server /foo/bar. I don’t know if making the user have an invalid shell adds particularly much security, though, and I think it is kind of ugly.

Update 2005-01-29: Just a quick note: don’t forget that chroot-sftp-server needs to be setuid root to use chroot(). I think I may have mentioned this earlier, but I ran into it again when setting this up. I am concerned (as I’m certain I have been before) about the security implications of making this SFTP server setuid root and 4511. It’s possible that I should restrict it to being executed by members of some sftp group or something like that. I’ll also note that I just applied the above patch cleanly to OpenSSH 3.9p1 without incident. I now have two servers using this patch.