RFC 4217

Securing FTP with TLS

๐Ÿ“… published October 2005, from ietf

Securing FTP with TLS โœจ

Okay bestie, let's start with the basics ๐ŸŽ€. This is RFC 4217, titled Securing FTP with TLS, by P. Ford-Hutchinson of IBM UK Ltd. It was published by the Network Working Group in October 2005 ๐Ÿ“… and it's on the Standards Track ๐Ÿ‘‘. The header doesn't have any Obsoletes or Updates lines, so there's nothing to flag there ๐Ÿ’….


Status of This Memo ๐Ÿ“œ

This document is an Internet standards track protocol for the Internet community ๐ŸŒ. It's asking for discussion and suggestions for improvements, so bring your ideas ๐Ÿ’–. If you want to know where this protocol stands in standardization, check the current edition of "Internet Official Protocol Standards" (STD 1) ๐Ÿ”. Distribution of this memo is unlimited ๐Ÿฆ‹.

Copyright (C) The Internet Society (2005) ๐ŸŒธ.

Abstract ๐Ÿงš

Okay so this doc explains how FTP clients and servers can use TLS to get security and authentication ๐Ÿ”. The TLS part comes from RFC 2246, "The TLS Protocol Version 1.0.", and the FTP extensions come from RFC 2228, "FTP Security Extensions" ๐Ÿ’œ. It covers the subset of those extensions that are required, the parameters to use, and the policy stuff clients and servers have to think about ๐ŸŽ€. It also looks at what those policies imply and describes some expected implementation behaviours so everyone can interoperate ๐Ÿซถ.

The goal is to give FTP TLS support the same kind of treatment that SMTP got in RFC 2487, "SMTP Service Extension for Secure SMTP over Transport Layer Security", and HTTP got in RFC 2817, "Upgrading to TLS Within HTTP/1.1." ๐Ÿฆ‹ It's giving consistency ๐Ÿ’….

This specification follows RFC 959, "File Transfer Protocol" โœจ. It relies on RFC 2246, "The TLS Protocol Version 1.0.", and RFC 2228, "FTP Security Extensions" ๐Ÿ‘‘.

Table of Contents ๐Ÿ“š

   1. Introduction ....................................................3
   2. Audience ........................................................5
   3. Overview ........................................................5
   4. Session Negotiation on the Control Port .........................5
      4.1. Client Wants a Secured Session .............................5
      4.2. Server Wants a Secured Session .............................6
   5. Clearing the Control Port .......................................6
   6. Response to the FEAT Command ....................................7
   7. Data Connection Behaviour .......................................8
   8. Mechanisms for the AUTH Command .................................9
   9. Data Connection Security ........................................9
   10. A Discussion of Negotiation Behaviour .........................11
      10.1. The Server's View of the Control Connection ..............11
      10.2. The Server's View of the Data Connection .................12
      10.3. The Client's View of the Control Connection ..............14
      10.4. The Client's View of the Data Connection .................15
   11. Who Negotiates What, Where, and How ...........................15
      11.1. Do we protect at all? ....................................15
      11.2. What level of protection do we use on the Control
            connection? ..............................................15
      11.3. Do we protect data connections in general? ...............16
      11.4. Is protection required for a particular data transfer? ...16
      11.5. What level of protection is required for a
            particular data ..........................................16
   12. Timing Diagrams ...............................................16
      12.1. Establishing a Protected Session .........................17
      12.2. Establishing a Protected Session Without a
            Password Request .........................................18
      12.3. Establishing a Protected Session and then
            Clearing with the CCC ....................................19
      12.4. A Standard Data Transfer Without Protection ..............20
      12.5. A Firewall-Friendly Data Transfer Without Protection .....20
      12.6. A Standard Data Transfer with Protection .................21
      12.7. A Firewall-Friendly Data Transfer with Protection ........21
   13. Discussion of the REIN Command ................................22
   14. Discussion of the STAT and ABOR Commands ......................22
   15. Security Considerations .......................................23
      15.1. Verification of Authentication Tokens ....................23
           15.1.1. Server Certificates ...............................23
           15.1.2. Client Certificates ...............................23
      15.2. Addressing FTP Security Considerations [RFC-2577] ........24
           15.2.1. Bounce Attack .....................................24
           15.2.2. Restricting Access ................................24
           15.2.3. Protecting Passwords ..............................24
           15.2.4. Privacy ...........................................24
           15.2.5. Protecting Usernames ..............................24
           15.2.6. Port Stealing .....................................25
           15.2.7. Software-Based Security Problems ..................25
      15.3. Issues with the CCC Command ..............................25
   16. IANA Considerations ...........................................25
   17. Other Parameters ..............................................25
   18. Scalability and Limits ........................................26
   19. Applicability .................................................26
   20. Acknowledgements ..............................................26
   21. References ....................................................26
      21.1. Normative References .....................................26
      21.2. Informative References ...................................27

1. Introduction ๐Ÿ’–

This document shows how three other documents fit together to make a useful, interoperable, and secure file transfer protocol ๐Ÿงฉ. Those three are:

  • RFC 959 [RFC-959] ๐Ÿ“ The description of the Internet File Transfer Protocol.
  • RFC 2246 [RFC-2246] ๐Ÿ” The description of the Transport Layer Security protocol (developed from the Netscape Secure Sockets Layer (SSL) protocol version 3.0).
  • RFC 2228 [RFC-2228] ๐Ÿ›ก๏ธ Extensions to the FTP protocol to allow negotiation of security mechanisms to allow authentication, confidentiality, and message integrity.

This document is meant to bring TLS support to FTP in a similar way to how SMTP got it in RFC 3207 [RFC-3207] and HTTP got it in RFC 2817 [RFC-2817] ๐ŸŒˆ.

The security extensions to FTP in [RFC-2228] come with a big, comprehensive set of commands and responses. They can add authentication, integrity, and confidentiality to FTP ๐Ÿ˜ญ. TLS is hugely popular (mostly because everyone adopted it wholesale in the HTTP world) as a general way to secure a socket connection ๐Ÿ”ฅ.

TLS isn't the only option for securing file transfer, but it has some seriously good perks ๐Ÿ‘‘:

  • Flexible security levels. TLS can support confidentiality, integrity, authentication, or some combination of all of these. During a session, clients and servers can dynamically decide what level of security a particular data transfer needs ๐ŸŽ€.
  • Ability to provide strong authentication of the FTP server ๐Ÿ’ช.
  • It is possible to use TLS identities to authenticate client users and client hosts ๐Ÿชช.
  • Formalised public key management. By using well established client identity mechanisms (supported by TLS) during the authentication phase, certificate management may be built into a central function. Whilst this may not be desirable for all uses of secured file transfer, it offers advantages in certain structured environments ๐Ÿข.
  • Co-existence and interoperation with authentication mechanisms that are already in place for the HTTPS protocol. This lets web browsers add secure file transfer using the same infrastructure that's already set up for secure web browsing ๐ŸŒธ.

TLS is a development of Netscape Communication Corporation's SSL protocol, and this document lets FTP work with either SSL or TLS ๐Ÿฆ‹. The protocol actually used gets decided during negotiation of the protected session at the TLS/SSL layer โœจ. This document only refers to the TLS protocol, but it's understood that the Client and Server MAY actually be using SSL if they're configured that way ๐Ÿซถ.

There are lots of ways these three protocols can be combined ๐Ÿงš. This document picks one method that lets FTP operate securely while still providing flexibility and interoperation ๐Ÿ’…. That means it needs a short description of the actual negotiation mechanism, a detailed description of the required policies and practices, and a discussion of the expected behaviours of clients and servers so either party can impose its security requirements on the FTP session ๐Ÿ”ฅ.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" and "OPTIONAL" that appear in this document are to be interpreted as described in [RFC-2119] ๐Ÿ“–โœจ.

2. Audience ๐ŸŽ€

This document is for developers who want to implement TLS as a security mechanism to secure FTP clients and/or servers ๐Ÿ’ป.

Systems administrators and architects should be fully aware of the security implications discussed in [RFC-2228]. Those need to be considered when choosing an implementation of this protocol and configuring it to provide the security they require ๐Ÿ›ก๏ธ.

3. Overview ๐Ÿฆ‹

The full description of the FTP security protocol enhancements lives in [RFC-2228] ๐Ÿ“š. This document describes how the AUTH, PROT, PBSZ, and CCC commands, which are defined there, should be implemented with the TLS protocol ๐ŸŒˆ.

Here's the summary ๐Ÿ“. An FTP session starts on the normal control port. A client asks for TLS with the AUTH command, and then decides whether it wants to secure the data connections using the PBSZ and PROT commands ๐Ÿ”. If a client wants the control connection to go back to plaintext (for example, once the authentication phase is done), it can use the CCC command ๐Ÿซง.

Implementing this protocol extension doesn't guarantee that every session and data transfer is secure ๐Ÿ˜ฌ. It just gives clients and/or servers the tools to negotiate an acceptable or required level of security for a given session or data transfer ๐Ÿ’œ. That said, a server implementation can be built to refuse to operate in an insecure fashion ๐Ÿ”’.

4. Session Negotiation on the Control Port ๐Ÿง 

The server listens on the normal FTP control port {FTP-PORT}, and the session initiation isn't secured at all ๐Ÿ™ˆ. Once the client wants to secure the session, it sends the AUTH command, and then the server MAY allow TLS negotiation to take place โœจ.

4.1. Client Wants a Secured Session ๐Ÿ”

If a client wants to try securing a session, then it SHOULD, in accordance with [RFC-2228], send the AUTH command with the parameter requesting TLS {TLS-PARM} ('TLS') ๐Ÿ’–.

The client then has to behave according to its policies, depending on the response it gets from the server and on the result of the TLS negotiation ๐ŸŽ€. A client that receives an AUTH rejection MAY choose to carry on with the session unprotected if it wants to ๐Ÿฅบ.

4.2. Server Wants a Secured Session ๐ŸŒธ

okay so FTP doesn't let a server straight up boss the client around ๐Ÿ™…โ€โ™€๏ธ, but the server can get the same effect by refusing certain FTP commands until the session is secured to a level it likes ๐Ÿ’…. honestly iconic.

Either way, 234 is the server's reply to an AUTH TLS command that it's gonna honour ๐Ÿซถ.

The 334 reply from [RFC-2228] basically says an ADAT exchange is coming next ๐Ÿ™ˆ. This doc doesn't use the ADAT command, though, so 334 is the wrong reply here ๐Ÿ’€.

FTP is very insistent that a USER command gets used to say who's trying to use the ftp server ๐Ÿงš. Even if TLS is already giving auth info, the client MUST still send the USER command ๐Ÿ’…. Still, it's totally up to the server implementation to decide which credentials to accept and what consistency checks to run between the client cert and the parameter on the USER command ๐Ÿง.

[RFC-2228] says the user must reauthorize (that is, reissue some or all of the USER, PASS, and ACCT commands) following an AUTH command ๐Ÿ”„. This doc adds that all the other transfer parameters (everything except the AUTH parameter) must be reset, almost like a REIN command just happened ๐Ÿ’–.

   Reset transfer parameters after the AUTH command, including (but
   are not limited to): user identity, default data ports, TYPE,
   STRU, MODE, and current working directory.

5. Clearing the Control Port ๐Ÿฆ‹

sometimes you only want the control connection protected for part of the session and then you want to go back to plaintext ๐Ÿ™ƒ. this is usually because boundary devices like NAT and firewalls need to be able to read the control connection so they can change how they behave ๐Ÿงฑ.

Typically the AUTH, USER, PASS, PBSZ, and PROT commands would be protected inside TLS, and then the CCC command gets sent to go back to a plaintext socket state ๐Ÿ”“. This has important Security Issues (which are discussed in the Security Considerations section) โš ๏ธ, but this document explains how the command should be used, if the client and server still want to use it after thinking through the issues ๐Ÿง .

When a server gets the CCC command, it should behave like this ๐Ÿ‘‘:

  • If the server does not accept CCC commands (or does not understand them), then a 500 reply should be sent.
  • Otherwise, if the control connection is not protected with TLS, then a 533 reply should be sent.
  • Otherwise, if the server does not wish to allow the control connection to be cleared at this time, then a 534 reply should be sent.
  • Otherwise, the server is accepting the CCC command and should do the following:
    • Send a 200 reply.
    • Shutdown the TLS session on the socket and leave it open.
    • Continue the control connection in plaintext, expecting the next command from the client to be in plaintext.
    • Not accept any more PBSZ or PROT commands. All subsequent data transfers must be protected with the current PROT settings.

6. Response to the FEAT Command ๐ŸŽ€

The FEAT command (introduced in [RFC-2389]) lets servers with extra features tell the client about them when they reply to FEAT ๐Ÿ“ฃ. If a server supports the FEAT command, it MUST advertise supported AUTH, PBSZ, and PROT commands in the reply, as described in section 3.2 of [RFC-2389] ๐Ÿ’…. The AUTH command should also have a reply that names TLS as one of its possible parameters. You don't need to list the TLS-C synonym separately ๐Ÿ™…โ€โ™€๏ธ.

Example reply (in the same style as [RFC-2389]):

   C> FEAT
   S> 211-Extensions supported
   S>  AUTH TLS
   S>  PBSZ
   S>  PROT
   S> 211 END

7. Data Connection Behaviour ๐Ÿงš

The Data Connection in the FTP model can be used in one of three ways ๐ŸŒˆ. (Note: these descriptions aren't necessarily in exact chronological order, but they do cover the steps required. See the diagrams later for clarification ๐Ÿ“.)

  • i) Classic FTP client/server data exchange
    • The client obtains a port, sends the port number to the server, and the server connects to the client ๐Ÿ“ฒ.
    • The client issues a send or receive request to the server on the control connection, and the data transfer starts on the data connection โœจ.
  • ii) Firewall-Friendly client/server data exchange (as discussed in [RFC-1579]) using the PASV command to reverse the direction of the data connection ๐Ÿ”
    • The client requests that the server open a port. The server obtains a port and returns the address and port number to the client, and the client connects to the server on this port ๐Ÿšช.
    • The client issues a send or receive request on the control connection, and the data transfer starts on the data connection ๐Ÿ’ซ.
  • iii) Client-initiated server/server data exchange (proxy or PASV connections) ๐Ÿค
    • The client requests that server A opens a port. Server A obtains a port and returns it to the client, and the client sends this port number to server B ๐Ÿ“จ.
    • Server B connects to server A. The client sends a send or receive request to server A and the complement to server B, and the data transfer starts ๐Ÿš€.
    • In this model, server A is the proxy or PASV host and is a client for the Data Connection to server B ๐Ÿฆ‹.

For i) and ii), the FTP client MUST be the TLS client and the FTP server MUST be the TLS server ๐Ÿ”.

That is to say, it doesn't matter which side starts the connection with a connect() call or which side reacts to it via the accept() call. The FTP client, as defined in [RFC-959], is always the TLS client, as defined in [RFC-2246] ๐Ÿ’œ.

In scenario iii), there's a problem: neither server A nor server B is the TLS client, and an FTP server has to act as a TLS server for Firewall-Friendly FTP [RFC-1579] ๐Ÿ˜ญ. So this is explicitly excluded in the security extensions document [RFC-2228] and in this document ๐Ÿ™…โ€โ™€๏ธ.


8. Mechanisms for the AUTH Command ๐Ÿ”‘

The AUTH command takes a single parameter that defines the security mechanism to negotiate ๐ŸŽฏ. Since the SSL/TLS protocols negotiate their own levels, there's no need to tell SSL and TLS apart at the application layer ๐Ÿ™Œ. The mechanism name for negotiating TLS is the character string identified in {TLS-PARM} ๐Ÿท๏ธ. This lets the client and server negotiate TLS on the control connection without changing how the data channel is protected. To protect the data channel too, the PBSZ command, followed by the PROT command sequence, MUST be used ๐Ÿ›ก๏ธ.

Note: the data connection state MAY be modified by the client issuing the PROT command with the new desired level of data channel protection, and the server replying in the affirmative ๐ŸŒธ. This data channel protection negotiation can happen at any point in the session (even straight after a PORT or PASV command) and as often as needed ๐Ÿ’….

See also Section 16, "IANA Considerations" ๐Ÿ“š.


9. Data Connection Security ๐Ÿ”

The Data Connection security level is decided by the PROT command ๐Ÿ’–.

The PROT command, as specified in [RFC-2228], lets the client and server negotiate the security level of the data connection ๐Ÿค. Once the client has issued a PROT command and the server has accepted it with a '200' reply, the security of later data connections MUST be at that level until another PROT command is issued and accepted. That holds until the session ends and a REIN command is issued, or until the session's security is renegotiated via an AUTH command ๐Ÿ”„.

Data Connection Security Negotiation (the PROT command) ๐ŸŽ€

Note: in line with [RFC-2228], there's no way to secure the Data connection when the Control connection is insecure ๐Ÿ™…โ€โ™€๏ธ. Specifically, the PROT command MUST be preceded by a PBSZ command, and a PBSZ command MUST be preceded by a successful security data exchange (the TLS negotiation in this case) ๐Ÿ”—.

