There are several reasons to restrict an SSH user session to a particular directory, especially on web servers, but the obvious one is 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 currently running user process and its child (parent) process with a new root directory called a chrooted jail.
In this tutorial, we’ll show you how to restrict SSH user access to a given directory in Linux. Note that we’ll run all the commands as root, use the sudo command if you are logged into the server as a normal user.
Table of Contents
Step 1: Create SSH Chroot Jail
1. Start by creating the chroot jail using the mkdir command below:
# mkdir -p /home/test
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}
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/test/dev/ # cd /home/test/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 the root user, and not writable by any normal user or group:
# chown root:root /home/test # chmod 0755 /home/test # ls -ld /home/test
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 using the cp command as follows:
# mkdir -p /home/test/bin # cp -v /bin/bash /home/test/bin/
6. Now, identify the bash required for shared libs
, as below, and copy them into the lib
directory:
# ldd /bin/bash # mkdir -p /home/test/lib64 # cp -v /lib64/{libtinfo.so.5,libdl.so.2,libc.so.6,ld-linux-x86-64.so.2} /home/test/lib64/
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 tecmint # passwd tecmint
8. Create the chroot jail general configurations directory, /home/test/etc
and copy the updated account files (/etc/passwd and /etc/group) into this directory as follows:
# mkdir /home/test/etc # cp -vf /etc/{passwd,group} /home/test/etc/
/home/test/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 tecmint #specify chroot jail ChrootDirectory /home/test
Save the file and exit, and restart the SSHD services:
# systemctl restart sshd OR # service sshd 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.1$ ls -bash-4.1$ date -bash-4.1$ uname
From the screenshot 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) as seen below:
# ssh [email protected] -bash-4.1$ pwd -bash-4.1$ echo "Tecmint - Fastest Growing Linux Site" -bash-4.1$ history
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 SSH user like so (do this for all future users):
# mkdir -p /home/test/home/tecmint # chown -R tecmint:tecmint /home/test/home/tecmint # chmod -R 0700 /home/test/home/tecmint
12. Next, install a few user commands such as ls, date, and mkdir in the bin
directory:
# cp -v /bin/ls /home/test/bin/ # cp -v /bin/date /home/test/bin/ # cp -v /bin/mkdir /home/test/bin/
13. Next, check the shared libraries for the commands above and move them into the chrooted jail libraries directory:
# ldd /bin/ls # cp -v /lib64/{libselinux.so.1,libcap.so.2,libacl.so.1,libc.so.6,libpcre.so.1,libdl.so.2,ld-linux-x86-64.so.2,libattr.so.1,libpthread.so.0} /home/test/lib64/
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 OR # service sshd restart
15. Now, test using SSH, and you’ll get the following error:
# ssh [email protected]
Try using SFTP as follows:
# sftp [email protected]
That’s it for now! In this article, we showed you how to restrict an SSH user in a given directory (chrooted jail) in Linux. Use the comment section below to offer us your thoughts about this guide.
Hello, I want to ask, I want a user with a chroot jail to be able to run the mysql service. I have moved several binary files. however, I get an error like cannot open ‘/var/run/mysqld/mysqld.sock‘ for reading: No such device or address (2) . Please help
Hello Aaron,
What measures are done to prevent the user from adding their own binaries (+ libraries they depend upon) to the chrooted jail to evade the chroot restrictions? They don’t need to put their uploaded libs to {,/usr}/lib64 in order to use them (they can ask the linker to perform the linking explicitly).
Dear Aaron,
I’ve performed your document steps twice along with the suggestion made by sizeur, but still I’m unable to execute all commands that we’ve added for the particular user.
Upon successful login, I can’t see anything inside /home/.
Please Guide
Hi Aaron, thanks for this valuable write-up and you made it so structured to follow.
I had to change the shell of chroot user to bash by “chsh -s /bin/bash chroot-user“. However Backspace, Tab, Del, and arrow keys not working in the terminal (using ssh). Delete throws a space. Moreover, nano throws “Error opening terminal: xterm-256color.” Please let me if I miss something. Looking for your help. Thanks in advance.
As many other users, the ls or date did not worked for me (command not found). I solved the problem easily by correcting the system PATH variable (add /bin/):
-bash-4.4$ ls
-bash: ls: command not found
-bash-4.4$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
-bash-4.4$ export PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/bin
-bash-4.4$ ls
bin dev etc home lib lib64
PS: Don’t forget to add the export in your .bashrc to make it permanent