16

openssh 5.1 chrootdirectory permissions issue

Posted on Thursday, 9 October 2008

If you're playing with the excellent new ChrootDirectory and internal-sftp options in recent OpenSSH releases (such as 5.1 which is in Ubuntu 8.10 Intrepid), you may have hit an error like:

fatal: bad ownership or modes for chroot directory

You may also have searched on Google for what to do about it and come away with very little useful information.

Well no more! I did the same thing and got bored of reading mailing list posts, so read the source code instead. The relevant section is in session.c:
    if (stat(component, &st) != 0)
      fatal("%s: stat(\"%s\"): %s", __func__,
          component, strerror(errno));
    if (st.st_uid != 0 || (st.st_mode & 022) != 0)
      fatal("bad ownership or modes for chroot "
          "directory %s\"%s\"",
          cp == NULL ? "" : "component ", component);

This is quite simple really, it's stat()ing the directory specified for "ChrootDirectory" and all its parents up to / and checking that they are:

  • owned by root

  • not group or other writable

  • (it also checks they are actually directories, but I'm going to assume you're not stupid enough to try and chroot into a file ;)


Note my emphesis that these checks apply to the chroot directory itself and its parents and /, so if you are chrooting users into /srv/chroot/ then you need to ensure that /, /srv and /srv/chroot are owned by root and not writable by the group (even if it's root, bizarrely) or other users.

Sorted.

Discussion

  1. Good to see solutions being published to this kind of problem - there are a few others on my Web page at:

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

    I hope this helps as well.

    --
    Minstrel

    ReplyDelete
  2. Yeah, Minstrel's information about this is very useful, I recommend reading that stuff :)

    ReplyDelete
  3. Hey,

    but what if I want to have permissions ChrootDirectory set to e.g. 777? The manual suggests I set "StrictModes" to "no", but that didn't work - I still get the same error (bad ownership...)

    Thanks,

    Marko

    ReplyDelete
  4. Marko: you can't do that with the current code. Move your 777 directory inside root:root 644 directory and chroot into that one.

    ReplyDelete
  5. Wow... thanks for the hint -- appreciate you taking the time to dig for the answer. :-)

    ReplyDelete
  6. Thanks for posting this. Since you found the code section, I was able to easily identify and fix the problem using this feature under Cygwin: that the "root" (Administrators) user is uid 544, not 0. I had to compile OpenSSH, of course, but that was worthwhile given that there's really not another reasonable solution for sftp on Windows that doesn't cost $500+ (and also wouldn't integrate into the existing ssh install).

    Note that I also adjusted the mode check NOT to check the actual chroot dir; it still checks the dirs leading up to it and requires root ownership still. I have no idea what the security implications of this change are, but it is sufficient for my purposes.

    #ifdef HAVE_CYGWIN
    if (st.st_uid != 544 || (cp != NULL && (st.st_mode & 022) != 0))
    fatal("bad ownership or modes for chroot "
    "directory %s\"%s\"",
    cp == NULL ? "" : "component ", component);
    #endif
    #ifndef HAVE_CYGWIN
    if (st.st_uid != 0 || (st.st_mode & 022) != 0)
    fatal("bad ownership or modes for chroot "
    "directory %s\"%s\"",
    cp == NULL ? "" : "component ", component);
    #endif

    ReplyDelete
  7. Geophphrie: I'd use the #ifdef section to set a variable to contain the uid and then use one bit of code to check it, rather than duplicate the whole section.
    Also I think you should file a bug about this, assuming that upstream care about windows.

    ReplyDelete
  8. You may also have searched on Google for what to do about it and come away with very little useful information.

    Next time try to read the manpage sshd_config(5)

    " ChrootDirectory
    Specifies a path to chroot(2) to after authentication. This
    path, and all its components, must be root-owned directories that
    are not writable by any other user or group.

    "

    ReplyDelete
  9. Thanks, the only guide that actually explained what I needed to do to fix the problem.

    ReplyDelete
  10. Thanks for the tip.

    ReplyDelete
  11. Thank you ... this has me very helped.

    ReplyDelete
  12. I found this page helpful but here are a couple of things that I came across elsewhere that might prove useful.

    You can set the ChrootDirectory to a static value (such as /var/chroot -- that is, no %h or %u values) and then set the user's home directory to the standard home path (ie, /home/), create a home directory under the ChrootDirectory (eg, /var/chroot/home/), chown the directory to that user (ie, it doesn't have to belong to root), and the user will be placed in that directory.

    Also, if you use this approach and want to support key-based auth then create a symbolic link in /home to the user's chroot directory (eg, /home/ -> /var/chroot/home/) so that the key will be found on login.

    ReplyDelete
  13. My last message didn't turn out quite right (dang angle brackets!). Please substitute /home/username where you see /home/.

    ReplyDelete
  14. [...] to 5.3, a special thanks helikaon for the instructions on how to build the rpms, I also used this site to correct the problem I had with permissions. Consider this thread [...]

    ReplyDelete
  15. Muchas gracias por el comentario, me sirvio muchísimo.

    ReplyDelete