📅 February 9, 2018
FTP is insecure because all commands, usernames, password, and data transfers in the clear. Anybody sniffing the network can easily peek into an FTP session.
Let’s thwart that attempt by encrypting our FTP server with an SSL/TLS certificate that we generate ourselves.
SFTP and FTPS: What’s the Difference?
There are two ways to encrypt an FTP session: SFTP (Secure File Transfer Protocol) and FTPS (FTP with SSL/TLS). Both encrypt, but they do so in different ways. Where the ‘S‘ is located in FTP makes a big difference in how we configure ProFTP.
This is FTP using SSH port 22. Just think of it as a secure shell connection. No certificate generation is necessary. If you have an SSH server running, then you can connect. With an FTP client, you will be limited to FTP transactions. However, everything is encrypted just as it would be with an SSH login.
This technique requires generating an SSL/TLS certificate that the user must accept upon login before the connection is allowed. This does not use port 22 unless you configure ProFTP to use that port. The FTP session is encrypted just like an HTTPS session using SSL (Secure Sockets Layer) / TLS (Transport Layer Security).
Which Method is Better?
As far as encryption goes, both work well. There is no need to be concerned that one technique is inferior to the other. The bigger issue is FTP client compatibility. When using SSL/TLS certificates with FTPS, FTP clients that lack SSL support will not connect. The default command-line ftp program will not work with FTPS. Filezilla does support FTPS (as well as SFTP), so we will be using this client to test the SSL connection.
We are going to use FTPS for practice with SSL certificates. It never hurts to learn a new Linux skill.
Certificates are created using the program openssl, so make sure that openssl is installed on your system.
sudo apt install openssl
We will generate a certificate for each FTP virtual host, so we need a place to store them. Create a directory that will hold all certificates and keys.
sudo mkdir /etc/proftpd/ssl
We can place the keys anywhere, but it is best to locate them in a root-level directory to help prevent access by casual users. By using a dedicated directory in /etc/proftpd we can see immediately that these keys must be used for proftpd.
Generating the Certificates
Let’s start with the zippy virtual host. We will use openssl to generate a certificate and a key (two separate files). the certificate follows the X.509 public key standard (the same used for HTTPS). Be root to perform this action so the certificate and key can be stored in /etc/proftpd/ssl.
sudo openssl req -new -x509 -days 300 -nodes -out /etc/proftpd/ssl/zippy.cert -keyout /etc/proftpd/ssl/zippy.key
This generates two ASCII armored text files. A virtual host needs both:
- zippy.cert – The X.509 certificate
- zippy.key – The 2048-bit RSA private key file
The other options, such as -days 300, set an expiration date for the certificate. After 300 days, you must generate another.
Let’s do the same for the bumble virtual host. We could use the same key for both servers, but this is better security. If one certificate/key is compromised, its certificate cannot be used to gain access to the other server.
sudo openssl req -new -x509 -days 300 -nodes -out /etc/proftpd/ssl/bumble.cert -keyout /etc/proftpd/ssl/bumble.key
Enter whatever information you like for your FTP virtual host. Again, this generates two files:
- bumble.cert – The X.509 certificate
- bumble.key – The 2048-bit RSA private key file
Change the Permissions
For added security, set the permissions so only root may read and write the certificates and keyfiles (proftpd also requires this for the certificate file).
sudo chmod 600 /etc/proftpd/ssl/*
The result should look like this:
Sidenote: The Certificate and Key
Have you ever wondered what a certificate looks like?
Go ahead and open the certificate and key files in a text editor to see what they look like. They are simply text files containing binary data encoded using Base64, so they can be opened in any text editor. Use sudo to open them. Do not edit either file.
These files are shown here for example purposes, so they are useless. However, keep your certificate and keyfile private.
Now that we have the certificates and keyfiles, we need to tell proftpd to use them. Open proftpd.conf for editing.
sudo xed /etc/proftpd/proftpd.conf
Inside the Global block, add these three lines to the existing file:
Include /etc/proftpd/tls.conf TLSEngine on TLSRequired on
This enables SSL/TLS encryption and requires that it be used for control and data communication. All logins will encrypt the passwords in addition to encrypting all data transfers.
Include /etc/proftpd/tls.conf tells proftpd to add this configuration file to the existing proftpd.conf configuration for extra TLS-related settings.
The Global context should now look like this:
# ----------------------------------------------------------------------------- # GLOBALS # ----------------------------------------------------------------------------- <Global> Include /etc/proftpd/tls.conf TLSEngine on TLSRequired on DisplayLogin welcome.msg DisplayChdir .message DenyFilter \*.*/,"%" ListOptions "-l" DefaultRoot ~ RequireValidShell on MultilineRFC2228 on ShowSymlinks on TimeoutNoTransfer 600 TimeoutStalled 600 TimeoutIdle 1200 Umask 022 022 AllowOverwrite on TransferLog /var/log/proftpd/xferlog IdentLookups off MaxClients 30 DeferWelcome on </Global>
Open tls.conf for editing.
sudo xed /etc/proftpd/tls.conf
Find the the following two lines, and comment them out if they exist. Arguments might appear after the directives. They are irrelevant.
These directives tell proftpd which certificate and keyfile to use the FTP server. We will specify them separately for each virtual host. Save and close tls.conf.
With proftpd.conf still open for editing, add these two lines to Zippy’s virtual host block:
TLSRSACertificateFile /etc/proftpd/ssl/zippy.cert TLSRSACertificateKeyFile /etc/proftpd/ssl/zippy.key
Make sure to use absolute paths to the certificate and keyfile to avoid any ambiguity. Wherever you placed the files on your system is the path you must use to each.
Zippy’s VirtualHost block should look like this:
# ============================================================================= # Zippy's FTP # ============================================================================= <VirtualHost 192.168.1.30> ServerName "Zippy's FTP" Port 21 DefaultServer on TransferLog /var/log/proftpd/zippy_xfer.log TLSRSACertificateFile /etc/proftpd/ssl/zippy.cert TLSRSACertificateKeyFile /etc/proftpd/ssl/zippy.key DisplayLogin welcome.msg <Anonymous /media/ftpdata/zippyftp> User zippy Group zippy AnonRequirePassword off UserAlias anonymous zippy <Limit LOGIN> AllowAll </Limit> HideUser root HideGroup root </Anonymous> </VirtualHost>
All anonymous logins to Zippy will be encrypted using an X.509 certificate.
Do the same for the bumble virtual host, but specify the path to bumble.cert and bumble.key.
TLSRSACertificateFile /etc/proftpd/ssl/bumble.cert TLSRSACertificateKeyFile /etc/proftpd/ssl/bumble.key
Bumble’s VirtualHost block should look like this by now:
# ============================================================================= # Bumble's FTP # ============================================================================= <VirtualHost 192.168.1.30> ServerName "Bumble's FTP" Port 4000 TransferLog /var/log/proftpd/bumble_xfer.log TLSRSACertificateFile /etc/proftpd/ssl/zippy.cert TLSRSACertificateKeyFile /etc/proftpd/ssl/zippy.key DisplayLogin welcome.msg <Anonymous /media/ftpdata/bumbleftp> User bumble Group bumble AnonRe quirePassword off UserAlias anonymous bumble <Limit LOGIN> AllowAll </Limit> HideUser root HideGroup root </Anonymous> </VirtualHost>
Note: There is an intentional goofup in Bumble’s VirtualHost block above. It involves certificates. Can you spot it? We will catch it later.
sudo service proftpd restart
If there are no errors in the configuration files (proftpd.conf and tls.conf), the FTP server should run with both virtual hosts active.
Open Filezilla (if open, close it and reopen because Filezilla sometimes caches an FTP session). Start by testing Zippy. Enter its IP address without any port (default is port 21). We should see something different this time.
Do you trust this certificate?
Normally, a trusted third-party certificate authority would generate a certificate for our FTP site, but since we made our own for zippy, we see a dialog regarding an “Unknown certificate.” This is why Subject of certificate (remember the certificate questionnaire when the certificate was generated?) and Certificate issuer match each other.
Do we trust it? Yes, of course, we do. Click OK.
Also notice that the Filezilla status text changes to “Initializing TLS…” and “Verifying Certificate…” This is normal. The certificate must be accepted in order to protect a user’s login credentials.
Zippy works, so log out. Now, let’s try to connect to bumble’s virtual host. Since bumble’s server is listening on port 4000, we must enter 4000 in Filezilla’s port field.
Oops! It turns out that copying and pasting directives from Zippy’s virtual block to Bumble’s virtual block resulted in the same certificate for both. Let’s change that by specifying the paths to bumble’s certificate and keyfile.
Even though proftpd started without errors, it did not catch this mistake. It demonstrates that we can use the same certificate and keyfile for more than one virtual host. Save the changes and restart proftpd.
sudo service proftpd restart
Now, try logging into Bumble again.
Nemo File Manager
Not all FTP clients support FTPS. This is discovered mostly through trial and error. Or virtual hosts are configured to require a TLS connection, so if a client does not support it, then no connection is allowed.
Nemo (the default file manager in Linux Mint Cinnamon), for example, supports both SFTP and FTPS.
To connect using Nemo, enter ftps://192.168.1.30 (for zippy) or ftps://192.168.1.30:4000 (for bumble) in the location entry bar. You will be presented with a certificate confirmation.
Notice that Nemo requires ftps not ftp when specifying the protocol in its location bar.
As of now, we have ProFTP running two TLS-encrypted virtual hosts that accept anonymous logins without passwords. TLS is required or else no connection is allowed. More virtual hosts can be added at different ports, and there is a wealth of options to explore that will allow you to fine-tune ProFTP to your needs.
By now you are probably wondering, “If we allow anonymous logins, then why bother encrypting the FTP session at all?”
Two reasons: for practice and to protect regular logins. Even though the two virtual hosts constructed allow password-less anonymous logins, they also allow regular, non-anonymous users to log in. These user accounts do require real usernames and passwords, which could cause trouble if sniffed, so they must be protected. SSL/TLS certificates provide that protection.
Of course, ProFTP allows you to limit user logins too, but this enters the realm of custom configuration for you to explore.