Summary

  • FTP negotiated commands on a control connection and carried file contents on a separate data connection.
  • RFC 1579 used the existing PASV command to reverse who opened that data connection, making client-side packet filters easier to cross while moving the inbound-port problem to the server.

FTP could say “send this file” on a connection that never carried the file itself. That separation was built into its design. It also meant that a login and a successful RETR command did not guarantee the bytes could get through: a second TCP connection still had to be established in the direction FTP selected.

The 1985 FTP specification, RFC 959, described a control process for commands and replies and data processes for transfers. In the common arrangement, the client opened the control connection to the server, typically on port 21. Before a transfer, it could send PORT with its own address and a port at which it would listen. The server then initiated the data connection back to the client. The data socket was separate from the command socket, so a firewall that admitted the first connection did not automatically admit the second.

FTP already had another arrangement. With PASV, the client asked the server’s data process to listen on a non-default port. The server returned the address and port, and the client opened the data connection to it. The file still travelled over a second connection; the caller changed. Passive mode was therefore present in the protocol years before it became a recommended workaround for packet filters.

By 1994, the practical pattern did not always match the original default. Steven Bellovin’s RFC 1579 says contemporary clients commonly opened a new data connection for each transfer, chose a new client port to avoid TCP’s TIME-WAIT delay, and announced it with PORT. A packet filter could see that as an incoming call to an unpredictable port. Firewalls often permitted selected inbound services while rejecting such calls, even when the user had already authenticated on the control connection.

RFC 1579 recommended that vendors change FTP clients, including Gopher proxy agents, to use PASV instead of PORT. The client’s data connection would then be an outgoing call. In the logic of a client-side firewall, outgoing initiation was easier to permit than an unsolicited inbound connection to a random client port. The memo did not propose a new wire protocol: the command already existed, and the client and server exchanged a similar setup command before each transfer either way.

The change moved the difficult boundary rather than removing it. A server in passive mode had to accept incoming data calls on ports selected for transfers. RFC 1579 acknowledged that its answer could create a firewall problem on the server side. Its case was administrative: there were fewer servers than clients, and an operator could constrain the server’s data-port range. That was a proposal about where to manage exposure, not proof that every server or firewall had adopted it.

The standards record helps separate a required capability from actual behavior. RFC 1123, published in 1989, required FTP servers to implement PASV and clarified how its reply should be interpreted, while noting that reply formatting was not fully standardized. RFC 1579 later said at least two independent modified clients existed. Neither statement measures how many users or sites changed modes. The 1994 memo records a recommendation and limited implementations, not a universal migration.

That distinction matters because FTP had two operational surfaces. The control connection could carry credentials, commands and success replies; the data connection carried a listing or file. A control-channel reply such as “opening data connection” was not the file, and a successful login was not evidence that the transfer completed. Troubleshooting had to follow both sockets and identify which endpoint was meant to initiate each one.

The lesson in RFC 1579 is narrower than “firewalls broke FTP.” FTP had already included a choice of data-connection direction. Filtering made that choice consequential. PASV let a client put the initiating call on the side where its firewall policy was more likely to allow it, while asking the server operator to manage a bounded set of inbound ports. The protocol remained the same; the location of the operational burden shifted.

Sources