A couple of gotchas with the OpenSSH chroot() implementation


I previously discussed the OpenSSH Match directive, and how it can be used to chroot SSH and SFTP users. Over the past couple of months I’ve encountered some gotchas with the chroot implementation in OpenSSH. Since I had to figure these items out myself, I figured I would share my findings here so folks wouldn’t need to spend hours looking at source code (if you want to geek out and see how this works, check out session.c in the OpenSSH source code).

The first gotcha occurs when the users home directory doesn’t have the correct permissions. The directory the user is chroot()‘ed into needs to be root owned, and in order for the user to see the contents of the top level directory the group permissions need to be read/execute. A user that is going to be chroot()‘ed into /chroot/user will need the following permissions:

$ mkdir /chroot/user

$ chmod 750 /chroot/user

$ chown root:user /chroot/user

If the permissions aren’t set 100% correctly you will be immediately disconnected:

$ sftp -o Port=222 user@192.168.1.25

Connecting to 192.168.1.25...
user@192.168.1.25's password:
Read from remote host 192.168.1.25: Connection reset by peer
Connection closed

And the following error will be written to your system logs:

Apr 23 14:06:27 vern sshd[13714]: fatal: bad ownership or modes for chroot directory "/chroot/user"

There is also an issue with directory write-ability. Users will not be able to write to the top-level directory of the chroot() due to the strong permissions that are required. If you want your user to be able to create files and directories they will need to change into a directory off of “/” prior to doing so. If you want to place the user into this directory you can replace the home directory field in /etc/passwd with this directory:

$ grep user /etc/passwd /etc/passwd-

user:x:502:502::/home:/bin/bash

In this example user will be chroot’ed into /chroot/user, then a chdir() will occur and the user will be placed into the directory home:

$ sftp -o Port=222 user@192.168.1.25

Connecting to 192.168.1.25...
user@192.168.1.25's password:
sftp> pwd
Remote working directory: /home

With a little understanding the OpenSSH chroot() implementation can definitely be made quite usable.

This article was posted by Matty on 2012-01-21 10:09:00 -0400 -0400