Chrooted SSH HowTo - Page 2

3 Create The Chroot Environment

Next I create a chroot environment under /home/chroot. This is the directory that all chrooted SSH users will get jailed in, i.e. they will not be able to see any files/directories outside /home/chroot.

I have to create some directories in /home/chroot, and I have to copy a few binaries like /bin/bash, /bin/ls, etc. as well as the libraries on which these binaries depend into the chroot environment so that they are available to any chrooted user.

mkdir /home/chroot/
mkdir /home/chroot/home/
cd /home/chroot
mkdir etc
mkdir bin
mkdir lib
mkdir usr
mkdir usr/bin
mkdir dev
mknod dev/null c 1 3
mknod dev/zero c 1 5

Now that we have created the necessary directories, we are goning to copy some binaries and all the libraries on which they depend into the chroot environment. This is an excerpt of a script that I found on that does this. Just copy and paste the following lines into your shell, and hit Return. If you want to make more programs available to your chrooted users, just add these programs to the APPS line:

APPS="/bin/bash /bin/ls /bin/mkdir /bin/mv /bin/pwd /bin/rm /usr/bin/id /usr/bin/ssh /bin/ping /usr/bin/dircolors"
for prog in $APPS; do
cp $prog ./$prog

# obtain a list of related libraries
ldd $prog > /dev/null
if [ "$?" = 0 ] ; then
LIBS=`ldd $prog | awk '{ print $3 }'`
for l in $LIBS; do
mkdir -p ./`dirname $l` > /dev/null 2>&1
cp $l ./$l

Then we do this:

cp /lib/ /lib/ /lib/ ./lib/
echo '#!/bin/bash' > usr/bin/groups
echo "id -Gn" >> usr/bin/groups
touch etc/passwd
grep /etc/passwd -e "^root" > etc/passwd

You should also copy the line of the group in which you will create new users from /etc/group to /home/chroot/etc/group. In this tutorial we will create users in the group users, so we do this:

grep /etc/group -e "^root" -e "^users" > etc/group

and restart SSH:

/etc/init.d/ssh restart

4 Create A Chrooted User

Even with the chrooted SSH that we have just installed you can log in without being chrooted (which makes sense if you log in as root, for example). Now, how does the chrooted SSH decide whom to chroot and whom not? That's easy: the chrooted SSH looks up the user who is trying to log in in /etc/passwd. If the user's home directory in /etc/passwd has a . in it, then the user is going to be chrooted.

Example (from /etc/passwd):

user_a:x:2002:100:User A:/home/user_a:/bin/bash

This user will not be chrooted.

user_b:x:2003:100:User B:/home/chroot/./home/user_b:/bin/bash

This user will be chrooted.

Now we create the user testuser with the home directory /home/chroot/./home/testuser and the group users (which is the default group for users on Debian so you do not have to specify it explicitly):

useradd -s /bin/bash -m -d /home/chroot/./home/testuser -c "testuser" -g users testuser

Then we give testuser a password:

passwd testuser

Finally, we have to copy the line for testuser in /etc/passwd to /home/chroot/etc/passwd:

grep /etc/passwd -e "^testuser" >> /home/chroot/etc/passwd

We have already copied the users group line from /etc/group to /home/chroot/etc/group so we do not have to do this here again. If you create a chrooted user in another group than users, add this group to /home/chroot/etc/group:

grep /etc/group -e "^othergroup" >> /home/chroot/etc/group

Now try to log in to SSH as testuser. You should be chrooted and not be able to browse files/directories outside /home/chroot.

Have fun!


Share this page:

12 Comment(s)

Add comment


From: Anonymous

How do you enable to your users a password change? This is IMO the biggest problem when offering a chrooted shell. The only way i found is to synchronise the chrooted passwd file and the real /etc/passwd file but still, you need to enable really close checks what excactly has been changed in the chroot passwd file...

Another thing is that breaking out of a chrooted shell environment is really easy, in order to prevent that, you'll need to set up the grsecurity kernel which does not allow the chdir() outbreak. So if you need *real* security with chrooted users, you need to do far more than just set up this environment.

From: Anonymous

It seems to be a good idea to put chrooted users in sshd_config file with the "AllowUsers" option. In this way only chrooted users are allowed to log in via sshd.

Another approach is to utilize systrace[1]. polarizers 2cent


From: Anonymous

try using checkinstall instead of make install it makes uninstalling easier, it will walk you through and then pack a deb file and install it. which you can uninstall if anything goes wrong.


 During lib copy script, ldd /bin/bash  | awk '{ print $3 }' misses /lib/

 #  ldd /bin/bash =>  (0xffffe000) => /lib/ (0xb7f0d000) => /lib/tls/i686/cmov/ (0xb7f0a000) => /lib/tls/i686/cmov/ (0xb7dda000)
        /lib/ (0xb7f56000)

 Just finish with "cp /lib/ lib/" to correct it.

From: Anonymous

Any thoughts on how to modify this for sftp usage only for several users and a shared directory (not a subdir of /home/)? And would less binaries be needed?

From: Versatilist

hi how are you doing. my name is fikret it is a turkish name, im new here i did have read the article creating a chroot environment and did have read your comment, did you ever refer to and look there for ssh sftp as search items passed to the search query on the front page, visit following url and read the faq and everything that might be important please tell me if you did had success. have fun

From: starzinger

Thanks alot, this tutorial was really helpful!

Finally I can setup a free shell access service :)



If you're a windows user following the instructions, you have to use Firefox.  If you use Internet Explorer or one of it's derivatives the script will format wrong when you copy it and won't run properly when you paste it into the command line with Putty of whichever program you're using.

For example, the above script comes out like this when copied from IE:

APPS="/bin/bash /bin/ls /bin/mkdir /bin/mv /bin/pwd /bin/rm /usr/bin/id /usr/bin/ssh /bin/ping /usr/bin/dircolors"for prog in $APPS;  do        cp $prog ./$prog        # obtain a list of related libraries        ldd $prog > /dev/null        if [ "$?" = 0 ] ; then                LIBS=`ldd $prog | awk '{ print $3 }'`                for l in $LIBS; do                        mkdir -p ./`dirname $l` > /dev/null 2>&1                        cp $l ./$l                done        fidone


This worked great! Many thanks.

I have only a few remarks:

i) To be able to use sftp and scp, I had to add "/usr/bin/sftp /usr/bin/scp" to the APPS variable on the chroot env build script AND I had to copy /usr/lib/sftp-server to the chroot environment;

ii) I've also add "/bin/rmdir" to the APPS var. But this is only an option.

From: SOR

Does the proposed solution work together with LDAP authentication? In the server, the user data is in the LDAP database, rather than in /etc/passwd, etc.  Please comment. Thanks.

From: Anonymous
From: Mike Mueller

While doesn't exists anymore a patch for the newer releases of OpenSSH can be found at: