FTP
Well-known ports already flagged FTP as the odd one out among TCP services: it's the only well-known protocol that opens a second TCP connection just to move the actual data. That single design decision, made in the early 1970s and formalized in RFC 959 in 1985, is responsible for nearly every modern complaint about FTP — and it's worth understanding properly rather than treating as a historical curiosity, because plenty of legacy systems, embedded devices, and internal file-distribution pipelines still run on it.
Two connections, not one
Every other application protocol covered so far in this course — HTTP included — does everything on a single TCP connection: commands and data share the same pipe. FTP splits the two apart deliberately:
- The control connection, opened to TCP port 21, carries commands and replies as plain text: logging in, changing directories, listing files, and telling the server what you're about to do. It stays open for the whole session.
- The data connection, a separate TCP connection, carries the actual bytes of whatever file is being listed, uploaded, or downloaded. It opens fresh for each transfer and closes when that transfer finishes.
That split made sense in 1971, when FTP was designed for a world of large batch transfers between a handful of trusted university and government machines, and separating control chatter from bulk data was a sensible way to keep a slow terminal link responsive while a large file moved in the background. It causes real trouble on a modern network built around firewalls and NAT, which is the whole story of the next section.
PORT and PASV: two different ways to open the data connection
Someone has to initiate that second TCP connection, and FTP gives two answers to who.
Active mode, the original design, has the server open the data connection back to the client. The client sends a PORT command telling the server which of its own local ports to connect to — an ordinary ephemeral port on the client side, picked and reported by the client itself, with no fixed number attached to it. The server then initiates that outbound connection from its own port 20, which is why "port 20" shows up in the well-known-ports table in the first place: 20 is the server's data-connection source port, not the client's.
This is precisely backwards from how every other client-server protocol works, and precisely what firewalls and home routers refuse to allow by default: a connection originating from the internet toward an internal client looks, from the firewall's point of view, indistinguishable from an attacker probing an open port. Active mode largely stopped working the day stateful firewalls became the norm rather than the exception.
Passive mode fixes this by having the client initiate both connections. The client sends PASV, and the server replies with an address and port of its own to connect to:
That reply packs an IP address and a port into six decimal numbers: the first four are the address 198.51.100.10, and the last two combine as (200 × 256) + 13 = 51213 — the port the server opened and is waiting on. The client then opens an ordinary outbound connection to 198.51.100.10:51213, exactly the direction firewalls expect. Virtually every FTP client defaults to passive mode today for this reason, and encountering active mode in production is now the exception rather than the rule.
The command channel in practice
FTP commands and replies are both plain ASCII text, one line at a time — readable in a packet capture without any decoding. A typical session, after the TCP handshake on port 21, looks like this:
220 Welcome to ProFTPD Server
USER alice
331 Password required for alice
PASS ********
230 User alice logged in
PWD
257 "/home/alice" is the current directory
TYPE I
200 Type set to I
PASV
227 Entering Passive Mode (198,51,100,10,200,13)
RETR report.pdf
150 Opening BINARY mode data connection for report.pdf
226 Transfer complete
QUIT
221 Goodbye
Replies follow the same three-digit convention already seen in SMTP and POP3: the first digit says whether the command succeeded (2yy), needs more input (3yy), or failed (4yy/5yy). TYPE I deserves a specific note — it switches the transfer mode to binary (I for "Image"), as opposed to the default TYPE A (ASCII), which silently rewrites line endings between systems and corrupts anything that isn't plain text. Forgetting to set binary mode before transferring an executable, an image, or a zip archive is a real, recurring mistake, and it produces a file that's subtly wrong rather than an obvious error.
Encrypting FTP: FTPS is not SFTP
Plain FTP sends the username and password from USER/PASS in cleartext over the control connection, and the file contents in cleartext over the data connection. Anyone positioned to observe the traffic — a shared Wi-Fi network, a compromised router, an ISP — reads both without any effort.
Plain FTP exposes credentials and data to anyone on the path
Don't use unencrypted FTP to move anything sensitive, and don't reuse an FTP password anywhere else — it has effectively been broadcast the first time it was used over cleartext FTP on a network you don't fully control. If a system still requires plain FTP, treat it as compromised the moment it's used outside a fully trusted, isolated network.
Two unrelated fixes exist, and mixing them up is common enough to call out directly:
- FTPS (FTP over TLS, specified in RFC 4217) is FTP with the same two-connection design, wrapped in TLS. The client sends
AUTH TLSon the control connection to negotiate encryption before authenticating, and separately negotiatesPROT Pto encrypt the data connection too — both channels need protecting independently, since encrypting one and not the other still leaks either the credentials or the file contents. - SFTP (SSH File Transfer Protocol) isn't FTP at all. It's a completely different protocol that runs entirely inside a single SSH connection — the same protocol and the same port 22 covered in well-known ports — and shares nothing with FTP's command set or its two-connection model beyond the superficial similarity of moving files remotely.
The similarity of the names causes real confusion in practice: a server administrator told to "open FTPS" sometimes opens port 990 (FTPS's implicit-TLS port) when the actual requirement was SFTP over the SSH port that's probably already open. Checking which one an application actually asks for, before touching a firewall, saves a wasted change.
Practical scenario: uploads hang right after listing succeeds
A backup script connects to an FTP server, logs in, and lists the remote directory without any trouble — then hangs indefinitely the moment it tries to upload a file, until it eventually times out. The login worked, so credentials and basic connectivity to port 21 are fine, which points investigation away from the obvious suspects.
A packet capture on the client, filtered to the FTP session, shows the PASV command going out and the 227 reply coming back with an address and a high port number — say 51213. But no SYN packet ever leaves the client for that address and port. The client parsed the passive-mode reply correctly; it simply never got to open the connection.
That silence is the finding. The outbound connection attempt to the high port the server nominated is being blocked before it leaves the network — most often by a corporate egress firewall that only permits outbound traffic on a short allow-list of ports (80, 443, and a handful of others), with no exception carved out for FTP's dynamically chosen passive-mode range. Because that range is different on every connection, there's no single port to add to the firewall; a real fix means either a dedicated passive-port range configured on the FTP server and explicitly opened end to end, or moving the whole workflow off FTP onto something that doesn't need a second, unpredictable connection at all — which is exactly the appeal of protocols like SFTP or plain HTTPS uploads.
Common mistakes
- Assuming "PASV" means "no firewall problem." Passive mode fixes the direction of the second connection, not the fact that a second, unpredictable port still has to be reachable.
- Transferring binary files in ASCII mode.
TYPE Arewrites line endings; anything that isn't plain text comes out corrupted, often in a way that isn't obvious until the file is opened. - Treating FTPS and SFTP as interchangeable. They share a similar name and nothing else — different transport, different port, different protocol entirely.
Practice exercises
- Using a test FTP server (many public ones exist for exactly this purpose) and
curl -v ftp://, capture a real227passive-mode reply and decode the port number by hand from its six decimal fields. - Explain why active-mode FTP is fundamentally at odds with how a stateful firewall is expected to behave, in terms of which side initiates the data connection.
- A colleague asks whether enabling "FTPS" on a server also secures anyone still connecting over plain FTP on port 21. Answer it, and explain what has to be disabled to actually force encryption.
FTP moves files. The next three protocols in this module move something arguably more central to how the internet is actually used day to day — mail — and the first of them, SMTP, inherits the same plain-text, line-based command style seen above, applied to a completely different problem: getting a message from one mail server to another.