#!/bin/blog

April 6, 2008

OpenSSH chrooted SFTP (e.g. for Webhosting)

Filed under: Security — Tags: , — martin @ 8:53 am

Over at Denny, I discovered that OpenSSH, since version 4.8, supports chrooted SFTP operation. This is, of course, a feature that many of us have been waiting for, so I immediately gave it a try, using a somewhat adventurous manually compiled OpenSSH on CentOS 5. (Update, February 27, 2009: See Packaging OpenSSH on CentOS for a more coherent installation method.) I also had a little help from the Debian Administration Blog.

In order to enable chrooted SFTP for some users, we’ll first create a separate group for users that will get the chroot treatment. I named this group chrooted, for no obvious reason. This group will be assigned as a supplementary group for chroot users.

The common application for this will be virtual WWW hosting, so I started with the assumption that a website called http://www.example.com will be accessed by SFTP. The directory /vhost/www.example.com will therefore serve as the user’s home directory. In order to make chrooting work along with key-based authentication, I found that it neccessary to make the user name and the name of his home directory identical, so the user was named http://www.example.com as well (login shell: /bin/false), along with a similar user private group http://www.example.com. This looks as if it may have a tendency to get awkward, but it really only is a first test. I’ll have to invest a bit more thought before this goes into production.

The directory /vhost/www.example.com was created and populated like this:

drwxr-xr-x 5 root            root            4096 Apr  5 22:01 .
drwxr-xr-x 3 root            root            4096 Apr  5 21:22 ..
drwxrwxr-x 2 www.example.com www.example.com 4096 Apr  6 08:45 htdocs
drwxr-xr-x 2 root            root            4096 Apr  5 21:22 logs
drwxr-xr-x 2 www.example.com www.example.com 4096 Apr  5 22:02 .ssh

With the user created and his directory populated, we’ll now edit sshd_config as follows:

#Replace the OpenSSH sftp-server backend with its internal SFTP engine:
#Subsystem      sftp    /opt/openssh/libexec/sftp-server
Subsystem       sftp    internal-sftp
# Configure special treatment of members of the group chrooted:
Match group chrooted
         # chroot members into this directory
         # %u gets substituted with the user name:
         ChrootDirectory /vhost/%u
         X11Forwarding no
         AllowTcpForwarding no
         # Force the internal SFTP engine upon them:
         ForceCommand internal-sftp

I actually had a quite hard time figuring out the proper constellation of user name, user home directory and ChrootDirectory. ChrootDirectory applies after the user has been authenticated. Before that, his home directory from /etc/passwd still applies. In order to enable the user to maintain his SSH key and to enable sshd to find the key, both environments must be congruent. However, the chroot destination must not be owned by the user for security reasons; the user’s home directory therefore belongs to root. Tricky, isn’t it? I must admit, though, that this would have been a lot more intuitive if I hadn’t strayed away from /home on the very first test. Doh! :-o

Here’s a sample session with the user “www.example.com”, authenticated by public key:

$ sftp www.example.com@192.168.1.24
Connecting to 192.168.1.24...
sftp> ls -la
drwxr-xr-x    5 0        0            4096 Apr  5 20:01 .
drwxr-xr-x    5 0        0            4096 Apr  5 20:01 ..
drwxr-xr-x    2 59984    59984        4096 Apr  5 20:02 .ssh
drwxrwxr-x    2 59984    59984        4096 Apr  6 07:32 htdocs
drwxr-xr-x    2 0        0            4096 Apr  5 19:22 logs
sftp> pwd
Remote working directory: /
sftp> cd ..
sftp> ls -la
drwxr-xr-x    5 0        0            4096 Apr  5 20:01 .
drwxr-xr-x    5 0        0            4096 Apr  5 20:01 ..
drwxr-xr-x    2 59984    59984        4096 Apr  5 20:02 .ssh
drwxrwxr-x    2 59984    59984        4096 Apr  6 07:32 htdocs
drwxr-xr-x    2 0        0            4096 Apr  5 19:22 logs
sftp> pwd
Remote working directory: /
sftp> ls -la .ssh
drwxr-xr-x    2 59984    59984        4096 Apr  5 20:02 .
drwxr-xr-x    5 0        0            4096 Apr  5 20:01 ..
-r--------    1 59984    59984         601 Apr  5 20:02 authorized_keys
sftp> bye

Pay attention to the UIDs, 0 and 59984: The SFTP subsystem, running under chroot, doesn't have access to /etc/passwd from the user's environment.

