FTP protocol discussion

FTP  typically uses two paths for normal operations.  This makes it particularly interesting when working or troubleshooting in NAT environments, Firewall environments, and any packet filtering schemes.

If we take for example a Telnet connection as a basis for a 'typical' tcp protocol (flame bait I know; each protcol is different, but telnet to me is the most basic to understand, and in my mind a good starting point - comments welcome).

The client initiates a connection on an ephemeral port (greater than 1023) to the servers telnet listening port 23. This is a TCP connection & goes through the SYN, SYNACK, ACK handshake, and then data starts passing. The packets on the wire look something like the following;

Source address:port               Dest address:port

client.i.p.addr:1025     server.i.p.addr:23 (SYN)
server.i.p.addr:23       client.i.p.addr:1025 (SYN ACK)
client.i.p.addr:1025     server.i.p.addr:23 (ACK)
server.i.p.addr:23       client.i.p.addr:1025 (ACK)(DATA - Username please:)
client.i.p.addr:1025     server.i.p.addr:23 (ACK)(DATA - user )
server.i.p.addr:23       client.i.p.addr:1025 (ACK)(DATA - user okay, send passwd)
client.i.p.addr:1025     server.i.p.addr:23 (ACK)(DATA - secret)
server.i.p.addr:23       client.i.p.addr:1025 (ACK)(DATA - Login okay, what next?)
client.i.p.addr:1025     server.i.p.addr:23 (ACK)(DATA - setting telnet options)
server.i.p.addr:23       client.i.p.addr:1025 (ACK)(DATA - reporting back set opts)
client.i.p.addr:1025     server.i.p.addr:23 (ACK)(DATA - do something )
server.i.p.addr:23       client.i.p.addr:1025 (ACK)(DATA - okay, I did it, what next) etc.

Note that each packet after the first one has the ACK bit set.  This is important to understanding how the Established keyword works in IOS access-lists.

FTP uses two distinct connections; Command connection & data connection. Commands flow on the command connection, and data flows on the data connection. You can do commands like 'cd' (change directory) or 'pwd' (print working directory ) without invoking the data connection. Commands such as 'dir' or 'get' or 'put' involve transfers of larger amounts of data, and will invoke the data connection.

This is all fairly straight forward so far.

But let's talk a little bit about when the connections get setup.

The FTP client initiates the command connection to the server. Then in just straight FTP, the server initiates the data connection back to the client. The client uses the PORT command to tell the server which port it's listening on for this particular data connection.

So, it goes like this (Pay close attention to the port numbers):

Source address:port             Dest address:port

client.i.p.addr:1025     server.i.p.addr:21 (SYN)
server.i.p.addr:21       client.i.p.addr:1025 (SYN ACK)
client.i.p.addr:1025     server.i.p.addr:21 (ACK)
server.i.p.addr:21       client.i.p.addr:1025 (ACK)(DATA: Login prompt)
client.i.p.addr:1025     server.i.p.addr:21 (ACK)(DATA: username)
server.i.p.addr:21       client.i.p.addr:1025 (ACK)(DATA: username OK; supply password please)
client.i.p.addr:1025     server.i.p.addr:21 (ACK)(DATA: password)
server.i.p.addr:21       client.i.p.addr:1025 (ACK)(DATA - username logged in)
client.i.p.addr:1025     server.i.p.addr:21 (ACK)(DATA - cd /drop )
server.i.p.addr:21       client.i.p.addr:1025 (ACK)(DATA - current direcory is /drop)
client.i.p.addr:1025     server.i.p.addr:21 (ACK)(DATA - PORT client.i.p.addr:1026) 
server.i.p.addr:21       client.i.p.addr:1025 (ACK)(DATA - Port successful)
client.i.p.addr:1025     server.i.p.addr:21 (ACK)(DATA - get this.file )
server.i.p.addr:20       client.i.p.addr:1026 (SYN)  (new connection, ACK not set yet)
client.i.p.addr:1026     server.i.p.addr:20 (SYN ACK)
server.i.p.addr:20       client.i.p.addr:1026 (ACK)
server.i.p.addr:20       client.i.p.addr:1026 (ACK)(DATA - File contents of this.file)
client.i.p.addr:1026     server.i.p.addr:20  (ACK of Data)
server.i.p.addr:21       client.i.p.addr:1025 (ACK)(DATA - Successful transfer closing data connection)

In older firewall systems (packet filters allowing outbound connections only - or ESTABLISHED connections on an IOS access-list) FTP flat out won't work for protected clients attempting to access a server outside the firewall. The data connections get denied immediately, as they are initiated from the outside server, and the ACK bit for the new connection doesn't get set.

SO, passive FTP is brought into the picture, to solve this problem.

In passive FTP, the client initiates BOTH connections to the server, and it looks like this:

Source address:port              Dest address:port