The command [RFC-2228] defines for negotiating data connection security is the PROT command ๐Ÿ“œ. As defined, the PROT command parameter can take four values:

'C' - Clear - neither Integrity nor Privacy

'S' - Safe - Integrity without Privacy

'E' - Confidential - Privacy without Integrity

'P' - Private - Integrity and Privacy

Since TLS negotiation covers (and goes beyond) the Safe / Confidential / Private distinction, only Private (use TLS) and Clear (don't use TLS) are used ๐Ÿ™Œ.

For TLS, the data connection can have one of two security levels:

  • 1) Clear (requested by PROT C) ๐Ÿ”“
  • 2) Private (requested by PROT P) ๐Ÿ”

With the 'Clear' protection level, the data connection is made without TLS. So it's unauthenticated and has no confidentiality or integrity ๐Ÿ˜ฌ. This might be what you want for servers sending file lists, pre-encrypted data, or non-sensitive data (for example, anonymous FTP servers) ๐Ÿ“.

If the data connection security level is 'Private', then a TLS negotiation must take place on the data connection to the satisfaction of the Client and Server before any data is sent over the connection ๐Ÿค. The TLS layers of the Client and Server handle negotiating the exact TLS Cipher Suites that will be used (and so the eventual security of the connection) ๐Ÿง .

On top of that, the PBSZ (protection buffer size) command, as detailed in [RFC-2228], is compulsory before any PROT command ๐Ÿ“. This document also defines a data channel encapsulation mechanism for protected data buffers. For FTP-TLS, which looks to the FTP application like a streaming protection mechanism, this isn't required ๐ŸŒŠ. So the PBSZ command MUST still be issued, but it must have a parameter of '0' to say that no buffering is happening and the data connection should not be encapsulated ๐Ÿ’….

Note that PBSZ 0 isn't in the grammar of [RFC-2228], section 8.1, which says:

PBSZ <sp> <decimal-integer> <CRLF>

<decimal-integer> ::= any decimal integer from 1 to (2^32)-1

That said, using a value of '0' to mean a streaming protocol is a reasonable use of '0' for that parameter, and it isn't ambiguous ๐Ÿซถ.

Initial Data Connection Security ๐ŸŒธ

The initial state of the data connection MUST be 'Clear' (this is the behaviour indicated by [RFC-2228]) ๐Ÿ”“.


10. A Discussion of Negotiation Behaviour ๐Ÿ’ญ

[RFC-2228] lets security qualities be negotiated, enabled, and disabled dynamically, and honestly that can make implementations feel super complex ๐Ÿ˜ตโ€๐Ÿ’ซ. But in any given instance, the behaviour should be pretty straightforward โœจ. Either the server is enforcing the policy of the server host, or it's providing security capabilities the client asked for ๐Ÿ . And either the client is conforming to the server's policy, or it's trying its best to provide the capabilities the user wants ๐ŸŽ€.

10.1. The Server's View of the Control Connection โœจ

Okay bestie, the server gets a whole policy wishlist ๐Ÿ“ A server MAY have a policy statement somewhere that might:

  • Deny any command before TLS is negotiated (this might cause problems if a SITE or some such command is required prior to login) ๐Ÿ™ˆ
  • Deny certain commands before TLS is negotiated (e.g., USER, PASS, or ACCT)
  • Deny insecure USER commands for certain users (e.g., not ftp/anonymous)
  • Deny secure USER commands for certain users (e.g., ftp/anonymous)
  • Define the level(s) of TLS to be allowed
  • Define the CipherSuites allowed to be used (perhaps on a per host/domain/... basis)
  • Allow TLS authentication as a substitute for local authentication
  • Define data connection policies (see next section)

TLS negotiation doesn't always go perfectly for the server either, so it can end up in one of these states ๐Ÿ’€

  • The TLS negotiation failed completely. The control connection should still be in an unprotected mode, and the server SHOULD issue an unprotected '421' reply to end the session.
  • The TLS negotiation completed successfully, but the server decides that the session parameters are not acceptable (e.g., the Distinguished Name in the client certificate is not permitted to use the server). The control connection should still be in a protected state, so the server MAY either continue to refuse to service commands or issue a protected '421' reply and close the connection.
  • The TLS negotiation failed during the TLS handshake. The control connection is in an unknown state, so the server SHOULD simply drop the control connection.

The server code is in charge of enforcing all of this ๐Ÿ‘‘ It has to actually refuse any command that goes against policy, otherwise the client could just walk around the chosen security. No sneaking past the bouncer!


10.2. The Server's View of the Data Connection

The server can take one of four basic views of the data connection. ๐ŸŽ€

  1. Don't allow encryption at all (in which case the PROT command should not allow any value other than 'C', if it is allowed at all).
  2. Allow the client to choose protection or not.
  3. Insist on data protection (in which case the PROT command must be issued prior to the first attempted data transfer).
  4. Decide on one of the above three for each and every data connection.

The server SHOULD only check the data protection level (for options 3 and 4 above) on the actual command that starts the data transfer, not on the PORT or PASV. These commands, defined in [RFC-959], open data connections, so they can get rejected before any 1xx message if the PROT setting is wrong:

STOR
RETR
NLST
LIST
STOU
APPE

The reply for a wrong PROT setting is 521 data connection cannot be opened with this PROT setting ๐Ÿ™…โ€โ™€๏ธ

If the protection level says TLS is required, then it should be negotiated once the data connection is made. So the 150 reply only tells you the command is allowed at the current PROT level ๐Ÿฆ‹ If the server doesn't like the TLS negotiation, it closes the data port right away and follows the 150 command with a 522 reply, which means the TLS negotiation failed or was unacceptable.

(Note: This means the application can pass a standard list of CipherSuites to the TLS layer for negotiation, and then check which one was negotiated for each instance.) ๐Ÿ’…

