FTPS servers can secure client connections using SSL/TLS certificates, but often the configuration details are more intricate than they appear.

Let’s see how it works. Imagine a client wants to upload a file to an FTPS server.

# Client initiates connection to ftps.example.com on port 21
$ openssl s_client -connect ftps.example.com:21 -starttls ftp

The server, ftps.example.com, will then present its SSL/TLS certificate.

CONNECTED(00000003)
--- certificate verification ---
...
---
Certificate chain
 0 s:/CN=ftps.example.com/OU=IT/O=Example Corp/C=US
   i:/C=US/ST=California/L=San Francisco/O=Example Intermediate CA/CN=Example Root CA
...
---

This certificate tells the client who the server is and allows the client to encrypt subsequent communication.

The core problem FTPS solves is encrypting the entire FTP session, not just data transfers. Unlike plain FTP where credentials and commands are sent in cleartext, FTPS wraps everything in a TLS tunnel. This is crucial for compliance and security in regulated industries.

Internally, FTPS operates in two modes: Implicit and Explicit.

  • Implicit FTPS: The client connects directly to a dedicated FTPS port (often 990) and immediately initiates the TLS handshake. No prior AUTH TLS command is needed.
  • Explicit FTPS: The client connects to the standard FTP port (21) and then issues an AUTH TLS command to upgrade the connection to a secure one. This is more common.

The server’s configuration dictates which mode it supports and how it handles certificates. A typical configuration in vsftpd might look like this:

# /etc/vsftpd.conf
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
rsa_cert_file=/etc/ssl/certs/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.key
ssl_ciphers=HIGH

Here’s what each setting does:

  • ssl_enable=YES: Turns on SSL/TLS support in vsftpd.
  • allow_anon_ssl=NO: Prevents anonymous users from using SSL/TLS (though anonymous FTP is generally discouraged).
  • force_local_data_ssl=YES: Mandates that data connections (for file transfers) must be encrypted.
  • force_local_logins_ssl=YES: Mandates that login commands must be encrypted.
  • ssl_tlsv1=YES, ssl_sslv2=NO, ssl_sslv3=NO: Specifies the TLS/SSL protocols to allow. TLSv1.2 and TLSv1.3 are generally preferred and should be explicitly enabled if your vsftpd version supports them (e.g., ssl_tlsv1_2=YES, ssl_tlsv1_3=YES). Disabling older, vulnerable protocols like SSLv2 and SSLv3 is critical.
  • rsa_cert_file=/etc/ssl/certs/vsftpd.pem: Points to the server’s SSL certificate file. This file often contains both the public certificate and the private key, concatenated.
  • rsa_private_key_file=/etc/ssl/private/vsftpd.key: (Optional, if not in rsa_cert_file) Specifies the private key file.
  • ssl_ciphers=HIGH: Configures the cipher suites that the server will offer. HIGH typically means strong encryption algorithms.

The most surprising true thing about FTPS certificates is that the rsa_cert_file often needs to contain both the server’s public certificate and its private key, concatenated into a single .pem file. The server uses the public part to present to clients for verification and the private part to decrypt traffic. If these are separate, vsftpd might complain, even if the paths are correct.

For example, if you have server.crt and server.key, you’d typically combine them:

cat server.crt server.key > vsftpd.pem

Then, ensure the permissions on vsftpd.pem are restrictive (e.g., 600 or 400) and that the vsftpd user can read it. The private key should never be world-readable.

The next hurdle you’ll likely face is correctly configuring passive mode FTP over TLS, which involves managing a range of ephemeral ports.

Want structured learning?

Take the full Ftp course →