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.
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.
Latest posts by Sahil Suri (see all)
- Enabling passwordless authentication for chrooted sftp users in Linux - August 15, 2018
- GitHub and git integration: using ssh instead of https - August 14, 2018
- How to use bash aliases over ssh in Linux - August 9, 2018
- Troubleshooting chrooted sftp account setup in Linux - August 8, 2018
- Using ShellCheck to write better shell scripts - August 6, 2018