The Security Considerations section covers cross-checking any certificates used to authenticate the data connection against the ones used for the control connection. This is an important security step, so please don't skip it ๐Ÿ”ฅ

It's reasonable for the server to insist that the data connection uses a TLS cached session. That could be a cache from a previous data connection or from a cleared control connection. If that's why the data transfer was refused, the 522 reply should say so ๐ŸŒธ

Note: This has a big impact on client design, but it lets servers save cycles during TLS negotiation by refusing to do a full negotiation with a client they've already authenticated โญ

It should be noted that the TLS authentication of the server is authentication of the server host itself, not a user on the server host ๐Ÿงš


10.3. The Client's View of the Control Connection

In most cases the client will be using TLS, because the server would refuse to interact insecurely ๐Ÿซถ To allow for this, clients SHOULD be flexible enough to manage securing a session at the right time, and still let the user/server policies decide exactly when during the session the security gets negotiated.

If the client is the one insisting on securing the session, the client needs to make sure all the negotiations complete satisfactorily. It also needs to be able to clearly tell the user if the server doesn't support the required security levels, or isn't prepared to use them ๐Ÿ’–

Clients SHOULD be coded so the timing of the AUTH, PBSZ, and PROT commands is flexible and set by the server. It's totally reasonable for a server to refuse certain commands before these ones. It's also quite possible that a SITE or quoted command might be needed by a server before the AUTH. A client MUST let a user override the timing of these commands to suit a specific server โœจ

For example, a client SHOULD NOT insist on sending the AUTH as the first command in a session, and it shouldn't insist on issuing a PBSZ/PROT pair right after the AUTH either. That can be the default behaviour, but a user must be able to override it ๐Ÿ™Œ

TLS negotiation might not finish satisfactorily for the client, so it can end up in one of these states ๐Ÿ˜ญ

  • The TLS negotiation failed completely. The control connection should still be in an unprotected mode, and the client should issue an unprotected QUIT command to end the session.
  • The TLS negotiation completed successfully, but the client decides that the session parameters are not acceptable (e.g., the Distinguished Name in the certificate is not the actual server the client expected). The control connection should still be up in a protected state, so the client should issue a protected QUIT command to end the session.
  • The TLS negotiation failed during the TLS handshake. The control connection is in an unknown state, so the client should simply drop the control connection.

10.4. The Client's View of the Data Connection

Client security policies ๐ŸŒˆ

Clients don't really have "policies" as such. They rely on the user to decide what to do, and they mostly react to the server's policy. So a client needs commands that let the user switch the protection level of the data connection on the fly ๐Ÿ’œ There might also be a general "policy" that tries all LIST and NLST commands on a Clear connection first, and automatically switches to Private if that fails. In that case there would need to be a user command that makes sure a given data transfer is never attempted on an insecure data connection ๐Ÿ”’

Clients also need to get that the PROT setting is only checked for a particular data transfer after that transfer has been requested ๐Ÿ‘€ So if the server refuses one specific transfer, the client shouldn't read that as the server refusing that protection level completely. Other transfers may be fine at that level, and the same transfer might even get accepted at the same level later in the session ๐Ÿฆ‹

It should be noted that the TLS authentication of the client should be an authentication of a user on the client host, not the client host itself ๐ŸŽ€


11. Who Negotiates What, Where, and How ๐Ÿ—บ๏ธ

11.1. Do we protect at all?

Client issues 'AUTH TLS', and the server accepts or rejects it. If the server needs AUTH, it refuses to accept certain commands until it gets a successfully protected session ๐Ÿ”

11.2. What level of protection do we use on the Control connection?

Decided entirely by the TLS CipherSuite negotiation ๐Ÿ’…

11.3. Do we protect data connections in general?

Client issues PROT command, and the server accepts or rejects it โœจ

11.4. Is protection required for a particular data transfer?

A client would have already issued a PROT command if it needed the connection to be protected ๐Ÿซถ

If a server needs the connection protected, it replies to the STOR/RETR/NLST/... command with a 522. That tells the client the current data connection protection level isn't enough for that transfer right now ๐Ÿ™ˆ

11.5. What level of protection is required for a particular data transfer?

Decided entirely by the TLS CipherSuite negotiation ๐ŸŒธ

So for flexibility, it's really useful for the FTP application to be able to talk to the TLS layer underneath it. That way it can define and discover the exact TLS CipherSuites that are to be (or have been) negotiated, and make decisions based on them ๐Ÿง 


12. Timing Diagrams โฑ๏ธ

These timing diagrams are here to explain how the TLS handshake and session protection fit into the existing logic of the FTP protocol ๐Ÿฆ‹ The FTP protocol itself isn't described very clearly when it comes to the timing of commands and responses in [RFC-959], so this part is partly based on what people actually observed in widespread client and server implementations ๐ŸŒˆ

12.1. Establishing a Protected Session ๐ŸŽ€

okay so this is the full handshake, bestie ๐Ÿ’– the client does its socket()/connect() thing, the server does accept(), and then the whole vibe kicks off with a 220 welcome. Then the client says AUTH TLS, the server says 234, and they do the TLS negotiation dance together ๐Ÿค

              Client                                 Server
     control          data                   data               control
   ====================================================================

                                                                socket()
                                                                bind()
     socket()
     connect()  ----------------------------------------------> accept()
               <----------------------------------------------  220
     AUTH TLS   ---------------------------------------------->
               <----------------------------------------------  234
     TLSneg()  <----------------------------------------------> TLSneg()
     PBSZ 0     ---------------------------------------------->
               <----------------------------------------------  200
     PROT P     ---------------------------------------------->
               <----------------------------------------------  200
     USER fred  ---------------------------------------------->
               <----------------------------------------------  331
     PASS pass  ---------------------------------------------->
               <----------------------------------------------  230

