Restrict SSH user access to certain directory using chrooted jail on Debian 9

There are several reasons to restrict a SSH user session to a particular directory, especially on web servers, but the obvious one is a system security. In order to lock SSH users in a certain directory, we can use chroot mechanism.

Change root (chroot) in Unix-like systems such as Linux, is a means of separating specific user operations from the rest of the Linux system; changes the apparent root directory for the current running user process and its child process with new root directory called a chrooted jail.

In this tutorial, we’ll show you how to restrict a SSH user access to a given directory in Linux. Note that we’ll run the all the commands as root.

Step 1: Create SSH Chroot Jail

1. Start by creating the chroot jail using the mkdir command below:

# mkdir -p /home/prado

2. Next, identify required files, according to the sshd_config man page, the ChrootDirectory option specifies the pathname of the directory to chroot to after authentication. The directory must contain the necessary files and directories to support a user’s session.

For an interactive session, this requires at least a shell, commonly sh, and basic /dev nodes such as null, zero, stdin, stdout, stderr, and tty devices:

# ls -l /dev/{null,zero,stdin,stdout,stderr,random,tty}
crw-rw-rw- 1 root root 1, 3 Jul 7 10:10 /dev/null
crw-rw-rw- 1 root root 1, 8 Jul 7 10:10 /dev/random
lrwxrwxrwx 1 root root 15 Jul 7 10:10 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jul 7 10:10 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jul 7 10:10 /dev/stdout -> /proc/self/fd/1
crw-rw-rw- 1 root tty 5, 0 Jul 7 10:10 /dev/tty
crw-rw-rw- 1 root root 1, 5 Jul 7 10:10 /dev/zero

3. Now, create the /dev files as follows using the mknod command. In the command below, the -m flag is used to specify the file permissions bits, c means character file and the two numbers are major and minor numbers that the files point to.

# mkdir -p /home/prado/dev
# cd /home/prado/dev/
# mknod -m 666 null c 1 3
# mknod -m 666 tty c 5 0
# mknod -m 666 zero c 1 5
# mknod -m 666 random c 1 8

4. Afterwards, set the appropriate permission on the chroot jail. Note that the chroot jail and its subdirectories and subfiles must be owned by root user, and not writable by any normal user or group:

# chown root:root /home/prado/
# chmod 755 /home/prado/
# ls -ld /home/prado/

drwxr-xr-x 3 root root 4096 Jul  7 10:30 /home/prado/

Step 2: Setup Interactive Shell for SSH Chroot Jail

5. First, create the bin directory and then copy the /bin/bash files into the bin directory as follows:

# mkdir -p /home/prado/bin
# cp -v /bin/bash /home/prado/bin/
'/bin/bash' -> '/home/prado/bin/bash'

6. Now, identify bash required shared libs, as below and copy them into the lib directory:

# ldd /bin/bash (0x00007fff05bb7000) => /lib/x86_64-linux-gnu/ (0x00007fbdad691000) => /lib/x86_64-linux-gnu/ (0x00007fbdad48d000) => /lib/x86_64-linux-gnu/ (0x00007fbdad0ee000)
        /lib64/ (0x00007fbdad8bb000)
# mkdir -p /home/prado/lib/x86_64-linux-gnu
# mkdir -p /home/prado/lib64

# cp -v /lib64/ /home/prado/lib64/
'/lib64/' -> '/home/prado/lib64/'

# cp -v /lib/x86_64-linux-gnu/{,,} /home/prado/lib/x86_64-linux-gnu/
'/lib/x86_64-linux-gnu/' -> '/home/prado/lib/x86_64-linux-gnu/'
'/lib/x86_64-linux-gnu/' -> '/home/prado/lib/x86_64-linux-gnu/'
'/lib/x86_64-linux-gnu/' -> '/home/prado/lib/x86_64-linux-gnu/'

Step 3: Create and Configure SSH User

7. Now, create the SSH user with the useradd command and set a secure password for the user:

# useradd kvm
# passwd kvm

8. Create the chroot jail general configurations directory, /home/prado/etc and copy the updated account files (/etc/passwd and /etc/group) into this directory as follows:

# cp -vf /etc/{passwd,group} /home/prado/etc/

'/etc/passwd' -> '/home/prado/etc/passwd'
'/etc/group' -> '/home/prado/etc/group'

Note: Each time you add more SSH users to the system, you will need to copy the updated account files into the /home/prado/etc directory.

Step 4: Configure SSH to Use Chroot Jail

9. Now, open the sshd_config file.

# vi /etc/ssh/sshd_config

and add/modify the lines below in the file.

#define username to apply chroot jail to
Match User kvm

#specify chroot jail
ChrootDirectory /home/prado

Save the file and exit, and restart the SSHD services:

# systemctl restart sshd


# /etc/init.d/ssh restart

Step 5: Testing SSH with Chroot Jail

10. At this point, test if the chroot jail setup is working as expected:

# ssh [email protected]
-bash-4.4$ ls
-bash: ls: command not found
-bash-4.4$ date
-bash: date: command not found
-bash-4.4$ uname
-bash: uname: command not found

From the output above, we can see that the SSH user is locked in the chrooted jail, and can’t run any external commands (ls, date, uname etc).

The user can only execute bash and its builtin commands such as (pwd, history, echo etc).

Step 6. Create SSH User’s Home Directory and Add Linux Commands

11. From the previous step, we can notice that the user is locked in the root directory, we can create a home directory for the the SSH user like so (do this for all future users):

# mkdir -p /home/prado/home/kvm
# chown -R kvm:kvm /home/prado/home/kvm/
# chmod -R 0700 /home/prado/home/kvm/

12. Next, install a few user commands such as ls, date, mkdir in the bin directory:

# cp -v /bin/ls /home/prado/bin
'/bin/ls' -> '/home/prado/bin/ls'

# cp -v /bin/date /home/prado/bin
'/bin/date' -> '/home/prado/bin'

# cp -v /bin/mkdir /home/prado/bin
'/bin/mkdir' -> '/home/prado/bin/mkdir'

13. Next, check the shared libraries for the commands above and move them into the chrooted jail libraries directory:

# ldd /bin/ls (0x00007ffcdb4d3000) => /lib/x86_64-linux-gnu/ (0x00007f9ccf1a8000) => /lib/x86_64-linux-gnu/ (0x00007f9ccee09000) => /lib/x86_64-linux-gnu/ (0x00007f9cceb96000) => /lib/x86_64-linux-gnu/ (0x00007f9cce992000)
        /lib64/ (0x00007f9ccf5f1000) => /lib/x86_64-linux-gnu/ (0x00007f9cce775000)

# cp -v /lib/x86_64-linux-gnu/{,,,,} /home/prado/lib/x86_64-linux-gnu/
'/lib/x86_64-linux-gnu/' -> '/home/prado/lib/x86_64-linux-gnu/'
'/lib/x86_64-linux-gnu/' -> '/home/prado/lib/x86_64-linux-gnu/'
'/lib/x86_64-linux-gnu/' -> '/home/prado/lib/x86_64-linux-gnu/'
'/lib/x86_64-linux-gnu/' -> '/home/prado/lib/x86_64-linux-gnu/'
'/lib/x86_64-linux-gnu/' -> '/home/prado/lib/x86_64-linux-gnu/'

# ldd /bin/date (0x00007ffe2357b000) => /lib/x86_64-linux-gnu/ (0x00007f4926062000)
        /lib64/ (0x00007f492661b000)

# ldd /bin/mkdir (0x00007fff0936f000) => /lib/x86_64-linux-gnu/ (0x00007fea85c9e000) => /lib/x86_64-linux-gnu/ (0x00007fea858ff000) => /lib/x86_64-linux-gnu/ (0x00007fea8568c000) => /lib/x86_64-linux-gnu/ (0x00007fea85488000)
        /lib64/ (0x00007fea860da000) => /lib/x86_64-linux-gnu/ (0x00007fea8526b000)

Step 7. Testing SFTP with Chroot Jail

14. Do a final test using sftp. Check if the commands you have just installed are working.

Add the line below in the /etc/ssh/sshd_config file:

# enable sftp to chrooted jail
ForceCommand internal-sftp

Save the file and exit. Then restart the SSHD services:

# systemctl restart sshd


# etc/init.d/ssh restart

15. Now, test using SSH, you’ll get the following error:

# ssh [email protected]
This service allows sftp connections only.
Connection to closed.

Try using SFTP as follows:

# sftp [email protected]
# sftp [email protected]
Connected to
sftp> pwd
Remote working directory: /home/kvm
sftp> ls
sftp> mkdir uploads
sftp> ls
public_html  uploads
sftp> ls -l
drwxr-xr-x    2 kvm      kvm          4096 Jul  7 08:18 public_html
drwxr-xr-x    2 kvm      kvm          4096 Jul  7 08:29 uploads

13 Replies to “Restrict SSH user access to certain directory using chrooted jail on Debian 9”

  1. 826117 886267I enjoyed reading your pleasant site. I see you offer priceless info. stumbled into this website by chance but Im positive glad I clicked on that link. You certainly answered all of the questions Ive been dying to answer for some time now. Will undoubtedly come back for much more of this. 480250

  2. 423659 564656After study several with the content material in your site now, we genuinely such as your technique of blogging. I bookmarked it to my bookmark web web site list and will also be checking back soon. Pls check out my web-site likewise and make me aware what you believe. 828458

  3. 58534 123914My spouse and I stumbled more than here from a different website and thought I may possibly as effectively check issues out. I like what I see so now im following you. Appear forward to going more than your internet page repeatedly. 926101

Leave a Reply

Your email address will not be published. Required fields are marked *