SSH File Transfer Protocol (SFTP) is a secure and robust file transfer protocol that leverages the full authentication and security of Secure Shell (SSH) functionality. Its one of the best alternative to the legacy FTP and FTP/S protocols since it offer advanced capabilities but is easy to configure, reliable, and more secure.
SFTP safeguards the integrity of your data using cryptographic and encryption hash functions. Besides, its abilities to protect against man-in-the-middle attacks and password sniffing are second to none.
Although it offers numerous benefits, this protocol comes with no extra configuration on servers with activated SSH access. This a major setback because by default, SSH server permits terminal shell access and file transfer access to a user with system’s account.
However, in some instances, it’s always important to give some user file transfer access while limiting their SSH access. This guide will show you how to configure an SSH daemon that will bar SFTP access to a single directory and limit SSH access on the per-user basis.
Ready? Let's go!
For this process to run smoothly, you require the following:
- An Ubuntu 18.04 VPS or dedicated server
- A user (non-root) with sudo privileges
- Firewall enabled
Step 1 - Constituting A User
The first step in our tutorial is to create the new user we intend to give the file transfer permissions. In our case, we’ll use hostadvicefiles as the username; feel free to use a different username. Run the command below to create the user:
$ sudo adduser hostadvicefiles
Once you run the command above, you will be asked to provide a new password for this account. You will also be prompted to provide additional information regarding the user. You don't have to give the username information; it's optional. If you do not want to give username details, simply press ENTER.
By now, you have fashioned anew user, we can now proceed and create the file transfer directory and configure the privileges.
Step 2 - Creating The File Transfer Directory
To successfully limit SFTP file access to any directory, the directory must comply with all permissions requirements for the SSH server. In particular, such a directory and the other folders above it in a filesystem structure must belong to the root and should only be writable by the root. It's also worth noting that we can not limit access to home directories because they belong to the user and not the root.
To evade the ownership issue we will create a new directory /var/sftp/uploads and use it as our central upload directory. The /var/sftp will belong to the root and no user will have the permission to edit this file. The user we created in step 1 (hostadvicefiles) will own the subdirectory /var/sftp/uploads, and we’ll have the permission to move files to this folder.
First, run the command below to create the new directory:
$ sudo mkdir -p /var/sftp/uploads
Next, execute the command below to set the root as the /var/sftp owner:
$ sudo chown root:root /var/sftp
Now, you need to grant the root write privileges to /var/sftp and permit other users to only execute and write.
$ sudo chmod 755 /var/sftp
Run the command below to grant the user (hostadvicefiles) the ownership to /var/sftp/uploads:
$ sudo chown sammyfiles:sammyfiles /var/sftp/uploads
That is it! The structure of our directory is set and we can now proceed to the next step.
Step 3 - Modifying SSH Server Configuration
Here, we’ll alter the SSH (Secure Shell) server configuration settings to permit file transfer access and restrict terminal access for the user (hostadvicefile).
First, run the command below to open the configuration file of the SSH server:
$ sudo nano /etc/ssh/sshd_config
To the bottom of this file, add the following snippet:
... MatchUserhostadvicefiles ForceCommandinternal-sftp PasswordAuthenticationyes ChrootDirectory/var/sftp PermitTunnelno AllowAgentForwardingno AllowTcpForwardingno X11Forwardingno
Save and exit this file.
Here is an explanation of each part of the above configuration snippet:
- Match User: this instructs SSH server to implement the commands strictly to hostadvicefiles
- ForceCommand internal-sftp: This part commands SSH to start SFTP server during login to disallow shell access.
- PasswordAuthentication yes: Prompts password verification for the user
- ChrootDirectory /var/sftp/: used to make sure the user accesses nothing beyond the directory; /var/sftp
- The last three parts deactivate port forwarding, tunneling, as well as X11 forwarding in that order.
The above set of command can be replicated for other users too. You only need to change the username to match that of the user of interest.
Now, you can run the command below to restart SSH server and implement all the changes made on the configuration:
$ sudo systemctl restart sshd
Step 4 - Authenticating Our Configuration
Now, we need to ensure that the user has permissions to only move files. Login to your server as hostadvicefiles via the standard shell access;
$ ssh hostadvicefiles@localhost
You get the error message below, prior to being directed back to the original prompt:
This service allows sftp connections only. Connection to localhost closed.
This indicates that the user (hostadvicefiles) cannot use SSH to log in to the shell server. Next, run the command below to see if hostadvicefiles can access the SFTP:
$ sftp hostadvicefiles@localhost
If everything is fine, you get the message below:
Connected to localhost. sftp>
While in the SFTP prompt, run the command below to see all directory contents:
This will give you an output showing the uploads directory created in step 2.
Try to change directory to another just above it:
The command will deliver no change; it will list all directory files as outputted by the listing command. This means that hostadvicefiles cannot switch to a parent directory. It signifies the success of our configuration and only permits the user (hostadvicefiles) to only log into the server via the SFTP file transfer protocol.
That is it! We have successfully configured SSH File Transfer Protocol to permit the user to access one directory without having complete shell access. If you intend to replicate this configuration to numerous users, repeat the process for each user.