Chrooted SSH/SFTP Tutorial (Debian Etch)

Version 1.0
Author: Falko Timme

This tutorial describes two ways 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. The users will also be able to use SFTP in their chroot jails.

This document comes without warranty of any kind! I want to say that this is not the only way of setting up such a system. There are many ways of achieving this goal but this is the way I take. I do not issue any guarantee that this will work for you!


1 Preliminary Note

This setup is based on a Debian Etch (Debian 4.0) system.

The first way to set up chrooted SSH is by hand and very similar to the method shown in this tutorial for Debian Sarge: The chrooted SSH will be installed in such a way that it will still use the configuration files of the standard OpenSSH Debian package which are in /etc/ssh/, and you will be able to use the standard OpenSSH Debian init script /etc/init.d/ssh. Therefore you do not have to create your own init script and configuration file.

The second way is to use the script from This setup is different from the first one in that we don't need to recompile OpenSSH. Instead of /bin/sh or /bin/bash, the chrooted users use /bin/chroot-shell which uses the sudo and chroot commands to chroot the users. This method is also different in that the users don't have a dot in their homedirs in /etc/passwd (therefore it cannot be used by control panels such as ISPConfig, which is no problem with the first method). Please take a look at to see what this script can do for you and what not.

You should decide for one way - please don't use both ways at the same time!


2 First Method (By Hand)

2.1 Install The Chrooted OpenSSH

First we install some prerequisites:

cd /tmp
apt-get install libpam0g-dev openssl libcrypto++-dev libssl0.9.7 libssl-dev ssh build-essential bzip2

Then we download the patched OpenSSH sources, and we configure them with /usr as directory for the SSH executable files, with /etc/ssh as the directory where the chrooted SSH will look for configuration files, and we also allow PAM authentication:

tar xvfj openssh-4.5p1-chroot.tar.bz2
cd openssh-4.5p1-chroot
./configure --exec-prefix=/usr --sysconfdir=/etc/ssh --with-pam
make install


2.2 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 -p /home/chroot/home/
cd /home/chroot
mkdir -p usr/lib/openssh
mkdir etc
mkdir etc/pam.d/
mkdir bin
mkdir lib
mkdir usr/bin
mkdir dev
mknod dev/null c 1 3
mknod dev/zero c 1 5

chmod 666 dev/null
chmod 666 dev/zero

Now that we have created the necessary directories, we are going 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. I've modified it a little bit:

vi /usr/local/sbin/create_chroot_env


APPS="/bin/sh /bin/bash /bin/cp /bin/ls /bin/mkdir /bin/mv /bin/pwd /bin/rm /bin/rmdir /usr/bin/id /usr/bin/ssh /bin/ping /usr/bin/dircolors /usr/bin/vi /usr/bin/sftp /usr/lib/openssh/sftp-server"
for prog in $APPS;  do
        mkdir -p ./`dirname $prog` > /dev/null 2>&1
        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  > /dev/null 2>&1

(If you want to make more programs available to your chrooted users, just add these programs to the APPS line.)

Now we make the script executable and run it:

chmod 700 /usr/local/sbin/create_chroot_env

Next we have to copy a few additional files and libraries to the chroot jail:

cp /lib/ /lib/ /lib/ /lib/ /lib/ /lib/ ./lib/

cp /etc/hosts etc/
cp /etc/resolv.conf etc/
cp /etc/pam.d/* etc/pam.d/
cp -r /lib/security lib/
cp -r /etc/security etc/
cp /etc/login.defs etc/

cp /usr/lib/ usr/lib/
cp /usr/lib/ usr/lib/
cp /usr/lib/ usr/lib/
cp /lib/ lib/
cp /usr/lib/ usr/lib/

Then we do this:

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 OpenSSH:

/etc/init.d/ssh restart


2.3 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 . (dot) 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 or SFTP as testuser. You should be chrooted and not be able to browse files/directories outside /home/chroot.

Share this page:

11 Comment(s)

Add comment



Ubuntu 8.04 LTS has now libssl0.9.8 instead of the older libssl0.9.7

So these days the updated command should look like this...

apt-get install libpam0g-dev openssl libcrypto++-dev libssl0.9.8 libssl-dev ssh build-essential bzip2


Thanks for your up to date . It help me thank again

From: DeluXe

On Debian you also have to copy the diretory /lib64, otherwise you get an error like this:

# ssh [email protected]
[email protected]'s password:
/bin/bash: No such file or directory
Connection to myserver closed.

From: apt




apps=$(which --skip-alias --skip-functions $APPS)

libs=$(ldd $apps |
    grep -v : | grep / |
    sed 's%^.*[[:space:]]\(/[-[:alnum:]/._]*\)[[:space:]].*$%\1%' |
    sort -u)

for i in $apps $libs; do
    dirname=$CHRD/$(dirname $i)
    [ ! -d $dirname ] && mkdir -p $dirname
    cp $i $dirname

From: Anonymous

Another way is to create user groups that are set by default to use SFTP. If you wanted everyone to use that then you could set that for the default group.

From: Narcis Garcia

I read this guide about the SFTP server part, and I've learnt with a lot of tutorials as this one. I link here my compendium to configure better clients and servers:

(with special care for users and permissions)

From: Anonymous

I followed all the steps, but when i loggin via ssh and sftp, i still can see whole directories outside chroot home. Any suggestion ?

From: Marius

Me too. Can navigate outside and change files in /home/user.

Any other options:

- /etc/passwd restrictions

- rbash

failed as well, by either cannot login or other linoxe effects.

From: selcuk

Hi, i 've same problem . i added chroot line in sshd_config. but this time i cannot create files in root folder of user. also ssh client dowesn't work , because cannot create .ssh and known host files. 

From: selcuk


i apply all steps. also i addes sshd_config chroot %h. user can see their on folders. but i wantto run in sheel ssh command. but i can't create folder in root folder because of root folder owner is root . also cannot create regular file in root folder. 


thanks in advance.

From: Jon McCain

Here is a patch file to fix so it works with Debian 8.2 (aka Jessie) 32-bit. In theory it should work with the amd64 version too as I looked up the new lib folder names for it too. But I have not tested that.

use the command:

patch -i make_chroot_jail_jessie.patch -o

to get the new script.