OpenBSD Journal

Chroot in OpenSSH

Contributed by merdely on from the lock-em-up dept.

You may have seen the recent commit message from djm@ about the new feature in OpenSSH: ChrootDirectory

Damien Miller (djm@), who worked on this new feature with Markus Friedl (markus@), offers more details about ChrootDirectory:

This commit adds a chroot(2) facility to sshd, controlled by a new sshd_config(5) option "ChrootDirectory". This can be used to "jail" users into a limited view of the filesystem, such as their home directory, rather than letting them see the full filesystem.

More from Damien follows.

Unfortunately, setting up a chroot(2) environment is complicated, fragile and annoying to maintain. The most frequent reason our users have given when asking for chroot support in sshd is so they can set up file servers that limit semi-trusted users to be able to access certain files only. Because of this, we have made this particular case very easy to configure.

In a previous commit, markus@ implemented an "in-process" sftp server in sshd, basically linking sftp-server(8) into sshd(8). When the in-process sftp server is used, sshd does not need any special chroot configuration (no /dev nodes, no libraries, no statically-linked sftp-server) so the chroot setup and maintenance burden is eliminated. The chroot support does work for login and command-execution sessions too, but administrators will need to configure the chroot environment manually.

To set up a restricted sftp server one should use the "ForceCommand" and "ChrootDirectory" directives in sshd_config. Presumably most people will not want to restrict every user, so they should also use the "Match" directive to select a user or group to apply the restrictions to. For example:

Match user djm
    ForceCommand internal-sftp
    ChrootDirectory /chroot

This will cause the user 'djm' to be chrooted to the "/chroot" directory at login, and the use of the in-process sftp server will be forced for all connections. I.e. the user will not be able to login interactively, or run arbitrary commands - the login will only be useful for sftp transfers. Note that the user's home directory may exist under the "/chroot" directory above (e.g. "/chroot/home/djm") and sshd will try to chdir to it before starting to serve files, but it doesn't matter if it does not exist.

Setting up a safe chroot jail is somewhat tricky, and it is quite easy to make to compromise one's security. To reduce this risk, sshd ensures the ChrootDirectory and each of its components is root-owned and not writable by other users, but it is still possible for administrators to break their own setups by doing dumb things (e.g. leaving /dev nodes for the physical drives in a chroot, executing scripts inside the chroot from cron(8) or elsewhere, etc.).

A limitation of the chroot support is that the in-process sftp server does not support scp(1) transfers. scp is a really busted protocol and it would be a fair bit more work to build it in in the way we have built in sftp. It is still possible to support chrooted scp, but administrators will need to populate the chroot environment manually. Please use sftp instead.

To make the internal-sftp chroot work for me, I made the following changes to /etc/ssh/sshd_config:

#Subsystem      sftp    /usr/libexec/sftp-server
Subsystem       sftp    internal-sftp

The full commit message:

CVSROOT:        /cvs
Module name:    src
Changes by:     djm@     2008/02/08 16:24:08

Modified files:
        usr.bin/ssh    : sshd_config.5 sshd_config sftp.h sftp-server.c
                         sftp-server-main.c session.c servconf.h
                         servconf.c

Log message:
add sshd_config ChrootDirectory option to chroot(2) users to a directory and
tweak internal sftp server to work with it (no special files in chroot
required). ok markus@

Thanks to Damien Miller for taking the time to explain the ChrootDirectory feature.

