FTP’s control connection is a wide-open, unencrypted channel, making it vulnerable to eavesdropping and man-in-the-middle attacks, which is why FTPS exists.
Let’s see what happens when we try to transfer a file over plain FTP.
# On the client, initiate an FTP connection
ftp ftp.example.com
# ...
# Log in with username and password
user myuser
Password: mypassword
# ...
# Set binary transfer mode
binary
# ...
# Transfer a file
put localfile.txt
Now, let’s imagine we’re sniffing the network traffic. We’d see myuser and mypassword in plain text, along with the commands and the data itself. This is the core problem FTPS aims to solve.
FTPS adds encryption to the FTP protocol. There are two main flavors:
-
Implicit FTPS: This is the older, more straightforward approach. The client connects to a dedicated FTPS port (usually 990), and the SSL/TLS handshake happens before any FTP commands are sent. The entire session, including control and data, is encrypted.
- Client Configuration (e.g.,
lftp):lftp -u myuser,mypassword --ssl-implicit ftp://ftp.example.com:990 - Server Configuration: The FTP server needs to be configured to listen on port 990 for implicit SSL/TLS connections. For example, in
vsftpd, you might see directives related tossl_enableandlisten_port.
- Client Configuration (e.g.,
-
Explicit FTPS (FTPES): This is generally preferred as it’s more flexible. The client connects to the standard FTP control port (usually 21). It then sends a command (typically
AUTH TLSorAUTH SSL) to request encryption. If the server supports it, the SSL/TLS handshake occurs over the existing control connection, and then the data connection is also encrypted.- Client Configuration (e.g.,
lftp):lftp -u myuser,mypassword --ssl-protect-data ftp://ftp.example.com:21 - Server Configuration: The FTP server needs to be configured to enable SSL/TLS and allow
AUTH TLScommands. Invsftpd, this might involvessl_enable=YESandallow_anon_ssl=NO(for non-anonymous FTPS).
- Client Configuration (e.g.,
The port difference is key:
- FTP: Control on 21, Data on a dynamic port (often 20 for active mode, or a high port for passive mode).
- Implicit FTPS: Control and Data (after handshake) typically on 990.
- Explicit FTPS: Control on 21 (then handshake), Data on a dynamic port (encrypted).
When to use each:
- Use Plain FTP: Only for internal networks where security is not a concern, or for extremely high-volume, non-sensitive transfers where the overhead of encryption is prohibitive. This is rare and generally discouraged.
- Use Implicit FTPS: If you control both the client and server and want a simple, always-encrypted connection on a dedicated port. It’s less common nowadays due to firewall complexities with dynamic data ports.
- Use Explicit FTPS (FTPES): This is the modern standard for secure FTP. It’s compatible with standard FTP ports, making it easier for firewalls to manage, and it allows clients to negotiate encryption on demand. Use this for any scenario where you need to transfer files securely over FTP, such as uploading website assets to a hosting provider or transferring sensitive data between systems.
The surprising thing about FTPS is that it’s not SFTP. SFTP stands for SSH File Transfer Protocol, which is an entirely different protocol that runs over SSH (port 22). While both FTPS and SFTP provide encrypted file transfers, they are fundamentally different in their underlying protocols and how they achieve security. FTPS is an extension of the FTP protocol, while SFTP is a subsystem of SSH.
Here’s how an explicit FTPS session handshake might look conceptually:
- Client connects to server on port 21:
telnet ftp.example.com 21(or similar) - Server responds:
220 (vsFTPd 3.0.3) Welcome to Pure-FTPd [privsep] [TLS]... - Client sends
AUTH TLS:AUTH TLS - Server responds:
234 Proceed with negotiation - Client and Server perform SSL/TLS handshake. This involves exchanging certificates, agreeing on ciphers, and establishing a secure channel.
- Client sends
USER myuser:USER myuser - Server responds:
331 Please specify the password. - Client sends
PASS mypassword:PASS mypassword - Server responds:
230 Login successful. - Client sends
PBSZ 0:PBSZ 0(Request to set protection level to clear) - Server responds:
200 PBSZ 0 successful. - Client sends
PROT P:PROT P(Request to use plain data channel, but it will be encrypted by the TLS session) - Server responds:
200 PROT P successful. - Client sends
TYPE I:TYPE I(Binary mode) - Server responds:
200 Switching to Binary mode. - Client sends
PASV:PASV(Request passive mode) - Server responds with IP and port:
227 Entering Passive Mode (192,168,1,10,123,45) - Client connects to
192.168.1.10:12345for data transfer. This data connection is now encrypted because it’s part of the established TLS session. - Client sends
STOR mynewfile.txt:STOR mynewfile.txt - Server responds:
150 Ok to send data. - File is transferred.
- Server responds:
226 Transfer complete.
The AUTH TLS command is the signal that FTPS is about to happen. Without it, the connection remains plain FTP. The PROT P command, confusingly, means "use plain data channel," but in the context of an established TLS session, it signifies that the data should be protected by that session’s encryption, as opposed to PROT C which would mean cleartext data.
The most overlooked aspect of FTPS is its reliance on two distinct channels: a control channel and a data channel. While FTPS encrypts both, the way these channels are managed, especially in passive mode, can still lead to firewall issues if the server’s passive port range isn’t correctly opened on the firewall. This is a major reason why SFTP (which uses a single, predictable SSH port) is often easier to manage in complex network environments.
The next step after securing your FTP transfers is often understanding the differences and use cases for SFTP.