Chrooted SSH/SFTP Tutorial (Debian Lenny)

Want to support HowtoForge? Become a subscriber!
 
Submitted by falko (Contact Author) (Forums) on Wed, 2009-03-18 18:23. :: Debian | Security

Chrooted SSH/SFTP Tutorial (Debian Lenny)

Version 1.0
Author: Falko Timme <ft [at] falkotimme [dot] com>
Last edited 03/03/2009

Since version 4.8, OpenSSH supports chrooting (see http://openssh.org/txt/release-4.8), so no patches are needed anymore. This tutorial describes how to give users chrooted SSH access. With this setup, you can give your users shell access without having to fear that they can see your whole system. Your users will be jailed in a specific directory which they will not be able to break out of. I will also show how to use chrooted SFTP.

I do not issue any guarantee that this will work for you!

 

1 Preliminary Note

The OpenSSH version coming with Debian Lenny is 5.1p1, so it supports chrooting.

I will use the user falko here with the home directory /home/falko. The user falko belongs to the group users. I want to chroot the user to the /home directory.

 

2 Installing OpenSSH

If OpenSSH is not already installed, install it as follows:

apt-get install ssh openssh-server

 

3 Enabling Chrooted SFTP

Enabling SFTP is very easy. Open /etc/ssh/sshd_config...

vi /etc/ssh/sshd_config

... and make sure you have the following line in it:

[...]
Subsystem sftp /usr/lib/openssh/sftp-server
[...]

Then add the following stanza at the end of the file (add such a stanza for each user that you want to chroot):

[...]
Match User falko
    ChrootDirectory /home
    AllowTCPForwarding no
    X11Forwarding no
    ForceCommand /usr/lib/openssh/sftp-server

Instead of adding a stanza for each user, you can also chroot groups, e.g. as follows:

[...]
Match Group users
    ChrootDirectory /home
    AllowTCPForwarding no
    X11Forwarding no
    ForceCommand /usr/lib/openssh/sftp-server

This would chroot all members of the users group to the /home directory.

Restart OpenSSH:

/etc/init.d/ssh restart

If you chroot multiple users to the same directory, but don't want the users to browse the home directories of the other users, you can change the permissions of each home directory as follows:

chmod 700 /home/falko

Afterwards, you can log in with an SFTP client, such as FileZilla or WinSCP.

 

4 Enabling Chrooted SSH

Enabling chrooted SSH is a bit more complicated because we must set up a chroot environment with all programs/tools (e.g. /bin/bash, /bin/cp, etc.) that the users should be able to use. This means we must also copy all libraries that these programs need to the chroot jail. You can do this manually with the cp command, and you can find out what libraries a tool needs by using the ldd command, e.g.

ldd /bin/bash

We also have to create some devices such as /dev/null, /dev/zero, /dev/tty, and /dev/urandom inside the chroot jail with the mknod command.

However, this can be a tedious task. Fortunately, there's a script that can do this for us.

First, we need to install some prerequisites:

apt-get install sudo debianutils coreutils

Then we download make_chroot_jail.sh to /usr/local/sbin and make it executable for the root user:

cd /usr/local/sbin
wget http://www.fuschlberger.net/programs/ssh-scp-sftp-chroot-jail/make_chroot_jail.sh
chmod 700 /usr/local/sbin/make_chroot_jail.sh

Before we use the script, you might want to add some programs (e.g. such as /usr/bin/vi) to the APPS line of your distribution in that script so that these tools get added to the chroot jail automatically:

vi /usr/local/sbin/make_chroot_jail.sh

[...]
elif [ "$DISTRO" = DEBIAN ]; then
  APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups /usr/bin/id /usr/bin/rsync /usr/bin/ssh /usr/bin/scp /sbin/unix_chkpwd /usr/bin/vi"
else
[...]

Next we add a symlink /home/home that points back to /home:

cd /home
ln -s . home

Now we can already use the script. Usage is as follows:

make_chroot_jail.sh username [/path/to/chroot-shell [/path/to/chroot]]

chroot-shell is a special shell created by the script to chroot users. Since OpenSSH now supports chrooting by default, we don't need the script to create a special shell; instead, we can use /bin/bash or /bin/sh.

It doesn't matter if the user is already existing or not. If he's existing, he will be updated; if not, he will be created.

make_chroot_jail.sh falko /bin/bash /home

This will create/update the user falko with the chroot jail /home.

To update all files/libraries in the chroot jail, run

make_chroot_jail.sh update /bin/bash /home

Now we need to configure OpenSSH which is similar to the SFTP configuration. Open /etc/ssh/sshd_config...

vi /etc/ssh/sshd_config

... and add the following stanza at the end of the file (add such a stanza for each user that you want to chroot):

[...]
Match User falko
    ChrootDirectory /home
    AllowTCPForwarding no
    X11Forwarding no

Instead of adding a stanza for each user, you can also chroot groups, e.g. as follows:

[...]
Match Group users
    ChrootDirectory /home
    AllowTCPForwarding no
    X11Forwarding no

This would chroot all members of the users group to the /home directory.

The difference to the SFTP configuration is that this time, we must not use the line ForceCommand /usr/lib/openssh/sftp-server in the Match stanzas! This makes that users can still use chrooted SFTP (provided you also have the line Subsystem sftp /usr/lib/openssh/sftp-server in /etc/ssh/sshd_config), but also chrooted SSH.

Restart OpenSSH:

/etc/init.d/ssh restart

If you chroot multiple users to the same directory, but don't want the users to browse the home directories of the other users, you can change the permissions of each home directory as follows:

chmod 700 /home/falko

Afterwards, you can log in with with an SSH client such as PuTTY.

 

5 Links


Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.
Submitted by PlanetMaster (not registered) on Tue, 2013-02-26 01:25.

You can chroot users to their own directory for SSH and SFTP access simply by changing a couple things>

In sshd conf file:

UseDNS no
AllowUsers USER

Match User USER
PasswordAuthentication yes
ChrootDirectory /home/%u
AllowTCPForwarding no
X11Forwarding no
 Match


And then running the script

make_chroot_jail.sh USER /bin/bash /home/USER

Works perfectly. I also fixed the  make_chroot_jail.sh with no errors and perfect installs every time. Tested on Ubuntu 12.04

More info and script here:

http://www.devcu.com/forums/topic/607-sshscp-and-sftp-chroot-user-to-directory-ubuntu-1204/ 

Submitted by michael (not registered) on Wed, 2011-06-22 15:54.

First of all thanks a lot to Falko for this great Tutorial!

It seems many people in the comments seem to have the same problem I had. I just found the cause and want to share it. Also Falko, maybe you could update your tutorial with it.

 Everything worked fine for me, I just couldn't use the Match directive. No matter how I used it, sftp would accept no connections.

The problem was that the Match clause in sshd.conf needs to be closed or in one line (like zhanchangheng in the comments already pointed out). So correct syntax for the Match clause (following the example of this tutorial) should be:

[...]
Match User falko
    ChrootDirectory /home
    AllowTCPForwarding no
    X11Forwarding no
    ForceCommand /usr/lib/openssh/sftp-server
Match 

Notice the second Match at the end closing the clause. With that all matched uses were accepted by sftp and restricted to ChrootDirectory.

I hope this helps!

Submitted by TooMeeK (not registered) on Sun, 2013-05-05 03:22.
Thank You for this post, helped a LOT !
Submitted by Hit_alive (not registered) on Sat, 2011-02-26 11:21.

How to add some programs to chroot users, etc. mc?

Submitted by Narcis Garcia (not registered) on Sun, 2010-10-10 14:22.
I've seen your guide for the chrooted SFTP part, and I've learnt from a lot of tutorials as yours. Here my compendium to configure better clients and servers:

http://wiki.lapipaplena.org/index.php/How_to_mount_SFTP_accesses

(special care of users and permissions)
Submitted by Anonymous (not registered) on Sun, 2010-08-29 13:43.
I finally managed to get this to work on my Ubuntu setup! I had a problem with it resetting every time I rebooted.
Submitted by immux (not registered) on Tue, 2010-08-10 02:36.

i got an error like this

 Adding User kmel to jail

Copying necessary library-files to jail (may take some time)

mv: missing destination file operand after `.bak'

Try `mv --help' for more information.

mv: missing destination file operand after `.bak'

Try `mv --help' for more information.

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexisten

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

/usr/local/sbin/make_chroot_jail.sh: 428: cannot create : Directory nonexistent

what should i do now?

Submitted by Romaric (not registered) on Wed, 2010-12-29 13:20.

Hi !

There's a bug in the script /usr/local/sbin/make_chroot_jail.sh lines 406 and 407 :

TMPFILE1=`mktemp` &>/dev/null ||  TMPFILE1="${HOME}/ldlist"; if [ -x ${TMPFILE1} ]; then mv ${TMPFILE1} ${TMPFILE1}.bak;fi
TMPFILE2=`mktemp` &>/dev/null ||  TMPFILE2="${HOME}/ldlist2"; if [ -x ${TMPFILE2} ]; then mv ${TMPFILE2} ${TMPFILE2}.bak;fi

You must remove the &>/dev/null, or TMPFILE1 and 2 are null.

Rewriting the following lines like :

 TMPFILE1=`mktemp` ||  TMPFILE1="${HOME}/ldlist"; if [ -x ${TMPFILE1} ]; then mv ${TMPFILE1} ${TMPFILE1}.bak;fi
TMPFILE2=`mktemp` ||  TMPFILE2="${HOME}/ldlist2"; if [ -x ${TMPFILE2} ]; then mv ${TMPFILE2} ${TMPFILE2}.bak;fi

fixed the problem for me.

 

I hope this help :)

Romaric

Submitted by Alastair (not registered) on Thu, 2012-07-26 13:34.
Thanks! Fixed it for me. 
Submitted by Anonymous (not registered) on Tue, 2010-04-13 09:55.

I can't get make_chroot_jail.sh and the sshd_config to work.

I can connect but get this message and no shell:
/bin/chroot-shell: No such file or directory

Without the sshd_config settings, the chroot works. But i want to lock the user within /home.
The jail is located in /home/jail

Match Group users
    ChrootDirectory /home
    AllowTCPForwarding no   
    X11Forwarding no
    ForceCommand /usr/lib/openssh/sftp-server

Submitted by frankie (registered user) on Mon, 2009-12-14 13:37.

This feature is nice, but it is annoying users can't write to their own main directory. It makes it useless in my organization, and I guess in many other places where users have write access to their ~. It won't be easy taking them away  that right.

Why was it developed that way ? Are there plans to fix it ?

 

Submitted by faonur (not registered) on Tue, 2009-10-13 12:24.

Hi,
I am newbie to this subject and I couldn't find good source how to disable chrooting for SUNOS sparc machine?
If anybody helps It will be very pleasure for me.
Thanks in advance

Submitted by Samuel (not registered) on Tue, 2009-07-14 02:50.

Hi! thanks for this great tutorial!

I have one problem, if I set the jail for the user to the path /home all seems to be working ok, but then the user has to enter to his directory manually... and can see other users names (even when he cant enter to their directories).

So I tried to set the jail as per user and set to /home/user

But after doing this I get this error when trying to connect to sftp:

Error:    Server unexpectedly closed network connection

What can be wrong? Why I can only set the jail to /home and not to /home/user ?? :(

Submitted by Anonymous (not registered) on Wed, 2009-10-14 05:24.
Because chrooted directory (and all directories above) need to be owned by root and writible only by root. Read man sshd_config.
Submitted by Anonymous (not registered) on Mon, 2009-08-17 21:32.
same problem..
Submitted by neon (not registered) on Mon, 2009-06-08 19:35.
 information is very clear. good and understandable explanation. super-topics. Thank you for sharing a very nice web site.
Submitted by Martin (not registered) on Thu, 2009-04-16 10:16.

It's not true that "no patches are needed anymore". If your users keep sensible data in their chroot directory, they might be thankful if the administrator does indeed patch OpenSSH once in a while.

Also, it's not true that you cannot break out of a chroot shell. There have been local exploits in the past that made this possible.

However, OpenSSH with chroot is more secure than without, so thank you for this tutorial!
Submitted by andrewm659 (registered user) on Tue, 2009-03-31 03:06.

 I have done the necessary config, but if i have multiple users, how do i chroot each users's home dir?  can i do a ChrootDirectory /home/$user?  Is there something like this?

Submitted by Anonymous (not registered) on Mon, 2009-03-23 21:31.
I am running debian lenny and could not get sftp to work till I changed the subsystem to interal-sftp and not the path to the sftp-server. 
Submitted by Tobias Nyström (not registered) on Mon, 2009-03-23 18:22.

If you're hitting this error it means that your base directory / has the wrong permissions:

fatal: bad ownership or modes for chroot directory component "/"

You should do:

chmod 755 /

// gl hf :) Tobias

Submitted by eolo999 (not registered) on Sun, 2009-03-22 14:43.

Hi,

on my ubuntu hardy box i get the following error while trying to add:

Match User falko
ChrootDirectory /home
AllowTCPForwarding no
X11Forwarding no

 Error:

/etc/ssh/sshd_config line 80: Directive 'ChrootDirectory' is not allowed within a Match block

 

any hints?

Submitted by Heinz (not registered) on Sun, 2009-04-26 13:29.

dpkg -l openssh-server ii openssh-server 1:4.7p1-8ubuntu1.2 secure shell server, an rshd replacement The version used in hardy is < 4.8 Chroot is not supported since version 4.8

Submitted by Mike Mueller (not registered) on Thu, 2009-03-19 17:50.

In some scenarios the chroot patch suits better as the build-in chroot function. Chrooted users can be defined by homedir path (by simply adding /./ to the current homedir; ex. /home/sn00p/./)

For this reason we continue the great patch originally written by Ricardo Cerqueira for newer OpenSSH releases. The patch can be found at: http://web.cybnet.ch/misc/opensource/openssh-5.2p1-chroot.patch

Submitted by cisco pagola (not registered) on Sat, 2009-03-28 07:58.

Hello I follow this guide and I can't get chroot working properly, after I edit my sshd_config I can't login to my sftp server. with any user.

 This is my configuration file. Any suggentions?????? , I have debian Lenny


# Package generated configuration file
# See the sshd(8) manpage for details

# What ports, IPs and protocols we listen for
Port 22
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes

# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 768

# Logging
SyslogFacility AUTH
LogLevel INFO

# Authentication:
LoginGraceTime 120
PermitRootLogin yes
StrictModes yes

RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile    %h/.ssh/authorized_keys

# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes

# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Change to no to disable tunnelled clear text passwords
PasswordAuthentication yes

# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes

X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no

#MaxStartups 10:30:60
#Banner /etc/issue.net

# Allow client to pass locale environment variables
AcceptEnv LANG LC_*

Subsystem sftp /usr/lib/openssh/sftp-server

UsePAM yes
 

AllowUsers ciscolin   #I tried with an without this

#AllowGroups users

Match User ciscolin
   ChrootDirectory /var/www/project
   AllowTCPForwarding no
   X11Forwarding no
   ForceCommand /usr/lib/openssh/sftp-server     #I tried with both two

 #ForceCommand internal-sftp


  I tried everything and nothing seems to work. I Have debian Lenny

Thanks in advance guys.

Submitted by zhanchangheng (not registered) on Thu, 2009-07-02 10:06.

use
Subsystem sftp internal-sftp
and delete the line in Match
Match User ciscolin   ChrootDirectory /var/www/project   AllowTCPForwarding no   X11Forwarding no  ForceCommand /usr/lib/openssh/sftp-server    
then it's ok

Submitted by zhanchangheng (not registered) on Thu, 2009-07-02 10:04.

use
Subsystem sftp internal-sftp
and delete the line in Match
Match User ciscolin   ChrootDirectory /var/www/project   AllowTCPForwarding no   X11Forwarding no  ForceCommand /usr/lib/openssh/sftp-server    
then it's ok

Submitted by tiscarabee (registered user) on Thu, 2009-12-03 10:02.

Hello all,

I've tried both

    ForceCommand /usr/lib/openssh/sftp-server
    and ForceCommand internal-sftp

with

   Subsystem sftp /usr/lib/openssh/sftp-server

and/or 

  Subsystem       sftp    internal-sftp

Good rights are on the files, and same configuration on a similar server (64bits, lenny) will work... but not on this server ! (the one where I really need chroot sftp, of course :)

I've surfed a lot and read lot of topics, but nothing more precise on an immedite closed session by the server. And no error in the logs...

http://pastebin.ca/1699821

Any idea is welcome, and thks again for clean Falko's works.

Submitted by tiscarabee (registered user) on Fri, 2009-12-04 20:11.

One day later, doing anything, it work... un-understandable.
Perhaps, just activating and desactivating the  PasswordAuthentication rule in the Match for my user...
Happy, I can work, but worry about ghost in my shell (or my head) ! :]
 

Submitted by Sid (not registered) on Fri, 2011-03-25 09:52.
I was extremely frustrated with the same thing. After a reboot of the whole system it starts to work, just restarting the ssh is not enough.
Submitted by William (not registered) on Tue, 2009-03-24 08:54.

On my Lenny box,

ForceCommand /usr/lib/openssh/sftp-server

did not work. I was unable to connect to it with Filezilla. This worked, however:

ForceCommand internal-sftp

What's the difference between the two?

Submitted by bro (registered user) on Wed, 2009-05-27 19:02.

It seems that you have to use

Subsystem sftp internal-sftp

and

ForceCommand internal-sftp

unless you have set up your chroot with the usual support files (/etc ...).

Submitted by bro (registered user) on Wed, 2009-05-27 18:49.

According to the manual page "internal-sftp" doesn't require the chroot to be populated with any files - contrary to "sftp-server" that needs some support files, maybe /etc/passwd, /etc/group etc. like chroots usually do.