I am convinced that this is the most important update to OpenSSH for at least the past five years. This has the opportunity to entirely eradicate authenticated FTP from the internet, just as it has already happened with Telnet.

Thanks a lot to the OpenSSH developers for making this happen!

About these ads

30 Comments »

  1. [...] 4.9 bzw. 5.0 an. Google spuckt etwa chroot(2) Unterstützung für OpenSSH – Jochens Blog oder OpenSSH chrooted SFTP (e.g. for Webhosting) #!/bin/blog [...]

    Pingback by ssh user auf sein eigenes Verzeichnis beschrnken - Server Support Forum — June 28, 2008 @ 1:41 pm

  2. Hi , followed as per your above article, am getting below error in /var/log/secure file :-

    sshd[4763]: Accepted password for jatin from 127.0.0.1 port 52312 ssh2
    sshd[4763]: pam_unix(sshd:session): session opened for user jatin by (uid=0)
    sshd[4765]: fatal: bad ownership or modes for chroot directory component “/X”
    sshd[4763]: pam_unix(sshd:session): session closed for user jatin

    tried doing chmod 777 /X/jatin , and still get same above error.

    Am trying to setup chroot sftp on Fedora 9. Tried changing the permission & owner of /X/jatin dir, getting same issue , except when the is root then works fine but then am not able to write in chroot dir.

    Appreciate your help..

    regards
    Dharmin

    Comment by Dharmin — August 20, 2008 @ 3:04 am

  3. The user’s home directory must be owned by root, just as I wrote in the article and as described in sshd_config(5). The user will consequentially only be able to write to existing subdirectories.

    Comment by martin — August 20, 2008 @ 5:44 am

  4. Hi Martin

    Thanks…

    regards
    Dharmin

    Comment by Anonymous — August 20, 2008 @ 10:04 am

  5. Very nice. I have an additional issue in that I don’t want users to be able to ls. Do you know any way to “break” ls for sftp?

    thanks,
    Lynette

    Comment by Lynette Bellini — August 27, 2008 @ 10:15 pm

  6. Making the directory “write-only” (removing read permission) might do what you want. If you have a Mac OS machine around, refer to what Apple did with the “Drop Box” folder in the user home directory.

    Comment by martin — August 28, 2008 @ 7:31 am

  7. I had a hard time with permissions here is what I found….

    /ftp/%h

    for user 123user directory was /ftp/123user

    that directory needs to be 755 and has to be owned by root:root

    Under that directory you can create other folders with any permissions you like…
    [root@bigbluerhel5 ftp]# ls -la
    total 20
    drwxr-xr-x 4 root sys 4096 Dec 9 15:19 .
    drwxr-xr-x 30 root root 4096 Dec 9 12:35 ..
    drwxr-xr-x 4 root root 4096 Dec 9 16:06 123test

    [root@bigbluerhel5 ftp]# cd 123test/
    [root@bigbluerhel5 123test]# ls -la
    total 36
    drwxr-xr-x 4 root root 4096 Dec 9 16:06 .
    drwxr-xr-x 4 root sys 4096 Dec 9 15:19 ..
    -rwxrwx— 1 root root 33 Dec 9 15:19 .bash_logout
    -rwxrwx— 1 root root 176 Dec 9 15:19 .bash_profile
    -rwxrwx— 1 root root 124 Dec 9 15:19 .bashrc
    -rwxrwx— 1 root root 515 Dec 9 15:19 .emacs
    drwxrwx— 4 root root 4096 Dec 9 15:19 .mozilla
    -rwxrwxrwx 1 root root 2188 Dec 9 16:04 passwd
    drwxrwxrwx 2 123test root 4096 Dec 9 16:20 to_epsilon

    Comment by Oleg Frayman — December 9, 2008 @ 11:28 pm

  8. I have openSSH working to a degree. When I try to login as one of the chrooted users I login fine but I have no permissions to do anthing. I have my conf almost setup like yours above and I figured out that the chroot directory needed to be owned by root:root which allowed me to login but now my chrooted user has no permissions.

    The OS is CentOS and I am using OpenSSH 5.1p1 which I download and built per the normal build process. I did not alter it in anyway. And it is working for everything except the internal-sftp chrooted user.

    Match User MyUser
    ChrootDirectory /var/www/html/members
    ForceCommand internal-sftp
    AllowTcpForwarding no

    I have set members to be owned by root:root and changed its permissions to 744
    drwxr–r– /var/www/html/members

    I have two directories under /var/www/html/members but when I login as MyUser I see nothing and I can’t create files, upload or do basically anything.

    Comment by Andrew Penhorwood — December 22, 2008 @ 2:50 am

  9. Andrew: You need to create user-owned directories inside the chroot environment. This is where the user will actually work. This is somewhat apparent from the directory listings above.

    Comment by martin — December 22, 2008 @ 8:12 am

  10. Hi,
    i want to ask you for options for command to create user http://www.example.com.

    I used useradd –base-dir /vhost –skel /dev/null –create-home –shell /bin/false –user-group http://www.example.com

    Are options above correct? Or is something wrong?

    Thank you!
    Regards Hoppik

    Comment by hoppik — December 29, 2008 @ 9:48 pm

  11. I only use useradd the non-GNU way, so I basically can’t tell if your command is correct without looking up the options in the manpage. Keep in mind that the home directory, if used for chrooting, must be owned by root. I doubt that there is a useradd invocation that will do this automatically.

    Comment by martin — December 30, 2008 @ 1:42 pm

  12. [...] UNIX & Linux — Tags: centos, openssh, redhat, rpm, ssh — martin @ 8:29 am My article on chrooted SFTP has turned out to be the most popular article on this blog. What a pity that its “companion [...]

    Pingback by Packaging OpenSSH on CentOS « #!/bin/blog — February 27, 2009 @ 8:29 am

  13. In order to make chrooting work along with key-based authentication, I found that it neccessary to make the user name and the name of his home directory identical
    Holy shit, I’m running this setup for about a year now and TODAY I found, that *this* is the reason for my troubles with pubkey authentification. I could logon in most cases, but for some users pubkey authentification fails without any logmessage…

    Comment by melle ("wer lesen kann ist klar im Vorteil") — May 7, 2009 @ 10:29 pm

  14. How could i enable key based authorization through portal for sftp.

    can please any give details.
    Thanks in advance

    Comment by abdul — May 25, 2009 @ 1:20 pm

  15. A tip that might help someone. OpenSSH kept complaining about every component in the path to the chroot directory, with a message like:

    fatal: bad ownership or modes for chroot directory component “/path/component”

    Changing every directory’s ownership/permissions wasn’t an option. So I used mount –bind. Like this:

    mkdir -p /chroot/foo
    mount –bind /path/to/chroot/home /chroot/foo

    and in sshd_config:

    Match …
    ChrootDirectory /chroot/foo

    Hope this helps.

    Comment by Amr Mostafa — June 14, 2009 @ 2:09 pm

  16. Very good article. Thank you.

    Can anyone give a little hint on how to set the default umask for chroot users? I’ve tried all kinds, couldn’t get it to work the way I want. Thanks.

    Comment by GMan — August 14, 2009 @ 8:28 pm

  17. Do you think they will ever add the functionality to allow users to upload files into their chrooted directory and not just child directories?

    Thanks

    Comment by Andy — August 18, 2009 @ 11:03 pm

  18. That’s hard to tell. I wouldn’t hold my breath for it but rather just adapt to the situation as it is.

    Comment by martin — August 19, 2009 @ 6:20 am

  19. I have not been able to get the chroot jail to work. I think I have a directory permissions problem but I can’t seem to get it right. Here is what I have in sshd_config

    Match Group sftponly
    ChrootDirectory /home/%u
    ForceCommand internal-sftp
    AllowTcpForwarding no

    I have created a user mark with and set his home directory to /home/mark.

    Here are the current permissions:

    For /home
    drwxrwxr-x 13 root root 4096 2009-08-21 22:11 home

    For /home/mark
    drwxr-xr-x 3 root root 4096 2009-08-21 22:12 mark

    For /home/mark/public_html
    drwxr-xr-x 2 mark sftponly 4096 2009-08-21 22:12 public_html

    When I try and connect using WinSCP (using SFTP protocol) I get this error in auth.log

    Aug 21 22:39:48 ftp sshd[7679]: Accepted password for mark from 67.180.247.75 port 49893 ssh2
    Aug 21 22:39:48 ftp sshd[7679]: pam_unix(sshd:session): session opened for user mark by (uid=0)
    Aug 21 22:39:48 ftp sshd[7687]: fatal: bad ownership or modes for chroot directory component “/home/”
    Aug 21 22:39:48 ftp sshd[7679]: pam_unix(sshd:session): session closed for user mark

    I am totally at a loss at this point and really need to make this work! Any ideas what is going on? What exactly should be the permissions at each level? Thanks

    Comment by Paul — August 22, 2009 @ 6:46 am

  20. Paul, my guess would be that you only need to remove group writability from /home.

    Comment by martin — August 22, 2009 @ 7:03 am

  21. Hello All;

    Here are the unofficial openssh5 rpms for CentOS5 and RHEL5 :

    http://fs12.vsb.cz/hrb33/el5/hrb-ssh/stable/i386/
    http://fs12.vsb.cz/hrb33/el5/hrb-ssh/stable/x86_64/

    Regards
    Bulent Tigin

    (I have released this comment but can’t make any statement whether these are safe to use. There is a way to get official RPMs, and that is to build your own from the OpenSSH sources. -ED)

    Comment by ebtigin — August 26, 2009 @ 12:05 am

  22. Hi to all,
    I’m desperate, I’m trying but without any result.. :(

    From Filezilla I receive this error:
    “Fatal: unable to initialise SFTP on server: could not connect”

    From logs I can read:
    Accepted password for double-SFTP from x.x.x.x port 4080 ssh2
    pam_unix(sshd:session): session opened for user double-SFTP by (uid=0)
    subsystem request for sftp
    pam_unix(sshd:session): session closed for user double-SFTP

    My /etc/ssh/sshd_config file contain:
    Match User double-SFTP
    ChrootDirectory /home/chrooted
    AllowTCPForwarding no
    X11Forwarding no
    ForceCommand /usr/lib/openssh/sftp-server

    My /etc/passwd file contain:
    double-SFTP:x:503:503::/home/chrooted/double-SFTP:/bin/false

    I’ve added a chrooted group and add on it the user double-SFTP.
    These are my permission:
    drwxr-xr-x root root /home/chrooted
    drwxr-xr-x doubleDB-SFTP doubleDB-SFTP /home/chrooted/doubleDB-SFTP

    What is wrong?!
    Thanks in advance..

    Comment by trenino — December 1, 2009 @ 5:24 pm

    • trenino, as stated in the article, the home directory must be owned by root and must not be writable by the user.

      Comment by martin — December 1, 2009 @ 6:57 pm

  23. If you use pam (for ldap, radius, etc)

    The installed /etc/pam.d/sshd is not compatible with newer distributions (pam_stack.so deprecated).
    Save the previous file and overwrite to fix.

    Comment by Eduardo Roldan — February 11, 2010 @ 1:32 am

  24. Ive looked at the end. thank you for this article.

    Comment by hosting — March 13, 2010 @ 2:16 pm

  25. I went through this complete article, this is what worked for me

    this is my version of open-ssh on RHEL 5.4

    # rpm -qa | grep openssh
    openssh-4.3p2-35.el5
    openssh-clients-4.3p2-35.el5
    openssh-askpass-4.3p2-35.el5
    openssh-server-4.3p2-35.el5

    Create a chroot dir like this with root as owner
    mkdir /chroot/home

    Mount it to /home as follows

    #mount -o bind /home /chroot/home

    Edit the /etc/ssh/sshd_config as follows:

    ChrootDirectory /chroot/%h
    Subsystem sftp internal-sftp

    Comment the default Subsystem entry in sshd file once you add the above line

    Thats it restart the sshd server, it will work like a breeze

    Comment by Hariharan Madhavan — May 28, 2010 @ 12:06 pm

  26. Thanks – would be so nice to have chrooted SFTP – but really seems safer to wait until the newer version of OpenSSH is officially supported by Centos!

    Comment by danny — August 10, 2010 @ 9:21 am

  27. [...] “OpenSSH chrooted SFTP (e.g. for Webhosting)” (#!/bin/blog; 2008.04.06) – http://binblog.info/2008/04/06/openssh-chrooted-sftp-eg-for-webhosting/ [...]

    Pingback by SSH, OpenSSH « Eikonal Blog — February 3, 2011 @ 9:39 pm

  28. Der Match Block sollte auch wieder mit Match geschlossen werden. Ist mir nur grade aufgefallen.

    Comment by http://exdc.net — July 27, 2011 @ 9:37 am

    • Guter Hinweis! Wenn man ihn mit Match schließt, kann man die Config danach noch außerhalb des Match-Kontext weiterschreiben. Aber statt Match darf auch einfach die Datei enden. :-)

      Comment by martin — July 27, 2011 @ 10:17 am


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Shocking Blue Green Theme. Create a free website or blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: