Once you’ve installed an FTP server on your Linux machine, it’s time to look into security. Earlier, I showed you how to set up an FTP server using “Pure-FTPd” because of its ease of use and its inbuilt support for virtual users. This allows you to maintain a distinction between FTP users and system users. While other programs like vsftpd also support virtual users, it’s not as seamless.
But FTP is an inherently insecure protocol. Here’s why.
Plain Text Username and Password Transmission
When your FTP client connects with the remote server, it sends the username/password credentials. By default this contains no encryption whatsoever. It means that anyone intercepting your transmission will have no difficulties reading your authentication data and can then connect themselves without a hitch. Here’s a proof of concept.
I used a popular Windows program called “Wireshark” to monitor my network traffic. It allows me to choose a network interface, and then filter out the traffic based on a variety of parameters. In this example, I selected to monitor traffic to and from the server IP address and filtered them with the word “ftp”. Here’s what I captured:
As you can see, not only are my username and password sent in plain text, they’re also clearly marked as such! If this was a hacker snooping on network transmissions, they would now be able to connect to my FTP server. If you read my previous article on setting up an FTP server, you’ll know that I created a user called “testftpuser”. And that is exactly what is displayed in the network traffic data.
Clearly this is a huge security risk. The notion of sending usernames and passwords in plaintext over the Internet is unthinkable in today’s day and age. Luckily for us, we have a few options to enable encryption with our FTP server so that we’re not exposed to such a glaring vulnerability. Pure-FTPd can utilize existing server certificates and keys to encrypt our traffic to and from the FTP client.
Reusing Existing Certificates and Keys
We can achieve FPT SSL/TLS security by providing Pure-FTPd with a certificate and key file combined into one. If you use the “HTTPS” protocol with your website, it means that you already have the necessary certificate for encrypting traffic. In an earlier tutorial, I’d shown you how to generate your own self signed certificates for HTTPS. If you follow that tutorial, you will now have the following in your server folder:
- A “.crt” file which is the certificate;
- A “.key” file that represents the key.
For use with FTP SSL or TLS, we need to combine these two files into a single “.pem” file. navigate to the directory containing these two files and type in the following command:
cat 126.96.36.199.crt 188.8.131.52.key > 184.108.40.206.pem
Here, replace the sections in bold with the actual names of your .crt and .key files. In this example, I’ve chosen to keep the names as my IP address. You can use whatever names you want as long as you can keep track of them! The above command will concatenate the two files into a single “.pem” file that is accepted by the Pure-FTPd configuration. Now we just need to move the newly created “.pem” file to the default location where Pure-FTPd looks for it. Type in:
mkdir /etc/ssl/private/ cp 220.127.116.11.pem /etc/ssl/private/pure-ftpd.pem
The first command creates the directory. The second transfers the newly created pem file into it. As before, replace the text in bold with the name of your own file.
Configuring Pure-FTPd with the Certificate Name
Now that we have the certificate in the right location, we have to inform Pure-FTPd about it and also enable TLS authentication. To do this, open the Pure-FTPd configuration file located at “/etc/pure-ftpd/pure-ftpd.conf”. You can open it with a text editor like this:
In this file, we need to make two changes. The first is to uncomment the line specifying the location of the certificate file like this:
Remove the “#” symbol at the beginning of the line to uncomment it. The second change is to enable TLS functionality by uncommenting the following line as well:
After removing the “#” symbols from both these lines, Pure-FTPd is configured to encrypt all FTP communications.
Opening the Necessary Ports
There’s one more thing we need to take care of. If you try and use Pure-FTPd “as is”, it might not work depending on your firewall. You might get an error that says:
Error listing directory '/'.
This is because FTP SSL or TLS changes the mode of FTP to something called “Passive Mode”. The details of this mode are not important. What’s important is that it no longer uses Port 21 which is the default for regular FTP communications. As a result if you have a firewall that doesn’t take this into consideration, the the FTP connection will fail with the above error.
To resolve this, we need to do two things. First, we enable a higher range of ports for passive FTP in the Pure-FTPd configuration file itself. Uncomment the following line:
#PassivePortRange 30000 50000
It’ll become like this:
By activating this line, you tell Pure-FTPd to use the port range of 30,000 to 50,000. The next step is to open up the same ports in your firewall. The method for this will depend on the kind of firewall you’re using. Personally I use csf, so that involves going into the csf configuration file and adding the range of ports to the TCP_IN and TCP_OUT lines. The csf configuration file is called “/etc/csf/csf.conf”. So the changes to the lines would look like this:
Notice that you can input IP ranges separated by the “:” character. So in this case, it’s 30000:50:000. As I mentioned earlier, this will depend on which firewall you’re using. Just make sure that the ports you open in the firewall are the same ports mentioned in the Pure-FTPd client under “PassivePortRange”.
Restarting Pure-FTPd and the Firewall
We’re almost done. After all the configuration changes, we need to restart both Pure-FTPd and the firewall for the changes to take effect. To restart Pure-FTPd, type in:
service pure-ftpd restart
And to restart csf, just type:
Or use whatever command for your particular firewall. Just make sure that the rule changes have taken effect, otherwise you may not be able to connect to FTP SSL.
Connecting from the Client
That completes our server side changes. It’s now ready to accept incoming FTP SSL/TLS connections. On the client side, you need to ensure that TLS is enabled. This will vary from client to client. For example, I use “WinSCP” and in that, I need to select the option called “TLS Explicit encryption” from the drop down box as shown here:
Now the connection proceeds as normal. If you have a self-signed certificate (like me), you’ll get a certificate warning that you can ignore:’
And here is the successful connection:
Checking if Encryption Works
Finally, let’s repeat the very first step and see if we can snoop the FTP username/password using Wireshark as we did at the beginning. Here’s the screenshot this time when I filter FTP traffic to that particular IP address:
As you can see, the data makes no sense now. That’s because it’s encrypted and no one will be able to see the username or the password, even if they have full access to the network packets. Congratulations! You have secured your FTP connection and rendered it invulnerable to hackers.