Note 1: The order of the PBSZ/PROT pair and the USER/PASS pair (with respect to each other) is not important (i.e., the USER/PASS can happen prior to the PBSZ/PROT, or the server can refuse to allow a PBSZ/PROT pair until the USER/PASS pair has happened).

Note 2: The PASS command might not be required at all (if the USER parameter and any client identity presented provide sufficient authentication). The server would indicate this by issuing a '232' reply to the USER command instead of the '331', which requests a PASS from the client (see below).

Note 3: The AUTH command might not be the first command after the receipt of the 220 welcome message.

12.2. Establishing a Protected Session Without a Password Request (The TLS Authentication is Sufficient) ๐ŸŒธ

same opening moves as before, but this time the TLS auth is doing all the heavy lifting ๐Ÿ’ช so the server just goes 232 instead of asking for a password. no PASS needed, iconic โœจ

              Client                                 Server
     control          data                   data               control
   ====================================================================

                                                                socket()
                                                                bind()
     socket()
     connect()  ----------------------------------------------> accept()
               <----------------------------------------------  220
     AUTH TLS   ---------------------------------------------->
               <----------------------------------------------  234
     TLSneg()  <----------------------------------------------> TLSneg()
     PBSZ 0     ---------------------------------------------->
               <----------------------------------------------  200
     PROT P     ---------------------------------------------->
               <----------------------------------------------  200
     USER fred  ---------------------------------------------->
               <----------------------------------------------  232

12.3. Establishing a Protected Session and then Clearing with the CCC Command ๐Ÿฆ‹

so here the session gets set up all protected, and then the client sends CCC to drop the TLS wrapper on the control connection. the rest of the chat keeps going in plaintext but the data transfers stay protected, which is giving very specific main character energy ๐Ÿงš

             Client                                 Server
    control          data                   data               control
  ====================================================================

                                                               socket()
                                                               bind()
    socket()
    connect()  ----------------------------------------------> accept()
              <----------------------------------------------  220
    AUTH TLS   ---------------------------------------------->
              <----------------------------------------------  234
    TLSneg()  <----------------------------------------------> TLSneg()
    PBSZ 0     ---------------------------------------------->
              <----------------------------------------------  200
    PROT P     ---------------------------------------------->
              <----------------------------------------------  200
    USER fred  ---------------------------------------------->
              <----------------------------------------------  232
    CCC        ---------------------------------------------->
              <----------------------------------------------  200
    TLSshutdown()  <-------------------------------------> TLSshutdown()
  • The rest of the control session continues in plaintext with protected data transfers (due to PROT P).
Note: This has serious security issues (see Security Considerations section) but may be useful in a firewall/NAT scenario. ๐Ÿšจ bestie, be careful with this one, it's not the vibe for everyday use ๐Ÿ™ˆ

12.4. A Standard Data Transfer Without Protection ๐Ÿ“ฆ

this is the classic PORT-then-STOR move, with no protection at all. the client shares its address with PORT, the server sends the file over a fresh connection, and everybody closes up nicely at the end ๐ŸŒˆ

              Client                                 Server
     control          data                   data               control
   ====================================================================

                      socket()
                      bind()
     PORT w,x,y,z,a,b ----------------------------------------->
         <----------------------------------------------------- 200
     STOR file ------------------------------------------------>
                                             socket()
                                             bind()
         <----------------------------------------------------- 150
                      accept() <-----------  connect()
                      write()   -----------> read()
                      close()   -----------> close()
         <----------------------------------------------------- 226

12.5. A Firewall-Friendly Data Transfer Without Protection ๐Ÿงฑ

same unprotected transfer, but this time the server opens the listening port with PASV so the firewall doesn't cry about it ๐Ÿ˜ญ the client does the connecting instead of the server.

              Client                                 Server
     control          data                   data               control
   ====================================================================

     PASV -------------------------------------------------------->
                                             socket()
                                             bind()
         <------------------------------------------ 227 (w,x,y,z,a,b)
                      socket()
     STOR file --------------------------------------------------->
                      connect()  ----------> accept()
         <-------------------------------------------------------- 150
                      write()    ----------> read()
                      close()    ----------> close()
         <-------------------------------------------------------- 226

Note: Implementers should be aware that the connect()/accept() function is performed prior to the receipt of the reply from the STOR command. This contrasts with the situation when a non-firewall-friendly PORT is used prior to the STOR, and the accept()/connect() is performed after the reply from the aforementioned STOR has been dealt with. ๐Ÿ‘€ the ordering flip is the whole plot twist, so keep it in mind!

12.6. A Standard Data Transfer with Protection ๐Ÿ”

now we're adding the protection layer on the data side ๐Ÿ›ก๏ธ the TLS handshake happens on the data connection after the connect/accept, then the file goes over TLSwrite and TLSread, and everyone shuts down cleanly. slay ๐Ÿ’…

              Client                                 Server
     control          data                   data               control
   ====================================================================

                      socket()
                      bind()
     PORT w,x,y,z,a,b -------------------------------------------->
         <-------------------------------------------------------- 200
     STOR file --------------------------------------------------->
                                             socket()
                                             bind()
         <-------------------------------------------------------- 150
                      accept()  <----------  connect()
                      TLSneg()  <----------> TLSneg()
                      TLSwrite() ----------> TLSread()
                      TLSshutdown() -------> TLSshutdown()
                      close()    ----------> close()
         <-------------------------------------------------------- 226

12.7. A Firewall-Friendly Data Transfer with Protection ๐Ÿงšโ€โ™€๏ธ

the firewall-friendly version of the protected transfer ๐Ÿฆ‹ PASV first, then the client connects to the server's data port, and the TLS negotiation happens on the data connection once it's up.

              Client                                 Server
     control          data                   data               control
   ====================================================================

     PASV -------------------------------------------------------->
                                             socket()
                                             bind()
         <------------------------------------------ 227 (w,x,y,z,a,b)
                      socket()
     STOR file --------------------------------------------------->
                      connect()  ----------> accept()
         <-------------------------------------------------------- 150
                      TLSneg()   <---------> TLSneg()
                      TLSwrite()  ---------> TLSread()
                      TLSshutdown() -------> TLSshutdown()
                      close()     ---------> close()
         <-------------------------------------------------------- 226

