Chrooting SSH Users

This guide will explain how to chroot an SSH user.
This is NOT a guide on how to jail/chroot an sFTP user, but allow the user to ssh into the device with restricted access and restricted commands.

Quick Links:
Directory Structure
SSH config
User Creation
Shell Access
Command Access


I am going to create a chrooted SSH user in a method that is scalable.

If you wish to add another user – see Users section.

If you wish to allow the users access to more commands, see the commands section.

Users will be chrooted to:


You can simply add more users by following the adding user section. Each additional user will be added to /home/chroot/home/user2, /home/chroot/home/user3 etc


Creating the Directory Structure

To chroot users we need to make sure all of the appropriate directories are created, these are used later on for the binaries and libraries needed to run the environment.

mkdir /home/chroot/home

mkdir -p /home/chroot/{bin,dev,lib64,usr/bin}

Check the permissions:

# namei -l /home/chroot/home
f: /home/chroot/home
dr-xr-xr-x root root /
drwxr-xr-x root root home
drwxr-xr-x root root chroot
drwxr-xr-x root root home

/home/, /chroot/,  /home/ and (bin, dev, lib64, usr/bin) all need to be owned by root:root and the permissions should be 755


SSH Config File

To ssh users we need to add a “Match” line into the ssh config file. If you wish to jail a group of users, then add a Match Group config line, otherwise you can simply jail a single user with “Match User username”:

# vim /etc/ssh/sshd_config

Match Group Jail
ChrootDirectory /home/chroot


User Creation

Now we need to create the user.

When creating the user we assign it a home directory. This home directory is NOT the full path.

This is a little difficult to understand but here we go: In the ssh configuration file we specify “Match” and then ChrootDirectory  /home/chroot. This means the user will see /home/chroot as /. When the passwd file is read and the user is placed in their home directory, it will be any directory under /home/chroot. So we need to make sure it exists and then add the user accordingly.

mkdir -p /home/chroot/home/Luke

This is the ACTUAL directory the user will be chrooted to although they will only see this as /home/Luke.

useradd -d home/Luke/ -G jail Luke
passwd Luke

<enter password>



Permissions are a very important part of this ssh chroot. If they are incorrect the user will not be able to log in.

We have already made sure /home/chroot/home permissions are correct, we also need to make sure that the user has access to their actual home directory /Luke

# namei -l /home/chroot/home/Luke
f: /home/chroot/home/Luke
dr-xr-xr-x root root /
drwxr-xr-x root root home
drwxr-xr-x root root chroot
drwxr-xr-x root root home
drwxr-xr-x Luke Luke Luke <-----needs to be owned by user:user (in this case Luke:Luke)


Binaries and Libraries (bash)

To allow the ssh user access to a shell, we need to copy over the shells binaries to the appropriate location: (my preference is bash):

cp -p /bin/bash /home/chroot/bin/


For this to work we need to find the libraries that bash requires to run:

# ldd /bin/bash => (0x00007ffc16ff9000) => /lib64/ (0x00007f071e7b5000) => /lib64/ (0x00007f071e5b1000) => /lib64/ (0x00007f071e1ee000)
/lib64/ (0x00007f071e9e9000)

We now copy these binaries to the chrooted location:

# cp -p /lib64/ /lib64/ /lib64/ /lib64/ /home/chroot/lib64/


Allowing the use of specific commands

The process here is the same as allowing user access to bash (as we did above)

First we find the binaries associated with the command:

# which ls
alias ls='ls --color=auto'

Copying over to the chroot enviroment

cp -p /usr/bin/ls /home/chroot/usr/bin/


Finding the libraries:

ldd /usr/bin/ls

# ldd /usr/bin/ls => (0x00007ffe3174b000) => /lib64/ (0x00007f16a5685000) => /lib64/ (0x00007f16a5480000) => /lib64/ (0x00007f16a5276000) => /lib64/ (0x00007f16a4eb4000) => /lib64/ (0x00007f16a4c53000) => /lib64/ (0x00007f16a4a2d000) => /lib64/ (0x00007f16a4829000)
/lib64/ (0x00007f16a58b4000) => /lib64/ (0x00007f16a4624000) => /lib64/ (0x00007f16a4407000)


Now we need to copy the libraries over to our chroot environment:

# cp -p /lib64/ /lib64/ /lib64/ /lib64/ /lib64/ /lib64/ /lib64/ /lib64/ /lib64/ /lib64/ /home/chroot/lib64/

You may be prompted if you wish to overwrite the libraries already there, this is because some of these libraries are shared with /bin/bash etc. You can either overwrite or skip.




> ssh [email protected] -p
-bash-4.2$ w
-bash: w: command not found <---exactly! We have not allowed access to this command!
-bash-4.2$ ls -lah <----we have allowed access to "ls"
total 12K
drwxr-xr-x. 2 1002 1002 4.0K Aug 21 09:41 .
drwxr-xr-x. 3 0 0 4.0K Aug 21 09:27 ..
-rw-------. 1 1002 1002 2 Aug 21 09:41 .bash_history
-bash-4.2$ touch
-bash: touch: command not found
-bash-4.2$ su -
-bash: su: command not found
-bash-4.2$ vim
-bash: vim: command not found
-bash-4.2$ cp
-bash: cp: command not found


Troubleshooting – Common Issues

Remember to check /var/log/secure for more information on ssh connection issues”



> ssh [email protected]
Could not chdir to home directory /home/chroot/home/Luke: No such file or directory

Check the users configuration:

# getent passwd Luke

As you can see from above this is WRONG. ssh configuration file jails the user to /home/chroot. Therefore you only need configure the users directory to /home/Luke. Eg:

# getent passwd Luke



> ssh [email protected] -p 666
Connection reset by

PERMISSIONS ISSUE! Check your permissions:

# namei -l /home/chroot/home/Luke/
f: /home/chroot/home/Luke/
dr-xr-xr-x root root /
drwxr-xr-x root root home
drwxr-xr-x Luke Luke chroot <------WRONG! Should be root:root
drwxr-xr-x root root home
drwxr-xr-x Luke Luke Luke

Another common permissions issue:

# namei -l /home/chroot/home/Luke/
f: /home/chroot/home/Luke/
dr-xr-xr-x root root /
drwxr-xr-x root root home
drwx------ root root chroot <----needs to be 755!!
drwxr-xr-x root root home
drwxr-xr-x Luke Luke Luke