Annex II.1. Configuring a Secure FTP on Our Linux Server

1. Installing vsftpd

$ sudo apt-get install vsftpd

2. Opening the Firewall

$ ufw status

If the firewall is active, you will have to open some ports. If it is inactive, you won’t have any problem with the FTP server (but there might be a problem with the security of your server). If you need to open ports in your firewall for the FTP server: 20, 21 for FTP, and 990 to enable TLS.

$ sudo ufw allow 20,21,990/tcp

Additionally, we will need to open some ports for passive mode, for example, from 40000 to 50000.

$ sudo ufw allow 40000:50000/tcp

3. Preparing the User Directory

Now, we are going to create a specific user for FTP and configure its home directory to be secure, with no chance to exit to the main directories of the system.

First, we add a user for FTP connections.

$ sudo adduser maricheloftp

You will be asked for a password and some other information. We only need to enter the password; the other information can remain empty.

Vsftpd jails local users in their home directory, and it may not be writable by the user when using shell connections instead of FTP. To avoid this and continue to secure our FTP connections, we are going to create a specific directory for FTP connections where the user, through FTP, will be unable to exit this directory.

$ sudo mkdir /home/maricheloftp/ftp
$ sudo chown nobody:nogroup /home/maricheloftp/ftp
$ sudo chmod a-w /home/maricheloftp/ftp

If we verify the permissions:

$ sudo ls -la /home/maricheloftp/ftp
dr-xr-xr-x 3 nobody       nogroup      4096 Feb 21 17:24 .
drwxr-xr-x 3 maricheloftp maricheloftp 4096 Feb 21 18:48 ..

Now, we are going to create a directory for uploading files.

$ sudo mkdir /home/maricheloftp/ftp/files
$ sudo chown maricheloftp:maricheloftp /home/maricheloftp/ftp/files
$ sudo ls -la /home/maricheloftp/ftp
dr-xr-xr-x 3 nobody       nogroup      4096 Feb 21 17:24 .
drwxr-xr-x 3 maricheloftp maricheloftp 4096 Feb 21 18:48 ..
drwxr-xr-x 2 maricheloftp maricheloftp 4096 Feb 21 18:57 files

And here, we can create a file to test our server.

$ echo "test file" | sudo tee /home/maricheloftp/ftp/files/test.txt

4. Configuring vsftpd

$ sudo nano /etc/vsftpd.conf

Here, you have to change or uncomment the following lines:

anonymous_enable=NO
local_enable=YES
write_enable=YES
chroot_local_user=YES

And add these ones (to enable passive FTP ports):

pasv_min_port=40000
pasv_max_port=50000

and these ones:

user_sub_token=$USER
local_root=/home/$USER/ftp

These last two lines will ensure that local users, when connecting through FTP, will access directly to the ftp directory and not to their home directory.

To allow FTP access only to some users, we add these lines:

userlist_enable=YES
userlist_file=/etc/vsftpd.userlist
userlist_deny=NO

We create the file vsftpd.userlist with the names of the users that will be allowed to use FTP.

$ echo "maricheloftp" | sudo tee -a /etc/vsftpd.userlist

Restart the service.

$ sudo service vsftpd restart

To check if the service is running okay, we can see its status with:

$ sudo service vsftpd status

Enter an editor with the information; to exit, press q.

Testing FTP Access

You can test the FTP access with the ftp command available in Linux and Windows. For Mac, you can use Finder and the option Go and Connect to a Server.

$ ftp maricheloftp@ftp.marich

elo.es
$ ftp ftp.marichelo.es

You will be asked for the password, and you can list with ls and change directory with cd. If you try to connect without inserting a user or using a valid user but not the one included in the vsftpd.userlist file, the connection will be refused.

Now, you can check your Java sources to connect to an FTP server.

6. Securing our FTP server

FTP does not encrypt data transactions, including user credentials, to avoid this hole in security we are going to enable TLS/SSL to provide encryption. First, we have to create the SSL certificates in our server to use them with vsftpd. Here we use openssl to create a certificate valid for 1 year and both the private key and the certificate will be located in the same file. This is only one instruction, only one line.

$ 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 about your address information that will be incorporated in your certificate request.

Once you have created the certificates, we will open the file vsftpd.conf again. We will comment these lines:

#rsa_cert_file=/etc/ssl/certs/ssl-cer-snakeoil.pem
#rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key

And we will add these ones:

rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem

Now, we are going to force the use of SSL always in our FTP server. Change ssl_enable to YES:

ssl_enable=YES

Next, add the following lines to explicitly deny anonymous conections over SSL and require SSL for both data transfer and logins:

allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES

With the following lines we will configure our server to use TLS:

ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO

And finally, we will add these 2 options to don’t require reuse of ssl because it can break many FTP clients and to use key lenghts equal or greater than 128 bits:

require_ssl_reuse=NO
ssl_ciphers=HIGH

Now we will close the configuration file and restart the service. Now, if we try to to connect with the command ftp we will have a message saying that non-anonymous sessions must use encryption.

To try it now we will need a FTP client that supports TLS as FileZilla or our Java program using the class FTPSClient.