SFTP Chroot Jail
Howto create a sftp chroot jail
SFTP Chroot Jails are a simple and easy way of creating a secure area on your Linux system that can be used for transferring files. A SFTP chroot jail allows you to create a secure directory that confines a user to specific area.
In the following example we will create a SFTP chroot jail that will confine a user to a particular directory. Our remote server is running RHEL 6.6 (Red Hat Enterprise Linux). We will be connecting to our sftp server from an Ubuntu 15.04 system. The following sections will take you through the simple set up that is required.
SFTP Chroot Jail
First we are going to modify the file "/etc/ssh/sshd_config". Comment out the line that begins Subsystem and replace it with the following line:
Subsystem sftp internal-sftp
Next add the following lines to the bottom of the same file:
Match Group sftpgroup ChrootDirectory %h ForceCommand internal-sftp AllowTcpForwarding no X11Forwarding no
The file "/etc/ssh/sshd_config" is the OpenSSH Daemon configuration file. Below is an explanation of the parameters used above:
Subsystem The subsystem option allows for the configuration of an external subsystem. The basic syntax is for a subsystem name, followed by a command.
On our system we are specifying “internal-sftp” which allows us to implement an in process "sftp” server. This is used to simplify the configuration of a ChrootDirectory.
Match is known as a conditional block. If all of the criteria of the Match line are met, then the following lines are used instead of the settings found in the global section.
In our example we are specifying a "Group" called sftpgroup. You may change this name to something that matches your system naming convention. This line means that the following lines will only be applicable to members of the specified group.
ChrootDirectory %h specifies that the user will be chrooted to their home directory.
The line "ForceCommand internal-sftp" will force execution of the internal-sftp subsystem.
The line "AllowTcpForwarding no" Specifies whether TCP forwarding is permitted. The default setting is “yes”. Note that disabling TCP forwarding does not improve security unless users are also denied shell access.
X11Forwarding no specifies that X11 forwarding is not allowed.
Creating a sftp user and group
The next part of this tutorial will show you how to create the user and group that we are going to use in our example. Here we will be using standard commands for the creation of the user and associated group.
Create a sftp group
To create a group we use the command groupadd. Note the group you create must be the group that you have specified in the "sshd_config" file. In our example we will create a group called "sftpgroup".
Create the sftp user account
To create a user, we will use the "useradd command. Here we will specify that the user must be a member of the group sftpgroup and that their default shell is set to nologin. By specifying the nologin option, we can limit the users access to only a sftp connection.
useradd -G sftpgroup -s /sbin/nologin sftpuser
Change the ownership and permissions of the sftpuser
When using a chroot jail, it is important to set the specified top level directory to be owned by root. To change the ownership from the normal user to that of the root user, we use the command chown.
chown root:root /home/sftpuser
Next we change the permissions on the directory as follows:
chmod 755 /home/sftpuser/
Create directory structure for sftpuser
In the next step we will create an upload and download directory structure. We will then grant the necessary privileges to the sftpuser.
cd /home/sftpuser/ mkdir upload mkdir download chown sftpuser:sftpgroup upload chown sftpuser:sftpgroup download
You should now have a similar directory structure with the following ownership and permissions set.
# ls -ld /home/sftpuser/ drwxr-xr-x. 6 root root 4096 Jun 7 09:37 /home/sftpuser/ # ls -ld /home/sftpuser/upload/ drwxr-xr-x. 2 sftpuser sftpgroup 4096 Jun 7 09:37 /home/sftpuser/upload/ # ls -ld /home/sftpuser/download/ drwxr-xr-x. 2 sftpuser sftpgroup 4096 Jun 7 09:37 /home/sftpuser/download/
Create a Password for the sftpuser
For the user to access the server, a password will need to be assigned to the account that was created earlier. To do this, we will use the command "passwd"
Configure iptables firewall rules
If you are using a firewall, you may need to open the port that your ssh daemon is running on. In this example we are using port 22. This is the default port for ssh and sftp. If you need to open a port using iptables, you may configure the firewall as follows:
First verify that you are using iptables and that it is active by issuing the following command: service iptables status
[root@rhel01a ~]# service iptables status Table: filter Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 5 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) num target prot opt source destination 1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) num target prot opt source destination
From the above output we can see that port 22 is already open:
4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
If you can not see port 22 open, you will need to issue the following command: iptables -A INPUT -p tcp --dport 22 -j ACCEPT
[root@rhel01 root]# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
For more information on using iptables, see our quick user guide iptables
Configure SELinux Settings for Chroot Jails
If you are running SELinux you will need to grant read/write access to chroot home directories.
To check if you are using SELinux in enforcing mode, you can issue the following command: sestatus
[root@rhel01a ~]# sestatus SELinux status: enabled SELinuxfs mount: /selinux Current mode: enforcing Mode from config file: enforcing Policy version: 24 Policy from config file: targeted
If you are running in enforcing mode, then you will need to grant the read/write permissions by running the following command: setsebool -P ssh_chroot_rw_homedirs on
setsebool -P ssh_chroot_rw_homedirs on
For information regarding SELinux, see our Introduction to SELinux
Testing access to the SFTP Server
The final test now is to connect to our test server.
john@ubuntu01-pc:~$ sftp firstname.lastname@example.org email@example.com's password: Connected to 192.168.0.40. sftp> pwd Remote working directory: / sftp> ls download upload sftp> cd upload/ sftp> lcd /home/john sftp> put test.txt Uploading test.txt to /upload/test.txt test.txt 100% 15 0.0KB/s 00:00 sftp> ls -l -rw-r--r-- 1 502 503 15 Jun 7 13:24 test.txt sftp> cd .. sftp> pwd Remote working directory: / sftp> cd download/ sftp> pwd Remote working directory: /download sftp> cd / sftp> pwd Remote working directory: / sftp> quit
In the above example we initiated our sftp connection by issuing the command sftp firstname.lastname@example.org
(sftpuser is the user we are using to connect with and the address 192.168.0.40 is the address of our remote server).
You can replace this address with your address or the hostname of the server you are connecting to.
First we issue the command pwd as this will display our current working directory.
If we issue the ls command we can see the two directories that we created earlier.
Next I changed the remote directory to the upload directory using the command cd upload
As a test I then changed the local directory on the local client to /home/john where I have a small test file called test.txt. The command lcd is used to specify a local directory to be used.
As I test I used the put command to upload a file to the remote directory. The output can be seen in the above example.