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
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.

2 thoughts on “A couple of gotchas with the OpenSSH chroot() implementation”

  1. And this is why I wrote sftponly: to ease users’ home directories management. Why the heck would you want to struggle with creating directories for each possible user, when you could just use pam_mkhomedir module?

  2. I’ve set up sftp chroot on my server. only problem is that when sftp’ing into my server i cant see any files in my subdirectories when giving these folders write permissions with chmod 775.

    The sftp chroot’ed folder is /mnt/lager/Media. It has 755 permissions. and everything works fine so far.
    But I do have a few subfolders, which are only readable if they too are owned på root and have the same permissions.
    This meens that I, nor any of my users can read and write to the folders.

    Any suggestions

Leave a Reply

Your email address will not be published. Required fields are marked *