client.i.p.addr:1025     server.i.p.addr:21 (SYN)
server.i.p.addr:21       client.i.p.addr:1025 (SYN ACK)
client.i.p.addr:1025     server.i.p.addr:21 (ACK)
server.i.p.addr:21       client.i.p.addr:1025 (ACK)(DATA: Login prompt)
client.i.p.addr:1025     server.i.p.addr:21 (ACK)(DATA: username)
server.i.p.addr:21       client.i.p.addr:1025 (ACK)(DATA: username okay; supply password please)
client.i.p.addr:1025     server.i.p.addr:21 (ACK)(DATA: password)
server.i.p.addr:21       client.i.p.addr:1025 (ACK)(DATA - username logged in)
client.i.p.addr:1025     server.i.p.addr:21 (ACK)(DATA - cd /drop )
server.i.p.addr:21       client.i.p.addr:1025 (ACK)(DATA - current direcory is /drop)
****<no difference SO FAR-- but here comes something new>*****
client.i.p.addr:1025     server.i.p.addr:21 (ACK)(DATA - PASV command)
server.i.p.addr:21       client.i.p.addr:1025 (ACK)(DATA- Passive mode okay:server.i.p.addr:1490)
client.i.p.addr:1025     server.i.p.addr:21 (ACK)(DATA - get this.file )
client.i.p.addr:1026     server.i.p.addr:1490 (SYN)  -note new port number for new connect and no ACK bit set-
server.i.p.addr:1490     client.i.p.addr:1026 (SYN ACK)
client.i.p.addr:1026     server.i.p.addr:1490 (ACK)
server.i.p.addr:1490     client.i.p.addr:1026 (ACK)(DATA - File contents of this.file)
client.i.p.addr:1026     server.i.p.addr:1490 (ACK of Data)
server.i.p.addr:21       client.i.p.addr:1025 (ACK)(DATA - Successful transfer closing data connection)

The major difference between Standard & passive FTP is who sets up the data connection. Passive mode refers to the Servers state, in that the server is Passively accepting both connections. In standard mode, the server initiates the data connection, and is not 'passive' in that case.   In passive mode, both destination and source ports are 'ephemeral' ports (greater than 1023)

The modes are driven by the client, as in each case the client must issue either the passive command, or the port command, to initiate the setup of the data connection. In each case the recipient of the data connection (server for passive mode, client for standard mode) must supply the port number they are listening on for this specific connection. It is not ALWAYS port 20 for the data connection, even in standard mode FTP. Nothing in the RFC's specifies that the ports to be used are 20 & 21, it is just convention. Many servers will use ephemeral ports for the data connection.  The Cisco MicroWeb 100 is one example; it uses ports greater than 1024 for the source port of the data connection.

To restate the above:  The command connection is USUALLY on port 21, but can be on different ports if the client somehow knows to connect to a different port.  The non-passive mode data connection is USUALLY sourced from port 20 (command port -1) on the ftp server to the negotiated ephemeral port of the client, but not necessarily all the time.  The passive mode data conneciton is sourced from an ephemeral port on the ftp client to the negotiated ephemeral port on the ftp server.
 

FTP Protocol is discussed in RFC 959;
Host Requirements are discussed in RFC 1123;

Both of the above RFC's are relevant, and should be reviewed if you are investigating a problem in detail.

Some interesting notes from the RFC, and how various products are affected:

The FTP commands are not case sensitive. So PaSv & PASV & pasv, should all be accepted by the server.  IOS NAT (11.2.x),  only looks for uppercase commands, and will miss mixed case, or lowercase PORT & PASV commands; not many clients implement lower case commands, but it is legitimate to do so.   See   CSCdk21941 for additional details & fixed in versions.

Servers MUST support passive mode.   Both the PASV command, and the PORT command.  The Cisco MWEB 100 server is not compliant in this regard, passive FTP is not supported:  See CSCdj05025.  The LocalDirector, although it is not a SERVER technically, did not support Passive mode FTP until version 2.1 (CSCdj61333).  Centri Firewall is also affected by this issue, and does not permit Passive mode ftp (CSCdk43612  or CSCgi01933) but as Centri is End-Of-Life, this defect will never be resolved.

The data connection SHOULD be one port lower than the command, but it is not required. Early verisons of the PIX firewall (4.0.4) did not make allowances for this behavior, and subsequently, the data connection would fail (CSCdj20000).   The LocalDirector is affected by this issue, and  resolved these issues in version 2.1.3 (CSCdkj82574).   IOS NAT has a related bug (CSCdk36116) as well.

FTP Command connection is not required to be on port 21.  IOS NAT has this issued filed as CSCdj18423.  The PIX firewall has this issue listed as CSCdk17784.
 

Owner: lnapier@cisco.com
Last Modified: Thu, 5 Nov 1998 22:32:43