Introduction

In one of our previous articles, we demonstrated how to setup an ftp server using vsftpd on a Linux system. FTP is a great way to transfer data between systems but it is not very secure since the data being transferred is not encrypted and therefore exposed to hacking attempts. SFTP is a secure form of the FTP program wherein the entire user session including typing in the password to login to the system is in encrypted. Another useful facet of the SFTP program from an administrators’ perspective is that it is included with the openssh package which is generally installed by default on most UNIX systems. Also, since SFTP is based on SSH it works on port 22 so we do not need to open ports 20 and 21 required by FTP. To add another layer of security restriction upon our SFTP setup, in this article we will explain how to setup chrooted SFTP accounts. A chrooted SFTP account will not allow the user to access any file or directory outside it’s own home directory which is extremely helpful when we want to prevent users from accessing and modifying each other’s files.

Steps to configure chrooted SFTP user account:

For the purpose of this demonstration, we will use an RHEL 6.8 system as our SFTP server and we will set up a user named ‘sahil’ as our chrooted SFTP user account.

Step 1: Create home directory for chrooted users First we will create a directory which will act as the parent directory for the home directories for our chrooted users. This is analogous to the /home directory on a Linux system. We’ll name this directory as chroots.

[root@linuxnix ~]# mkdir /chroots
[root@linuxnix ~]# ls -ld /chroots/
drwxr-xr-x. 2 root root 4096 Jul 19 20:19 /chroots/
[root@linuxnix ~]#

The ownership of the directory should be root:root. We’ll also create a home directory for the user that we’ll create later.

[root@linuxnix ~]# mkdir /chroots/sahil
[root@linuxnix ~]# ls -ld /chroots/sahil/
drwxr-xr-x. 2 root root 4096 Jul 19 22:04 /chroots/sahil/
[root@linuxnix ~]#

The actual home directory for the user sahil will be /chroots/sahil/myhome.

root@linuxnix ~]# mkdir /chroots/sahil/myhome
[root@linuxnix ~]# ls -ld /chroots/sahil/myhome
drwxr-xr-x. 2 root root 4096 Jul 19 22:42 /chroots/sahil/myhome
[root@linuxnix ~]#

For a more complex configuration, we’ve created a home directory for the user sahil under /home/sahil/myhome which we will actually mount on the /chroots/sahil/myhome directory using the bind option.

[root@linuxnix ~]# ls -ld /home/sahil/myhome
drwxr-sr-x. 2 root sahil 4096 Jul 19 22:39 /home/sahil/myhome
[root@linuxnix ~]# chown sahil:sahil /home/sahil/myhome
[root@linuxnix ~]#
[root@linuxnix ~]# ls -ld /home/sahil/myhome
drwxr-sr-x. 2 sahil sahil 4096 Jul 19 22:39 /home/sahil/myhome

[root@linuxnix ~]# grep myhome /etc/fstab
/home/sahil/myhome /chroots/sahil/myhome none rw,noexec,nosuid,nodev,bind 0 0
[root@linuxnix ~]# mount /chroots/sahil/myhome
[root@linuxnix ~]# df -h /chroots/sahil/myhome
Filesystem Size Used Avail Use% Mounted on
/home/sahil/myhome 18G 4.3G 12G 27% /chroots/sahil/myhome
[root@linuxnix ~]#

Step 2: Create a group for chrooted users We could restrict users to their home directories via chroot using either of two approaches. The first approach is to match for a username. This means that the particular user’s names when matched while logging in will not be allowed to access any content on the system outside their home directories. The other approach is to create a group and add the users which we would like to behave as chrooted accounts to that group.  This approach is more conveniently and is the method that is generally used while configuring chrooted accounts. Both methods are implemented by adding parameters in the sshd_config file and we’ll do this shortly. So we will now add a group named sftpusers on the system.

[root@linuxnix ~]# groupadd sftpusers
[root@linuxnix ~]# grep sftpusers /etc/group
sftpusers:x:501:
[root@linuxnix ~]#

