FTP Architecture — The Dual-Channel Design
The File Transfer Protocol (RFC 959, 1985) introduced a design that felt clever at the time but became a persistent operational headache: two separate TCP connections for a single file transfer.
FTP Dual-Channel Architecture:
Client Server
│ │
│── Control Connection ──────────│ port 21 (persistent)
│ USER, PASS, CWD, RETR │
│ reply codes, directory list │
│ │
│── Data Connection ────────────│ port 20 (Active)
│ file bytes, directory listing│ ephemeral port (Passive)
│ (opened per transfer) │
The control connection (port 21) carries commands and replies in plain text and remains open for the entire FTP session. Every time you list a directory or transfer a file, a *new* data connection is opened for the actual bytes and closed when the transfer completes.
This split made sense in 1971 when FTP was first designed (RFC 114) — it separated signaling from data, a pattern borrowed from telephony. But it means FTP negotiates new TCP connections constantly, each with its own 3-way handshake, and it creates profound firewall complications.
Command/Reply Model
Authentication Sequence
FTP sends credentials in cleartext over the control connection:
Client: USER alice
Server: 331 Password required for alice.
Client: PASS secret123
Server: 230 User alice logged in.
The 3-digit reply codes follow the same class structure as HTTP:
| Class | Meaning | Example |
|---|---|---|
| 1xx | Positive Preliminary | 125 Data connection open; starting transfer |
| 2xx | Positive Completion | 226 Transfer complete |
| 3xx | Positive Intermediate | 331 Password required |
| 4xx | Transient Negative | 421 Service not available |
| 5xx | Permanent Negative | 530 Not logged in |
Core Commands
Authentication:
USER <name> Send username
PASS <pass> Send password
QUIT End session
Navigation:
PWD Print working directory
CWD <path> Change working directory
CDUP Change to parent directory
Directory:
LIST [path] List directory contents (human-readable)
NLST [path] Name list (machine-parseable filenames only)
MKD <path> Make directory
RMD <path> Remove directory
File Transfer:
RETR <file> Retrieve (download) a file
STOR <file> Store (upload) a file
DELE <file> Delete a file
RNFR / RNTO Rename from / rename to
SIZE <file> Get file size in bytes
Data Channel:
PORT h1,h2,h3,h4,p1,p2 Active mode: client specifies data port
PASV Passive mode: server specifies data port
TYPE A / TYPE I Set transfer type (ASCII / binary)
A Full Download Session
Client → Server: USER anonymous
Server → Client: 331 Guest login OK, send email as password.
Client → Server: PASS [email protected]
Server → Client: 230 Guest login OK.
Client → Server: TYPE I
Server → Client: 200 Type set to I.
Client → Server: PASV
Server → Client: 227 Entering Passive Mode (192,0,2,1,19,136).
# Port = 19*256 + 136 = 5000
Client → Server: RETR /pub/rfc959.txt
# Client now connects to 192.0.2.1:5000 (data connection)
Server → Client: 150 Opening data connection.
# ...file bytes flow over data connection...
Server → Client: 226 Transfer complete.
Client → Server: QUIT
Server → Client: 221 Goodbye.
Active vs Passive Mode
This is the part of FTP that breaks in modern networks. The two modes differ in *who* initiates the data connection.
Active Mode (PORT)
In active mode, the client tells the server which port it is listening on:
Active Mode:
Client sends: PORT 10,20,30,40,5,0 (IP=10.20.30.40, port=1280)
Server opens a TCP connection FROM its port 20 TO client's port 1280
CLIENT (NAT) ROUTER/FIREWALL SERVER
192.168.1.5 ──────────────────────────→ 198.51.100.1:21 (control)
192.168.1.5:1280 ←─────────────────── 198.51.100.1:20 (data)
↑ INBOUND connection from server — blocked by NAT/firewall!
Active mode breaks whenever the client is behind NAT or a stateful firewall. The server tries to initiate an inbound TCP connection to the client's private IP address, which is unreachable from the internet. This is why active mode is rarely used today.
Passive Mode (PASV)
In passive mode, the server tells the client which port to connect to:
Passive Mode:
Client sends: PASV
Server replies: 227 Entering Passive Mode (198,51,100,1,19,136)
Client opens a TCP connection TO server's port 5000 (19*256+136)
CLIENT (NAT) ROUTER/FIREWALL SERVER
192.168.1.5 ──────────────────────────→ 198.51.100.1:21 (control)
192.168.1.5:ephemeral ─────────────→ 198.51.100.1:5000 (data)
↑ OUTBOUND connection from client — NAT handles it fine
Passive mode works through client-side NAT because *the client* initiates both connections. However, it requires the server's firewall to allow inbound connections on the ephemeral data port range (typically 49152–65535). FTP server configurations must specify a pasv_min_port / pasv_max_port range that matches the firewall rules.
EPSV (Extended Passive Mode) is the IPv6-compatible successor — it returns only a port number instead of embedding an IPv4 address in the reply:
Client: EPSV
Server: 229 Entering Extended Passive Mode (|||5000|)
Transfer Types
ASCII Mode (TYPE A)
ASCII mode was designed for transferring text files across systems with different line ending conventions. The FTP server converts between the local line ending and the NVT-ASCII standard (CRLF, \r\n) on the fly:
Unix server (LF \n) → FTP ASCII mode → Windows client (CRLF \r\n)
Windows server (CRLF) → FTP ASCII mode → Unix client (LF)
This causes silent file corruption when transferring binary files in ASCII mode. If a binary file contains the byte sequence 0x0A (which looks like LF), the server will insert 0x0D before it or strip the 0x0D from 0x0D 0x0A, corrupting the binary. Always use binary mode for non-text transfers.
Binary Mode (TYPE I — Image Mode)
Binary (image) mode transfers bytes verbatim with no translation:
# Ensure binary mode in command-line FTP:
ftp> binary
200 Type set to I.
ftp> get archive.tar.gz
The name "image mode" is a historical artifact — it meant the file image was transferred without modification. For everything except plain text files, use binary mode.
Structure and Record Mode (Unused)
RFC 959 also defines file structure (FILE, RECORD, PAGE) and transmission modes (STREAM, BLOCK, COMPRESSED). In practice, only FILE structure and STREAM mode are used — the rest were designed for mainframe record-oriented filesystems that no longer exist.
FTP's Legacy — SFTP, FTPS, and SCP
The Security Problem
FTP was designed in an era when the internet was a trusted academic network. Everything — username, password, commands, file contents — travels in cleartext. A passive network observer can capture everything with a single tcpdump:
# On the network, an attacker sees:
USER alice
PASS my_secret_password
RETR /confidential/salary_data.xlsx
# ...file contents follow in plaintext...
FTPS — FTP Over TLS (RFC 4217)
FTPS wraps FTP in TLS. It comes in two flavors:
- Explicit FTPS (STARTTLS): Connects on port 21, then upgrades with
AUTH TLScommand. The server advertises TLS support in its feature list. - Implicit FTPS: Connects directly to port 990 with TLS from the first byte. Deprecated but still common on legacy servers.
FTPS encrypts the control connection but still has all of FTP's firewall problems for the data connection. The PROT P command enables TLS on the data connection.
SFTP — SSH File Transfer Protocol
Despite the similar name, SFTP is not FTP over SSH — it is a completely different protocol (defined in the SSH protocol suite). SFTP operates over a single SSH channel (port 22), uses SSH authentication (keys, passwords), and has none of FTP's dual-channel firewall problems:
# SFTP client (OpenSSH)
sftp [email protected]
sftp> get /remote/file.txt ./local/
sftp> put ./local/upload.zip /remote/
# Non-interactive transfer:
scp [email protected]:/remote/file.txt ./local/
SFTP encrypts everything, uses a single firewall-friendly connection, supports SSH key authentication, and integrates with standard SSH infrastructure. For any new deployment, SFTP is the correct choice.
Why Modern Protocols Won
| Feature | FTP | FTPS | SFTP | HTTPS |
|---|---|---|---|---|
| Encryption | None | TLS | SSH | TLS |
| Firewall friendly | Poor | Poor | Excellent | Excellent |
| Authentication | Password only | Password/Cert | Key/Password | Cert/Token |
| Resume support | Yes (REST) | Yes | Yes | Partial (Range) |
| Proxy friendly | No | No | Yes | Yes |
| Modern browser | No | No | No | Native |
SFTP should be your default for file transfer. FTPS is acceptable when you need to maintain compatibility with a legacy system that already uses FTP and cannot switch. Plain FTP should never be used on a modern network.