13. Discussion of the REIN Command ๐Ÿงน

okay so REIN is the reset button ๐Ÿ”„ the RFC-959 people describe it like this:

REINITIALIZE (REIN) This command terminates a USER, flushing all I/O and account information, except to allow any transfer in progress to be completed. All parameters are reset to the default settings and the control connection is left open. This is identical to the state in which a user finds himself immediately after the control connection is opened. A USER command may be expected to follow.

so when the server gets REIN, the TLS session(s) MUST be cleared and the control and data connections go back to being unprotected, clear communications ๐Ÿซง it MAY be acceptable to reuse cached TLS sessions for later connections, but a server MUST NOT mandate that. hard pass on forcing it ๐Ÿ™…โ€โ™€๏ธ

and if REIN is being used to clear a TLS session, then the reply to REIN MUST be sent in a protected session before the session(s) get cleared. so the server gets to say bye properly first ๐Ÿฅน

14. Discussion of the STAT and ABOR Commands ๐Ÿฆ‹

The ABOR and STAT commands and the use of TCP Urgent Pointers

okay this one is a little throwback ๐Ÿ“ผ RFC-959 says ABOR and STAT are sent with Telnet commands (IP and DM) and the TCP Urgent pointer, so you can send a command while a data transfer is running. FTP uses the Telnet Interrupt Process and Data Mark commands together with Urgent data to preface the two commands: ABOR (Abort Transfer) and STAT (Status request).

why Urgent? on a Unix box, a TCP packet marked Urgent would trigger the SIGURG interrupt handler ๐Ÿง  that reliance on interrupt handlers was needed on systems that didn't have select() or didn't support multiple threads. but TLS doesn't support the notion of Urgent data, so it's a whole different game now ๐ŸŽฎ

when TLS is the security method in FTP, the server SHOULD NOT rely on SIGURG to process input on the control channel during data transfers. and the client MUST send all data, including Telnet commands, across the TLS session. no sneaking stuff in around it ๐Ÿ™…โ€โ™€๏ธ๐Ÿ”’

15. Security Considerations ๐Ÿ”

bestie, this one is SERIOUS ๐Ÿšจ this doc talks about using TLS together with [RFC-2228] to secure FTP sessions. the deep security rationale and properties live in [RFC-2228], so go read that one too, we're not repeating it here ๐Ÿ“š

15.1. Verification of Authentication Tokens ๐Ÿชช

in this section we assume X.509 certificates are used for the TLS authentication. if some other identity token is used (e.g., kerberos tickets - see [RFC-2712]), then similar, mechanism-specific considerations will need to be made. so if you're swapping in a different token, you've gotta think through its own security stuff too, no shortcuts ๐Ÿ’€

15.1.1. Server Certificates

okay so server certs are a whole vibe ๐Ÿ”โœจ these are the rules bestie needs to know:

  • Although it is entirely an implementation decision, it is recommended that certificates used for server authentication of the TLS session contain the server identification information in a similar manner to those used for http servers (see [RFC-2818]).
  • It is strongly recommended that the certificate used for server authentication of Data connections be the same certificate as that used for the corresponding Control connection. If different certificates are to be used, there should be some other mechanism that the client can use to cross-check the data and control connection server identities. ๐Ÿซถ
  • If Server Certificates are not used, then many of the security benefits will not be realised. For Example, in an anonymous Diffie-Hellman environment, there is no server identity authentication, so there is little protection against man-in-the-middle attacks. ๐Ÿ’€ that's giving "nobody checked who's on the other end," and it's not it ๐Ÿ™ˆ

15.1.2. Client Certificates

the client side is giving the same energy ๐Ÿ’…

  • Deciding which client certificates to allow and defining which fields define what authentication information is entirely a server implementation issue. ๐ŸŽ€
  • However, it is strongly recommended that the certificate used for client authentication of Data connections be the same certificate as that used for the corresponding Control connection. If different certificates are to be used, there should be some other mechanism that the server can use to cross-check the data and control connection client identities. ๐ŸŒธ
  • If Client Certificates are not used, then many of the security benefits will not be realised. For Example, it would still be possible for a malicious client to hijack a data connection. ๐Ÿ˜ญ

15.2. Addressing FTP Security Considerations [RFC-2577]

this section is basically the old FTP drama getting a glow-up ๐Ÿฆ‹

15.2.1. Bounce Attack

a bounce attack should be harder in a secured FTP environment because:

  • The FTP server that is being used to initiate a false connection will always be a 'server' in the TLS context. Therefore, only services that act as 'clients' in the TLS context could be vulnerable. This would be a counter-intuitive way to implement TLS on a service. ๐Ÿ™ƒ
  • The FTP server would detect that the authentication credentials for the data connection are not the same as those for the control connection, thus the server policies could be set to drop the data connection. ๐Ÿšซ
  • Genuine users are less likely to initiate such attacks when the authentication is strong, and malicious users are less likely to gain access to the FTP server if the authentication is not easily subverted (password guessing, network tracing, etc...) ๐Ÿ•ต๏ธโ€โ™€๏ธ

15.2.2. Restricting Access

this document presents a strong mechanism for solving the issue raised in this section ๐Ÿ‘‘

15.2.3. Protecting Passwords

the twin solutions of strong authentication and data confidentiality ensure that this is not an issue when TLS is used to protect the control session ๐Ÿ”’๐Ÿ’–

15.2.4. Privacy

the TLS protocol ensures data confidentiality by encryption. Privacy (e.g., access to download logs, user profile information, etc...) is outside the scope of this document (and [RFC-2577] presumably). ๐Ÿงš