Step 3: Create the user/s In this step we’ll create our user which we intend to use as a chrooted sftp account.

[root@linuxnix ~]# useradd -G sftpusers -d /myhome -s /bin/false sahil

Notice that we’ve mentioned the home directory as /myhome although the home directory we created for this user was /chroots/sahil/myhome. We’ll explan the reason for doing this when we configure the chroot parameters in the sshd_config file. Now let’s set a password for the user.

[root@linuxnix ~]# echo "LinuxNix@123" | passwd sahil --stdin
Changing password for user sahil.
passwd: all authentication tokens updated successfully.
[root@linuxnix ~]#

From the output of the above commands, we can assume that our user has been created successfully and the password has been set. Let’s run the id command for this user.

[root@linuxnix ~]# id -a sahil
uid=501(sahil) gid=502(sahil) groups=502(sahil),501(sftpusers)
[root@linuxnix ~]#

Step 4: Chroot configuration This is the most important step in the process since this is where we configure all members belonging to the group sftpusers to act as chrooted user accounts. We’ll now modify the /etc/ssh/sshd_config file. First comment out the line “Subsystem sftp /usr/libexec/openssh/sftp-server” in the file.

[root@linuxnix ~]# tail -6 /etc/ssh/sshd_config
Subsystem sftp internal-sftp
Match Group sftpusers
X11Forwarding no
AllowTcpForwarding no
ChrootDirectory /chroots/%u
ForceCommand internal-sftp
[root@linuxnix ~]#

Given below is a description of the major parameters involved in the chroot configuration: Match Group sftpusers – This indicates that the following lines will be matched only for users who belong to group sftpusers ChrootDirectory %u – The %u in the above entry is a variable place-holder.  So instead of having to type a separate entry for every user you are chrooting, the %u will change to the user-name of the account logging into the server.  This allows you to have multiple users jailed, with only one ChrootDirectory entry as shown above. For our example when the user sahil logs in to the server via sftp, the /chroots/%u will be replaced by /chroots/sahil followed by the path /myhome thereby allowing the user to drop into /home/sahil/myhome as it’s home directory. ForceCommand internal-sftp – This forces the execution of the internal-sftp and ignores any command that is mentioned in the ~/.ssh/rc file. In order to allow the configuration to take effect, we need to restart the sshd service.

[root@linuxnix ~]# service sshd restart
Stopping sshd: [ OK ]
Starting sshd: [ OK ]
[root@linuxnix ~]#

Step 5: Test the setup To test the setup let’s connect to the server via sftp as the user sahil.

[root@linuxnix ~]# sftp sahil@linuxnix
Connecting to linuxnix...
sahil@linuxnix's password:
sftp> pwd
Remote working directory: /myhome
sftp> ls
sftp> cd /tmp
Couldn't canonicalise: No such file or directory
sftp> cd /var
Couldn't canonicalise: No such file or directory
sftp> bye
[root@linuxnix ~]#

Note that when we ran the pwd command the present working directory was shown as /myhome although we never created this directory. The /myhome directory here is actually /chroots/sahil/myhome which infarct has the directory /home/sahil/myhome mounted on it via the bind mount option. If we try to change directories to any other location we are not allowed to do so thereby confirming that our chroot configuration is working correctly.

Conclusion

In this article, we demonstrated how to configure chrooted sftp access with detailed steps and provided a description of the parameters that get added to the /etc/ssh/sshd_config file. Along with setting up our chrooted sftp configuration, we also tested it and verified it’s working. We hope that you’ve found this article to be useful and look forward towards your feedback and suggestions.

The following two tabs change content below.

Sahil Suri

He started his career in IT in 2011 as a system administrator. He has since worked with HP-UX, Solaris and Linux operating systems along with exposure to high availability and virtualization solutions. He has a keen interest in shell, Python and Perl scripting and is learning the ropes on AWS cloud, DevOps tools, and methodologies. He enjoys sharing the knowledge he's gained over the years with the rest of the community.