(Comments are closed)


  1. By Didier () didier.wiroth@mcesr.etat.lu on http://www.wiroth.net

    Thanks:
    1) for the excellent feature
    2) for the excellent report on this page
    3) for the good sample!!!
    and THANKS AGAIN!!!

  2. By Anonymous Coward () on

    Awesome! Just what I was looking for. Is it safe to assume that this will be included in the upcoming 4.3?

    1. By Anonymous Coward () on

      > Awesome! Just what I was looking for. Is it safe to assume that this will be included in the upcoming 4.3?

      It is safe, considering that this was committed, and 4.3 has not yet been tagged.

      1. By Anonymous Coward () on

        > > Awesome! Just what I was looking for. Is it safe to assume that this will be included in the upcoming 4.3?
        >
        > It is safe, considering that this was committed, and 4.3 has not yet been tagged.
        >

        But man, it wasn't far off.

    2. By TomazZ () tzveglic@email.si on

      > Awesome! Just what I was looking for. Is it safe to assume that this will be included in the upcoming 4.3?

      Try to install new version of OpenSSH.

      Just installed OpenSSH by this notes on 4.2:
      http://www.openssh.org/openbsd.html

      Chroot works just as I expected!

      Thanks for that feature!

      Regards,
      TomazZ

  3. By Anonymous Coward () on

    I am going to try this out tonight.
    GREAT feature

  4. By Paul R. () on

    Thank you for working on this, it is a great feature....

  5. By Paul Irofti () bulibuta@gmail.com on

    When I first saw the cvs commit I was at home reading my mail, I read
    the announcement just a few minutes after the code entered the tree. I
    remember I just pool()-ed my cvs mirror to get in sync and fetch this
    beauty!

    Thank you *very* much!!!

  6. By Anonymous Coward () on

    great feature,

    but SCARRY, so many commands like ping could break out of other ssh jail setups....

    So many web servers need to support scp/sftp that jury rigged ssh jails are widespread,
    But if it is in the base, it stands a better chance of being better scrutinized... thank you.

  7. By Anonymous Coward () on

    I hope this is another nail in the coffin of ftp. I think sshd just needs a feature to configure an sftp-only account (if it doesn't have already -- I haven't checked recently) that can be encryptionless and passwordless, and that ftp server can go the way of the dodo.

    1. By Anonymous Coward () on

      > I hope this is another nail in the coffin of ftp. I think sshd just needs a feature to configure an sftp-only account (if it doesn't have already -- I haven't checked recently) that can be encryptionless and passwordless, and that ftp server can go the way of the dodo.

      I guess I should have read the rest of the post =) Good job fellas!!

      1. By sthen () on

        > > I hope this is another nail in the coffin of ftp. I think sshd just needs a feature to configure an sftp-only account (if it doesn't have already -- I haven't checked recently) that can be encryptionless and passwordless, and that ftp server can go the way of the dodo.
        >
        > I guess I should have read the rest of the post =) Good job fellas!!

        So who will open the first scp://anonymous@ package mirror? (-:

        1. By Anonymous Coward () on

          > > > I hope this is another nail in the coffin of ftp. I think sshd just needs a feature to configure an sftp-only account (if it doesn't have already -- I haven't checked recently) that can be encryptionless and passwordless, and that ftp server can go the way of the dodo.
          > >
          > > I guess I should have read the rest of the post =) Good job fellas!!
          >
          > So who will open the first scp://anonymous@ package mirror? (-:


          scp does not work :))))

    2. By Anonymous Coward () on

      > I hope this is another nail in the coffin of ftp. I think sshd just needs a feature to configure an sftp-only account (if it doesn't have already -- I haven't checked recently) that can be encryptionless and passwordless, and that ftp server can go the way of the dodo.

      sftp auto completion would be another nail

      1. By CODOR (CODOR) on

        > sftp auto completion would be another nail

        lftp (which, not surprisingly, is in ports) already does this. (Plus it speaks FTP so you can speak to silly people who still use that protocol...)

        1. By Anonymous Coward () on

          > > sftp auto completion would be another nail
          >
          > lftp (which, not surprisingly, is in ports) already does this. (Plus it speaks FTP so you can speak to silly people who still use that protocol...)

          yafc also does this. And of course there's also sshfs, which lets you use your shell's tab-completion!

        2. By Anonymous Coward () on

          > > sftp auto completion would be another nail
          >
          > lftp (which, not surprisingly, is in ports) already does this. (Plus it speaks FTP so you can speak to silly people who still use that protocol...)

          How does it do that ?

          Does it login to the system when you hit tab and find appropriate options ?



  8. By Alan Watson () alan@alan-watson-.org on http://www.alan-watson.org

    This looks like a great addition. However, can a user limited to the internal sftp server still forward ports?

    1. By sthen () on

      > This looks like a great addition. However, can a user limited to the internal sftp server still forward ports?

      Depends how you set pf.conf.

    2. By Mike Erdely (merdely) on http://erdelynet.com/

      > This looks like a great addition. However, can a user limited to the
      > internal sftp server still forward ports?

      Yes. By default. Unless you set up something like this:
      Match User foo
              X11Forwarding no
              AllowTcpForwarding no
              ForceCommand internal-sftp
              ChrootDirectory /chroot

  9. By Pete () on

    I'm curious by what is meant by the "scp is a really busted protocol." Because sftp has always been an external process, and I can put everything except the password on the command line, I've generally preferred the scp client over sftp in the past. Am I putting myself at risk doing so, or is the busted part in the server security side?

    1. By Anonymous Coward () on

      The way understand it, scp isn't, how shall i put it, very well standardised. sftp is well documented and more or less properly specified. if you add features to scp, you risk breaking compatibility.

      1. By Pete () on

        Ah, ok. Thanks.

  10. By Mike () on

    sshd ensures the ChrootDirectory and each of its components is root-owned and not writable by other users

    Does that mean that the whole chroot jail is actually read-only for the user? Or what does each of its components mean?

    1. By Damien Miller (djm) on http://www.mindrot.org/~djm/

      > sshd ensures the ChrootDirectory and each of its components is
      > root-owned and not writable by other users
      >
      > Does that mean that the whole chroot jail is actually read-only for
      > the user? Or what does each of its components mean?

      Yes, the jail directory must be read-only for the user. Typically the jail directory isn't the home directory though, so you might configure "ChrootDirectory=/chroot" and create "/chroot/home/djm" within in.

      1. By Markus () on

        > > sshd ensures the ChrootDirectory and each of its components is
        > > root-owned and not writable by other users
        > >
        > > Does that mean that the whole chroot jail is actually read-only for
        > > the user? Or what does each of its components mean?
        >
        > Yes, the jail directory must be read-only for the user. Typically the jail directory isn't the home directory though, so you might configure "ChrootDirectory=/chroot" and create "/chroot/home/djm" within in.
        >

        This defeats about half the purpose with this great feature... Consider the following, common setup:

        users are placed in /home (or perhaps another filesystem; /web etc.)
        the rationale for each user is the default, readable by others, in order to allow an httpd running as nobody/nobody to fetch content of the users' directory, and the content per itself is per default "RWXR-XR-X".

        Now.. what is the point of not being able to use this setup to supply SFTP-only access to users to administrate their web content? Shouldn't there be a setting to override the "chroot dir must be read-only-by-the-user"? It seems quite useless without, since it only results in a read-only repository for unique users, hidden from everyone, including an eventual httpd.

        I admit that I am not sure what the security implications might be to chroot to a directory owned and writable by a mortal user.... are there any that would make this an issue?

        I'd like to see a way to finally allow users SFTP-only access to their normal home-dirs from where normal web content is served. Apparently this is not it.




        1. By yann () on

          > > > sshd ensures the ChrootDirectory and each of its components is
          > > > root-owned and not writable by other users
          > > >
          > This defeats about half the purpose with this great feature...

          Maybe using --bind mount option may solve your problem (this option have always be of great use for real chrooted env: to be able to make some data subtrees accessible to sftp chrooted users).

          You have your chroot dir with required owner (root)+rights:
          /chroot
          Inside this one, create /chroot/home

          on the other side, consider:
          /home/...

          And, as root:
          mount --bind /home /chroot/home

          should do the job. Add it in your fstab to be reset persistant...

      2. By Markus () on

        addendum:

        to elaborate, the problem here with a shared webserver setup is that either you create a messy, nested dir-structure (/home/user1/user1 etc.) in order to keep users entirely isolated from eachother (as you may want to), or, you just keep a normal dir-tree and ChrootDirectory to /home and users will be locked out from the main system, but able to snoop around in eachothers' content since it has to be readable by others.

        sigh... add a flag to circumvent this and point out all the risks with it?

    2. By Anonymous Coward () on

      > sshd ensures the ChrootDirectory and each of its components is root-owned and not writable by other users
      >
      > Does that mean that the whole chroot jail is actually read-only for the user? Or what does each of its components mean?

      For example you have ChrootDirectory set to "/mnt/blah/chroot"
      in this case it would have 3 component dirs: /mnt, /mnt/blah, and /mnt/blah/chroot, all of which must be root-owned and not writable by any other users.

  11. By Anonymous Coward () on

    Is is possible to have some unchrooted users using /usr/libexec/sftp-server and other chrooted
    users with internal-sftp on the same server?

    1. By Damien Miller (djm) on http://www.mindrot.org/~djm/

      > Is is possible to have some unchrooted users using
      > /usr/libexec/sftp-server and other chrooted
      > users with internal-sftp on the same server?

      Yes, use Match+ForceCommand+ChrootDirectory to contain the untrusted users but include a normal Subsystem line for the regular users.

  12. By Lennie () on

    I was hoping for ChrootDirectory ~ (homedirectory), so it could be used for shared webservers...

    But this looks like it's not that simple.

    That's too bad.

    I would have loved to have been able to do:

    Match user user1
    Match user user2
    ChrootDirectory ~

    AllowUsers adminuser1 adminuser2 user1 user2

    It's to bad, this won't kill FTP, I'm afraid. It would have been better to have something really simple.

    Maybe a chroot-dir and a hardlink per user would be kinda manageable ?

    ssh killed telnet, sftp could have killed ftp.

    1. By sthen () on

      > I was hoping for ChrootDirectory ~ (homedirectory), so it could be used for shared webservers...
      >
      > But this looks like it's not that simple.

      Read the manual page for sshd_config. It's linked from the article. Specifically look at the bit about ChrootDirectory.

      1. By Mike Erdely (merdely) on http://erdelynet.com/

        >> I was hoping for ChrootDirectory ~ (homedirectory), so it could be
        >> used for shared webservers...
        >>
        >> But this looks like it's not that simple.
        >
        > Read the manual page for sshd_config. It's linked from the article.
        > Specifically look at the bit about ChrootDirectory.

        djm@ even explained it earlier in the comments for this article.

    2. By Anonymous Coward () on

      > I was hoping for ChrootDirectory ~ (homedirectory), so it could be used for shared webservers...
      >
      > But this looks like it's not that simple.
      >
      > That's too bad.
      >
      > I would have loved to have been able to do:
      >
      > Match user user1
      > Match user user2
      > ChrootDirectory ~
      >
      > AllowUsers adminuser1 adminuser2 user1 user2
      >
      > It's to bad, this won't kill FTP, I'm afraid. It would have been better to have something really simple.
      >
      > Maybe a chroot-dir and a hardlink per user would be kinda manageable ?
      >
      > ssh killed telnet, sftp could have killed ftp.


      Just use "Match group" instead and add all restricted users to that group.

    3. By jirib () on

      > I was hoping for ChrootDirectory ~ (homedirectory), so it could be used for shared webservers...
      >
      > But this looks like it's not that simple.
      >
      > That's too bad.
      >
      > I would have loved to have been able to do:
      >
      > Match user user1
      > Match user user2
      > ChrootDirectory ~
      >
      > AllowUsers adminuser1 adminuser2 user1 user2
      >
      > It's to bad, this won't kill FTP, I'm afraid. It would have been better to have something really simple.
      >
      > Maybe a chroot-dir and a hardlink per user would be kinda manageable ?
      >
      > ssh killed telnet, sftp could have killed ftp.
      >
      >


      I tried it right now and i would suggest following:

      Change homedir in /etc/passwd for users to /user1, /user2 etc...

      Match Group sftpusers
      ChrootDirectory /chroot/%u
      ForceCommand internal-sftp

      and make following dir structure:

      /chroot/user1/user1
      |-user2/user2

      so they don't see theirs home dirs :)

      j.

      1. By Anonymous Coward () on

        > I tried it right now and i would suggest following:
        >
        > Change homedir in /etc/passwd for users to /user1, /user2 etc...
        >
        > Match Group sftpusers
        > ChrootDirectory /chroot/%u
        > ForceCommand internal-sftp
        >
        > and make following dir structure:
        >
        > /chroot/user1/user1
        > |-user2/user2
        >
        > so they don't see theirs home dirs :)
        >
        > j.
        >

        This was very helpful, but I do not understand the last point. Why do you not want them to see their home dirs? Exactly what are you accomplishing by this additional level of directory?

        Thanks!

        BTW, I am a new AC here - I'm not related to the previous AC posters. :-)

        1. By jirib () on

          > This was very helpful, but I do not understand the last point. Why do you not want them to see their home dirs? Exactly what are you accomplishing by this additional level of directory?
          >

          'see their home dirs' means if you have more users they don't see home dir of other users :) like it works in chrooted ftp, you just see your 'home'.

          j.

    4. By Kamil Wencel () on http://www.reaktorblog.de

      > I was hoping for ChrootDirectory ~ (homedirectory), so it could be used for shared webservers...


      In case anyone is still looking for the homedir feature, have a look at

      http://www.minstrel.org.uk/papers/sftp/builtin/

      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.

  13. By Rico Secada (ricosecada) coolzone@it.dk on

    Thank you very very much!! A long needed feature!

  14. By Anonymous Coward () on

    Time to smoke a cheroot in celebration.

  15. By Anonymous Coward () on

    Great feature !
    is it possible to build a jail with a bash session ?!

  16. By TA () on

    Is it possible to use the chroot and use public key authentication where the authorized_keys file is outside the home directory, so that the user cannot modify or see the keys? I cannot get this to work. I also used usermod user -s /bin/false to prevent ssh login. Please advise

  17. By morophla () on

    Cool. But what is the procedure to truly isolate users from each other? With this method, any user can sneak in everobdy's directory in the same chroot. That's not what we want for web hosting.

    1. By SirQuack () openbsd@roelof.io on

      > Cool. But what is the procedure to truly isolate users from each other? With this method, any user can sneak in everobdy's directory in the same chroot. That's not what we want for web hosting.

      You'd give every user their own directory to work in. This is commonly done using a central chroot dir with a user-specific dir.

      I use this for my clients:

      ChrootDirectory /var/www/users/%u

Credits

Copyright © - Daniel Hartmeier. All rights reserved. Articles and comments are copyright their respective authors, submission implies license to publish on this web site. Contents of the archive prior to as well as images and HTML templates were copied from the fabulous original deadly.org with Jose's and Jim's kind permission. This journal runs as CGI with httpd(8) on OpenBSD, the source code is BSD licensed. undeadly \Un*dead"ly\, a. Not subject to death; immortal. [Obs.]