Setting up a Chroot Jail SFTP Server

Tuesday, 29 May, 2018

Preliminaries

We are going to imagine a simple situation. You have, in your control, a server class machine, exposed to the world as 'www.myfantasticserver.com'. On this server, is a hard disk (logical or physical) mounted as '/data'. Now, you wish to allow someone, let's say user 'abc' to place some files on this storage volume and retrieve it. Assuming your server is a Linux machine hosting a Debian based operating system (such as Debian itself or Ubuntu), we are going to try and achieve the following. (With a little adjustment, it should work for non Debian distributions as well.)

Setting Up

Traditionally, the File Transfer Protocol (FTP) based servers and clients were used for this purpose. The machine willing to host the files would have to setup an FTP server and the users logging into the machine would have to use an FTP client to access the files. But this is a very insecure protocol. All communication over this protocol, whether it is the authentication password or the files themselves, is unencrypted.

A more modern approach is to setup an SFTP server (a secure FTP). However, the name is a little confusing. It seems to suggest that instead of installing some kind of an FTP server, you will install an SFTP server. Actually, the SFTP server is a part of the OpenSSH software which implements or enables SSH (Secure Shell) communication with your server. So, the first step is to install this software, if not already installed.

$ sudo apt-get update
$ sudo apt-get install openssh-server
$ sudo systemctl start ssh.service
$ sudo systemctl enable ssh.service

All SSH communication happens through port 22. It is therefore extremely important to ensure that in case there is a firewall system enabled on your machine, it allows incoming traffic through port 22. On a Debian based machine, a typical firewall software is the "Uncomplicated Firewall" which can be accessed using the command ufw. To enable all incoming SSH connections,

$ sudo ufw allow ssh

If you wish to have a more fine grained control over whether SSH should be allowed only from a particular network, please refer to the excellent tutorial available on Digital Ocean's website.

Configuring the Secure Shell

How the SSH server behaves is governed by a configuration file /etc/ssh/sshd_config. We need to modify its behavior to setup an SFTP server. Since these files are critical and the smallest of modifications to this file can lead to a breakdown of the service, it is a healthy practice to back it up before changing it.

$ cd /etc/ssh
$ sudo su
# cp sshd_config sshd_config.backup

Now, we edit the file. You can use 'vi', 'vim' or 'nano' to edit the file. You need to find a line that says Subsystem sftp /usr/lib/openssh/sftp-server and replace it with Subsystem sftp internal-sftp. You may find that there is no need of such a replacement but if there is, please do so. Not too long ago, 'sftp-server' was a stand alone program requiring its own separate process but now there is an internal SFTP module within the SSH server. By performing this replacement, we are conveying our intent to use this module instead of the older stand-alone server.

Next, we will tell SSH to do the following

This is achieved by adding the following lines in the 'sshd_config' file.

Match Group sftponly
        ChrootDirectory /data/sftpusers/%u
        ForceCommand internal-sftp
        X11Forwarding no
        AllowTcpForwarding no

And finally, we restart our server to reflect the new additions/edits to the configuration file. Make sure the following command does not give you any error.

# /etc/init.d/ssh restart

Since we need users to belong to 'sftponly' group, let us create that group. Further, we are going to give a non-conventional home directory for each user i.e. '/data/sftpusers', so let's create that as well.

# groupadd sftponly
# mkdir /data/sftpusers

Creating a New User to Login to our SFTP server

For any user, one needs to follow these steps. If you find yourself creating too many users (because your server is meant to be a dedicated SFTP server), you could make a shell script out of the following commands. First step, creator the user. We use the '-m' to demand that the user's home directory be created automatically and the '-d' option to specify the home directory (since we need it to be something other than the usual '/home' directory).

# mkdir /data/sftpusers/abc
# useradd -d /data/sftpusers/abc abc

Add the user to sftponly group and also deny them any default shell (so that they cannot control the command line once logged in this machine),

# useradd -g sftponly abc
# usermod -s /bin/false abc

It is important that the directory which will be used a chroot jail for any user be under the ownership of the root. So, '/data/sftpusers/abc' should be owned by the root. If you created this directory as a root, this should already be the case else you can change the ownership easily by saying,

# chown root:root /data/sftpusers/abc

Now, here is a problem! Because of the requirement that the main folder which will serve as the jail be owned by the root, we have left no place where the user in question will have write access! So, let's create a mock home directory for the user within the folder and make the user its owner.

# mkdir /data/sftpusers/abc/abc
# chown abc:abc /data/sftpusers/abc/abc

Final step is set a password for the user.

# passwd abc

Done! Your user is setup.

Accessing SFTP using FileZilla.

FileZilla is a friendly program which can be run on all major operating systems which allows easy access to an FTP/SFTP server using a simple GUI. Please refer to instructions specific to your OS for installing this. Once it is installed, you can launch the program. At the top are four fields - server, username, password and port.

The server can either be the hostname or the IP address. Generally, when accessing SFTP over a LAN, it will be an IP address beginning with 192.168 but it could be a name if the local administrator has setup a local DNS server. For a public facing machine, the domain name or IP can be provided. The username and password should be as set in the previous section. It is important to note that the port should be set to 22. FileZilla assumes the connection is an FTP connection which uses port 21 for negotiation (authenticating user and for commands) and therefore you may get an error if it is left blank. Clicking QuickConnect should show the a directory with folder 'abc' inside it. All files should be transferred to this location.

Hope this helps!




Up