Protocol Deep Dives

RFC 959: FTP Protocol Deep Dive

Understanding the File Transfer Protocol — command/response model, active vs passive mode, ASCII vs binary transfer types, and why FTP is being replaced by SFTP and FTPS.

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:

ClassMeaningExample
1xxPositive Preliminary125 Data connection open; starting transfer
2xxPositive Completion226 Transfer complete
3xxPositive Intermediate331 Password required
4xxTransient Negative421 Service not available
5xxPermanent Negative530 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 TLS command. 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

FeatureFTPFTPSSFTPHTTPS
EncryptionNoneTLSSSHTLS
Firewall friendlyPoorPoorExcellentExcellent
AuthenticationPassword onlyPassword/CertKey/PasswordCert/Token
Resume supportYes (REST)YesYesPartial (Range)
Proxy friendlyNoNoYesYes
Modern browserNoNoNoNative

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.

โปรโตคอลที่เกี่ยวข้อง

เพิ่มเติมใน Protocol Deep Dives