Introduction
Vsftpd short of Very Secure File Transfer Protocol Daemon is a secure FTP (File Transfer Protocol) for Ubuntu systems. FTP is the most commonly used standard network protocol for downloading and uploading files between two computers in a given network.
By default, FTP data is insecure because critical information such as usernames, data, passwords, etc. is normally transmitted unencrypted in plain text. Therefore, it is important to ensure the FTP connections are encrypted using vsftpd.
In this tutorial, we will show you how to configure vsftpd with SSL/TLS support on Ubuntu 18.04 VPS.
Prerequisites
Before you begin, make sure you have the following:
- A non-root user with sudo privileges.
- A VPS or dedicated server running on Ubuntu 18.04
- A configured static IP address.
Step 1 – Installing vsftpd
To start off, update the packages and install vsftpd daemon by running the commands below:
$ sudo apt update $ sudo apt install vsftpd
Once the file is installed, check the vsftpd status using the following command:
$ sudo service vsftpd status
Let’s now copy the current configuration file and create an original backup for it before configuring the firewall:
$ sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.orig
Step 2 – Configuring Firewall
Start by checking whether the firewall is enabled. But before that, make sure you allow SSH traffic otherwise the firewall may block these tests.
Now check the status of the firewall. Press y then Enter if warned about altering the SSH connection.
$ sudo ufw status
If the firewall is working properly, you should get a Status: active message and the firewall rules will be automatically added:
Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6)
Now, go ahead and open the ports 20 and 21 for FTP, including ports 40000-50000 for passive FTP. Also, open port 990 to enable TLS which we will set up later:
$ sudo ufw allow 20/tcp $ sudo ufw allow 21/tcp $ sudo ufw allow 990/tcp $ sudo ufw allow 40000:50000/tcp $ sudo ufw status
Once the process is complete, the firewall rules output should look like this:
Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 990/tcp ALLOW Anywhere 20/tcp ALLOW Anywhere 21/tcp ALLOW Anywhere 40000:50000/tcp ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) 20/tcp (v6) ALLOW Anywhere (v6) 21/tcp (v6) ALLOW Anywhere (v6) 990/tcp (v6) ALLOW Anywhere (v6) 40000:50000/tcp (v6) ALLOW Anywhere (v6)
Having installed vsftpd and after ensuring the required ports are open, we can proceed to create an FTP user.
Step 3 – Creating FTP User
Let’s create a new user for FTP. Make sure you add a test user. In our example, we will call our new user ftpuser.
$ sudo adduser ftpuser
Create a strong password for it. You will be prompted to enter some key information, then press ENTER for each case.
For FTP to be more secure to users, it should be directed to a certain directory. Vsftpd can achieve this using chroot. Enabling chroot for users restricts them to a specific home directory. But, since vsftpd ensures the home directory is safe, it shouldn’t be writable by the local user.
In this tutorial, instead of getting rid of the write privileges in the home directory, we shall create a new ftp directory in place of chroot and a corresponding writable files directory for the original files.
To create a new ftp folder, run the following command:
$ sudo mkdir /home/ftpuser/ftp
Create an ownership file to the ftp directory to nobody:nogroup:
$ sudo chown nobody:nogroup /home/ftpuser/ftp
Do away with the write permissions:
$ sudo chmod a-w /home/ftpuser/ftp
Now, verify these permissions:
$ sudo ls -la /home/ftpuser/ftp
This will give you an output like the one below
total 8 4 dr-xr-xr-x 2 nobodynogroup 4096 Aug 24 21:29 . 4 drwxr-xr-x 3 ftpuser ftpuser 4096 Aug 24 21:29 ..
The next step is to create a new directory to store uploads and ensure they are assigned to the local user:
$ sudo mkdir /home/ftpuser/ftp/files $ sudo chown ftpuser:ftpuser /home/ftpuser/ftp/files
Now, run the command below to check the permission on ftp directory:
$ sudo ls -la /home/ftpuser/ftp
This will give you the following output:
total 12 dr-xr-xr-x 3 nobodynogroup 4096 Aug 26 14:01 . drwxr-xr-x 3 ftpuser ftpuser 4096 Aug 26 13:59 .. drwxr-xr-x 2 ftpuser ftpuser 4096 Aug 26 14:01 files
Now, add another file test.txt for test purpose:
$echo"vsftpd test file" | sudo tee /home/ftpuser/ftp/files/test.txt
Once the ftp directory is secure and the the files directory is accessible by the user, go ahead and configure FTP.
Step 4 – Configuring FTP -vsftpd Access
The major settings to allow one single user to connect with FTP are already made in vsftpd.conf. Create a backup file before editing the config file.
$ sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak
Now, open the config file to confirm that the configuration settings you have match the following:
$ sudo nano /etc/vsftpd.conf
You should see the output below:
. . . # Allow anonymous FTP? (Disabled by default). anonymous_enable=NO # # Uncomment this to allow local users to login. local_enable=YES . . .
Now, you need to allow the FTP users to upload files to the server by uncommenting the setting labelled write_enable in the directory /etc/vsftpd.conf.
. . . write_enable=YES . . .
Now, go ahead and edit the chroot to make sure the FTP users have no access to any files apart from those in the directory /etc/vsftpd.conf:
. . . chroot_local_user=YES . . .
Add a user_sub_token line to include a username in the local_root directory to ensure the configuration process works for the local user and any other users in future. Add the following settings in the file /etc/vsftpd.conf:
. . . user_sub_token=$USER local_root=/home/$USER/ftp
Also, let’s add the ports limit range for passive FTP to ensure there are enough connections available:
. . . pasv_min_port=40000 pasv_max_port=50000
Note that we opened these ports in Step 2 to setup the port range for passive FTP. In case of any changes made to these values, ensure you update the firewall settings.
To make sure that users can access FTP only when they are on the list, and not by default, let’s set the following configuration in the directory /etc/vsftpd.conf:
. . . userlist_enable=YES userlist_file=/etc/vsftpd.userlist userlist_deny=NO
From the configuration above, if userlist_deny is set to YES, it means that the users added on the list will not gain FTP access. If it is set to NO, the only users allowed access are those on the list.
Once you have done these changes, save your file and exit.
Now, add the user to /etc/vsftpd.userlist. Make sure you use the -a flag attached to the file:
$echo"ftpuser" | sudo tee -a /etc/vsftpd.userlist
Check to ensure that the file has been added:
$ cat /etc/vsftpd.userlist
This will deliver the output below:
ftpuser
Lastly, restart the vsftpd daemon to apply these changes:
$ sudo systemctl restart vsftpd
Once you have the configuration set, now test the FTP access.
Step 5 – Testing FTP Access
Now that you have successfully configured your server to allow the ftpuser to connect through FTP, we need to ensure this process works properly.
Start by trying whether anonymous can gain access to the system. If the configuration is working as planned, non-users should not access the system.
$ ftp -p (IP address)
The output should look like this:
Connected to IP address. 220 (vsFTPd 3.0.3) Name (IP address:default): anonymous 530 Permission denied. ftp: Login failed. Ftp
Now close the connections:
ftp>bye
Next, try to connect as a sudo user. Other users other than ftpuser should be denied permission before they even enter their password.
$ ftp -p IP address
The output should look like this:
Connected to IP address. 220 (vsFTPd 3.0.3) Name (IP address:default): sudo_user 530 Permission denied. ftp: Login failed. ftp>
Now, close the connection:
ftp>bye
Next, the ftp user should connect, read, and even write files. We need to ensure that our user finds it’s easy to connect:
$ ftp -p IP address
The output should look like this:
Connected to IP address. 220 (vsFTPd 3.0.3) Name (IP address:default): ftpuser 331Please specify the password. Password: your_user's_password 230Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp>
Now, change to the files directory and transfer the files created earlier to your computer using the get command:
ftp>cd files ftp> get test.txt
The output should look like this:
227EnteringPassiveMode (IP address). 150OpeningBINARY mode data connection for test.txt (16 bytes). 226Transfer complete. 16 bytes received in0.0101 seconds (1588 bytes/s) ftp>
Now, let’s test the write permissions by uploading our file in the directory with a new name:
ftp> puttest.txtupload.txt
The output should look like this:
227EnteringPassiveMode (IP address). 150Ok to send data. 226Transfer complete. 16 bytes sent in0.000894 seconds (17897 bytes/s)
Now, close the connections:
ftp>bye
Having tested the configuration, let’s secure the server.
Step 6 – Securing The Transactions
FTP doesn’t encrypt data including the user’s credentials. So, we will activate TLS/SSL to get an encryption. Start by creating an SSL certificate for vsftpd.
To do so, we will use OpenSSL for the certificate and include the -days line to acquire one-year validity. We will also include a private key on this command to have the certificate and the key in one file:
$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem
You will be asked to provide more details for the certificate. Use your information on the highlighted areas in the display below:
Generating a 2048 bit RSA private key ............................................................................+++ ...........+++ writing newprivate key to '/etc/ssl/private/vsftpd.pem' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:NY Locality Name (eg, city) []:New York City Organization Name (eg, company) [Internet Widgits Pty Ltd]:HostAdvice Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []: your_server_ip Email Address []:
Once the certificates are ready, go to the vsftpd configuration file and open it again:
$ sudo nano /etc/vsftpd.conf
At the bottom are two lines starting with RSA. Edit them so that you have something like this:
. . . # rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem # rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key . . .
On the next line in the same directory (/etc/vsftpd.conf), add the following information:
. . . rsa_cert_file=/etc/ssl/private/vsftpd.pem rsa_private_key_file=/etc/ssl/private/vsftpd.pem . . .
The next thing is to ensure SSL is working to prevent TLS users from gaining access. This is important to make sure all the traffic is fully encrypted. However, this move may force the FTP user to change clients.
Go ahead and change ssl enable to YES
/etc/vsftpd.conf
. . . ssl_enable=YES . . .
Edit and add these lines to deny anonymous access over SSL:
/etc/vsftpd.conf
. . . allow_anon_ssl=NO force_local_data_ssl=YES force_local_logins_ssl=YES . . .
Now, add the following lines to configure your server to use TLS:
/etc/vsftpd.conf
. . . ssl_tlsv1=YES ssl_sslv2=NO ssl_sslv3=NO . . .
Lastly, we will include two extra options. We will need high encrypted cipher suites meaning that the key lengths will be 128 bits or more:
/etc/vsftpd.conf
. . . require_ssl_reuse=NO ssl_ciphers=HIGH . . .
The output will look like this:
/etc/vsftpd.conf
# This option specifies the location of the RSA certificate to use for SSL # encrypted connections. #rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem #rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key rsa_cert_file=/etc/ssl/private/vsftpd.pem rsa_private_key_file=/etc/ssl/private/vsftpd.pem ssl_enable=YES allow_anon_ssl=NO force_local_data_ssl=YES force_local_logins_ssl=YES ssl_tlsv1=YES ssl_sslv2=NO ssl_sslv3=NO require_ssl_reuse=NO ssl_ciphers=HIGH
When everything is complete, save and exit the file.
Now restart the system to apply these changes:
$ sudo systemctl restart vsftpd
The next step is to verify that it is possible to connect to the server with a client supporting TLS.
Step 7 – Testing TLS Using FileZilla
To test TLS we shall use FileZilla since it offers a cross-platform support service.
When you’re inside FileZilla, locate the Site Manager and click on it.
On the new window, press the New Site button.
Go to My Sites icon where you will see another icon labeled New Site. Use the Rename button to assign a new name to your site.
Enter your name or IP address in the Host field. Go to Encryption and choose Require explicit FTP over TLS.
For the Login Type section, select Ask for password. Enter your FTP user in the next section labeled User field.
Press the Connect and enter your password.
Press OK to start the connection. Now, you should be automatically be connected to the server using TLS/SSL encryption.
If everything worked out properly, you will see a server certificate display as shown below:
After accepting the certificate, go to the files folder and double click on it, then drag upload.txt to the left side to ensure you can easily download the files.
Now, rename the copy to upload-tls.txt then transfer it back to the server to see if your can successfully upload files.
If the process is successful, it shows you can transfers files using SSL/TLS enable successfully.
Conclusion
Congratulations! You can comfortably set up FTP for different users on Ubuntu 18.04 VPS. Over to you.
Check out these top 3 Linux hosting services
- To know further about best VPS hosting, click here.