15.2.5. Protecting Usernames

this is not an issue when TLS is used as the primary authentication mechanism ๐ŸŒˆ

15.2.6. Port Stealing

this specification will do little for the Denial of Service element of this section ๐Ÿ˜ฌ however, strong authentication on the data connection will prevent unauthorised connections from retrieving or submitting files. Of course, this is only the case where strong client authentication is being used. If client certificates are not used, then port stealing by a rogue client is still a problem. If no strong authentication is in use at all (e.g., anonymous Diffie-Hellman), then the port stealing problem will remain. ๐Ÿšจ

warning bestie: strong auth is the only thing standing between a rogue client and your files. No client certs, and port stealing is still on the table ๐Ÿšจ

15.2.7. Software-Based Security Problems

nothing in this specification will affect the discussion in this section ๐Ÿ“

15.3. Issues with the CCC Command

using the CCC command can create security issues ๐Ÿ‘€ for the full tea, read the "CLEAR COMMAND CHANNEL (CCC)" section of [RFC-2228]. Clients should not assume that a server will allow the CCC command to be processed.

server implementations may wish to refuse to process the CCC command on a session that has not passed through some form of client authentication (e.g., TLS client auth or FTP USER/PASS). This can prevent anonymous clients from repeatedly requesting AUTH TLS followed by CCC to tie up resources on the server. ๐Ÿ›ก๏ธ๐Ÿ’œ

16. IANA Considerations โœจ

{FTP-PORT} - The port assigned to the FTP control connection is 21.

17. Other Parameters ๐ŸŽ€

{TLS-PARM} - The parameter for the AUTH command to indicate that TLS
is required.  To request the TLS protocol in accordance with this
document, the client MUST use 'TLS'

   To maintain backward compatibility with older versions of this
   document, the server SHOULD accept 'TLS-C' as a synonym for 'TLS'.

   Note: [RFC-2228] states that these parameters are case-
   insensitive.

the client MUST use 'TLS' ๐Ÿ”ฅ and the server SHOULD accept 'TLS-C' as a synonym for backwards compat ๐Ÿซถ also [RFC-2228] says these params are case-insensitive, so no stress about caps ๐Ÿ’…

18. Scalability and Limits ๐ŸŒธ

there are no issues other than those concerned with the ability of the server to refuse to have a complete TLS negotiation for each and every data connection, which will allow servers to retain throughput whilst using cycles only when necessary. โšก

19. Applicability ๐Ÿฆ‹

this mechanism is generally applicable as a mechanism for securing the FTP protocol. It is unlikely that anonymous FTP clients or servers will require such security (although some might like the authentication features without the confidentiality). ๐Ÿงšโ€โ™€๏ธ

20. Acknowledgements ๐Ÿ’–

  • Netscape Communications Corporation for the original SSL protocol.
  • Eric Young for the SSLeay libraries.
  • University of California, Berkeley for the original implementations of FTP and ftpd, on which the initial implementation of these extensions were layered.
  • IETF CAT working group.
  • IETF TLS working group.
  • IETF FTPEXT working group.
  • Jeff Altman for the ABOR and STAT discussion.
  • The various people who have help author this document throughout its protracted draft stages, namely Martin Carpenter, Eric Murray, Tim Hudson, and Volker Wiegand. ๐Ÿซถโœจ

21. References ๐Ÿ“š

21.1. Normative References

[RFC-959]  Postel, J. and J. Reynolds, "File Transfer Protocol", STD
           9, RFC 959, October 1985.

[RFC-2119] Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC-2228] Horowitz, M. and S. Lunt, "FTP Security Extensions", RFC
           2228, October 1997.

[RFC-2246] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0",
           RFC 2246, January 1999.

[RFC-2389] Hethmon, P. and R. Elz, "Feature negotiation mechanism for
           the File Transfer Protocol", RFC 2389, August 1998.

21.2. Informative References

[RFC-1579] Bellovin, S., "Firewall-Friendly FTP", RFC 1579, February
           1994.

[RFC-2222] Myers, J., "Simple Authentication and Security Layer
           (SASL)", RFC 2222, October 1997.

[RFC-2577] Allman, M. and S. Ostermann, "FTP Security
           Considerations", RFC 2577, May 1999.

[RFC-2712] Medvinsky, A. and M. Hur, "Addition of Kerberos Cipher
           Suites to Transport Layer Security (TLS)", RFC 2712,
           October 1999.

[RFC-2817] Khare, R. and S. Lawrence, "Upgrading to TLS Within
           HTTP/1.1", RFC 2817, May 2000.

[RFC-2818] Rescorla, E., "HTTP Over TLS", RFC 2818, May 2000.

[RFC-3207] Hoffman, P., "SMTP Service Extension for Secure SMTP over
           Transport Layer Security", RFC 3207, February 2002.

Contributors ๐ŸŒŸ

Tim Hudson
RSA Data Security
Australia Pty Ltd

Phone: +61 7 3227 4444
EMail: tjh@rsasecurity.com.au


Volker Wiegand
SuSE Linux

EMail: wiegand@suse.de


Martin Carpenter
Verisign Ltd

EMail: mcarpenter@verisign.com


Eric Murray
Wave Systems Inc.

EMail: ericm@lne.com

Author's Address ๐Ÿ–Š๏ธ

Paul Ford-Hutchinson
IBM UK Ltd
PO Box 31
Birmingham Road
Warwick
United Kingdom

Phone: +44 1926 462005
EMail: rfc4217@ford-hutchinson.com

Copyright (C) The Internet Society (2005).

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property ๐Ÿ”

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.

Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.

Acknowledgement ๐Ÿ’œ

Funding for the RFC Editor function is currently provided by the Internet Society. ๐ŸŽ€

๐Ÿ“ฆ where this page comes from