RFC 7151
File Transfer Protocol HOST Command for Virtual Hosts
RFC 7151 π File Transfer Protocol HOST Command for Virtual Hosts
okay bestie, this is RFC 7151 and it's about a new FTP command called HOST π Here's the title block tea: it's by P. Hethmon (Hethmon Brothers) and R. McMurray (Microsoft Corporation). It's a Standards Track doc, published March 2014, with ISSN 2070-1721. It updates RFC 959 (that's the original FTP spec), and the header doesn't list anything it obsoletes. β¨
Abstract πΈ
Okay so, RFC 959 (the original FTP spec) has no way for FTP clients and servers to tell apart multiple DNS names that are all registered to one IP address. This doc adds a new FTP command that lets clients and servers identify individual virtual hosts on an FTP server. Main character energy π
Status of This Memo π
This is an Internet Standards Track document. π¦
This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 5741.
Info about the current status of this doc, any errata, and how to give feedback is at http://www.rfc-editor.org/info/rfc7151. π
Copyright Notice Β©οΈ
Copyright (c) 2014 IETF Trust and the persons identified as the document authors. All rights reserved. π«Ά
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, because they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License. π
Table of Contents πΊοΈ
1. Introduction ....................................................2
2. Document Conventions ............................................3
2.1. Basic Tokens ...............................................3
2.2. Server Replies .............................................4
3. The HOST Command ................................................4
3.1. Syntax of the HOST Command .................................5
3.2. HOST Command Semantics .....................................7
3.2.1. REIN Command Semantics ..............................8
3.2.2. User-PI Usage of HOST ...............................9
3.2.3. State Diagrams .....................................11
3.3. HOST Command Errors .......................................16
3.4. FEAT Response for HOST Command ............................17
4. Security Considerations ........................................17
5. IANA Considerations ............................................19
6. References .....................................................19
6.1. Normative References ......................................19
6.2. Informative References ....................................20
Appendix A. Unworkable Alternatives ...............................21
A.1. Overloading the CWD Command ................................21
A.2. Overloading the ACCT Command ...............................21
A.3. Overloading the USER Command ...............................22
A.4. Conclusion .................................................23
Appendix B. Acknowledgements ......................................23
1. Introduction π§
It's super common on the Internet for lots of DNS names to resolve to a single IP address. This practice gave us the idea of a "virtual host", where a host appears to be an independent entity but actually shares its physical resources with one or more similar hosts. π
This setup causes some problems for FTP servers, because an FTP server tells incoming FTP connections apart by IP address rather than by DNS name. So all DNS names that share an IP address get handled by the same FTP server and share the same Network Virtual File System (NVFS). π
That means different virtual hosts can't offer clients different virtual file systems, and they can't offer different authentication systems either. Any fix for this has to indicate not only the destination IP address but also the virtual hostname that goes with the virtual FTP server the client wants. Right now, typical user-FTP processes use hostnames to resolve the IP address and then ignore the hostname for the rest of the FTP session. So any fix would need changes to the user protocol interpreter (user-PI) and the server protocol interpreter (server-PI). π₯
Worth noting: this same problem existed for HTTP/1.0 as defined in [RFC1945], and it was solved in HTTP/1.1 as defined in [RFC2616] by adding the Host request header field. The goal of this document is to give FTP that same level of feature parity by introducing a new HOST command. It lets a user-FTP process say which virtual host it wants to connect to, on a server-FTP process that handles requests for multiple virtual hosts on a single IP address. β¨
2. Document Conventions π
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119]. π
In examples, "C>" and "S>" indicate lines sent by the client and server, respectively. π
This document also uses notation defined in [RFC959] and [RFC1123]. Specifically, the terms "reply", "user", "NVFS", "NVT", "file", "pathname", "FTP commands", "DTP", "user-FTP process", "user-PI", "user-DTP", "server-FTP process", "server-PI", "server-DTP", "mode", "type", "control connection", "data connection", and "ASCII" all mean exactly what they mean there. π
The required syntax is written in the Augmented BNF from [RFC5234]. Some general ABNF definitions are needed throughout the document, and they'll be defined in later sections. π§
With virtualization tech being used so much these days, there might be several possible definitions for "virtual host". This document follows the definition from Section 4.1.14 of [RFC3875], where several virtual hosts share the same IP address, and hostnames are how the server-FTP process routes user-PI sessions to the right virtual host. π¦
2.1. Basic Tokens π
This document imports the core definitions from Appendix B of [RFC5234]. That's where you'll find basic ABNF elements like ALPHA, DIGIT, SP, and so on. On top of those, this document adds the following term. πΈ
TCHAR = VCHAR / SP / HTAB ; visible plus white space
The VCHAR rule (from [RFC5234]) and the TCHAR rule give basic character types from different subsets of the ASCII character set, for use in various commands and responses. π₯
Quick heads-up: in ABNF, string literals are case insensitive. That convention is kept in this document, which means the FTP commands and parameters added by this spec can be written in any case. So "HOST" is the same as "host", "Host", "HoSt", and so on. Domain names are also case insensitive, so "ftp.example.com" is the same as "Ftp.Example.Com", "fTp.eXample.cOm", and so on. π
2.2. Server Replies π¨οΈ
Section 4.2 of [RFC959] defines the format and meaning of replies from the server-PI to FTP commands from the user-PI. This document uses those reply conventions without any changes. β¨
error-response = error-code SP *TCHAR CRLF
error-code = ("4" / "5") 2DIGIT
Implementers should know that the ABNF syntax in this document and other FTP-related documents (but not the syntax in [RFC959]) sometimes shows replies in the one-line format. Unless it's explicitly stated otherwise, multi-line responses are also allowed. Implementers should assume that, unless stated to the contrary, any reply to any FTP command (including QUIT) can be in the multi-line format described in [RFC959]. π«Ά
Throughout this document, replies are identified by the three-digit code that comes first in them. So the term "500 reply" means a reply from the server-PI using the three-digit code "500". π
3. The HOST Command π
A new command, "HOST", is added to the FTP command set so that a server-FTP process can work out which of possibly many virtual hosts the client wants to connect to. If a HOST command is sent, it MUST be issued before the user is authenticated, because that lets the authentication scheme and the set of authorized users depend on the virtual host that gets chosen. π
Server-FTP processes MUST treat a situation in which the HOST command is issued more than once before the user has been authenticated as though only the last HOST command had been sent. They then return the appropriate reply for that last HOST command. Server-FTP processes MUST treat a situation in which the HOST command is issued after the user has been authenticated as an erroneous sequence of commands, and return a 503 reply. π
Servers should note that the response to the HOST command is a good moment to send their "welcome" message. That lets the message be personalized for any virtual hosts that are supported. It also lets the client use the FEAT response to see which languages or representations the server supports, and pick one with the LANG command. See [RFC2640] for more information. π§
Also, user-PI implementations created before the HOST command was introduced won't support this new command. A similar problem came up when the Host header was introduced for HTTP in [RFC2616]. HTTP server implementations had to figure out how best to handle HTTP requests from down-level clients that didn't support the Host header. With that in mind, server-FTP processes will need to figure out how best to handle FTP requests from down-level FTP clients that don't support the HOST command. Those considerations are outside the scope of this document, though. π¦
3.1. Syntax of the HOST Command π
okay so here's the grammar for the HOST command π§ bestie, one thing first: [RFC3986] is still the source of truth for how IPv4 and IPv6 address literals are written. That keeps the presentation identical in 'ftp' URI hostname parts and in the protocol element here π
host-command = "HOST" SP hostname CRLF
hostname = domain / IP-literal
domain = sub-domain *("." sub-domain)
sub-domain = let-dig [ldh-str]
let-dig = ALPHA / DIGIT
ldh-str = *( ALPHA / DIGIT / "-" ) let-dig
IP-literal = ( "[" IPv6address "]" ) / IPv4address
IPv6address = <see [RFC3986] Section 3.2.2>
IPv4address = <see [RFC3986] Section 3.2.2>
host-response = host-ok / error-response
host-ok = "220" [ SP *TCHAR ] CRLF
The "hostname" rule is a tighter version of the "host" rule from [RFC3986] πΈ This doc adds extra restrictions, and you'll see the details in the syntax talk later in this section. The whole point is to make implementers' lives easier by only allowing stuff that's precisely specified and actually used on the Internet. Iconic, honestly β¨
As with every FTP command, the "HOST" command word is case independent. You can type it in whatever case you want π
The "hostname" parameter is the virtual host you want to access π¦ It SHOULD be the same hostname that was used to get the IP address the FTP control connection was made to. This counts after any client conversions that turn an abbreviated or local alias into a full (fully qualified) domain name, but it's before you resolve a DNS alias (the owner of a CNAME resource record) to its canonical name. Main character sequencing, no cap π
Internationalized domain names are only supported through Internationalized Domain Names for Applications (IDNA) "A-labels" for <sub-domain>, as described in [RFC5890]. For example, this HOST command specifies an internationalized domain name π
HOST xn--e1afmkfd.com
Now, if the user was handed an IPv4 or IPv6 literal address, and so never had to derive it from a hostname, the client MAY send the HOST command with the IPv4 or IPv6 literal address exactly as it was given π§ Lowkey weird to send a literal address with HOST after you already connected using one, I know π But this is expected behaviour, because a user-FTP process shouldn't have to tell the difference between a fully qualified domain name and an IPv4 or IPv6 network literal address. That said, if the literal address the client specifies doesn't match the server's literal address, the server MUST respond with a 504 reply to say the IPv4 or IPv6 literal address isn't valid π
When the hostname parameter has a literal address, square brackets are there to tell IPv6 address syntax apart from port number syntax π So if the literal address is an IPv6 address, it is required to be enclosed in square brackets. (This is after getting rid of any syntax that might also be enclosed in brackets but doesn't have to be, and that the server used to work out a literal address was specified.) Here are some examples that MAY be sent if the client was told to connect to "192.0.2.1", "2001:db8::c000:201", or "::192.0.2.1", respectively, with IPv6 syntax preferred π«Ά
HOST 192.0.2.1
HOST [2001:db8::c000:201]
HOST [::192.0.2.1]
The client MUST NOT send the port number as part of the HOST command, even if it was told to connect to a non-standard port π The reason is that the user-PI has already set up a connection to the server-PI before the HOST command gets sent, so giving a different port with HOST means absolutely nothing π For example, the server-PI MUST respond with a 501 reply if the client sends a HOST command that looks like either of these:
HOST 192.0.2.1:2112
HOST [2001:db8::c000:201]:2112
Otherwise, the hostname parameter is treated as a fully qualified domain name or a relative name, as those terms are defined in Section 3.1 of [RFC1034] π That means the name is a case-independent string: uppercase ASCII characters count as the same as their lowercase ASCII versions, but otherwise they're kept exactly as given. It also means there are limits on the length of the parameter and of the parts that make up its internal structure. Those limits aren't changed in any way here πΈ
Neither [RFC1034] nor [RFC1035] puts any other restrictions on what names can be stored in the DNS. This spec, though, only allows names that can be inferred from the ABNF grammar given for "hostname" π Similarly, this spec only allows address literals from the IPv4 and IPv6 address families that are well established on the Internet β¨
3.2. HOST Command Semantics π
When a server gets the HOST command, before it authenticates the user-PI, a server-FTP process SHOULD check that the hostname given is a valid virtual host for that server. If it is, the server-FTP process sets up the right environment for that virtual host π¦ This doc doesn't specify what actions create that environment. They could be anything from doing nothing at all, to a simple change of working directory, to changing authentication schemes and/or username and password lists, or even much more elaborate state changes like creating isolated environments for each FTP session π€―
The 220 reply code for the HOST command is the same code used in the initial "welcome" message that gets sent after the connection is established π
If the hostname specified would normally be acceptable but is temporarily unavailable, the server-FTP process SHOULD respond to the HOST command with a 421 reply and close the connection π
Example: The server-FTP process is shutting down, so it responds to the HOST command with a 421 reply and closes the connection. In this scenario, the 421 reply tells the client it can retry at another time.
If the hostname specified is unknown to the server, or if the server is otherwise unwilling to treat this particular connection as a connection to the hostname specified, the server SHOULD respond with a 504 reply π
Examples: The particular virtual host that the HOST command specified is disabled at the server. The server responds with a 504 reply and keeps the connection open, so the user-PI gets a chance to name another virtual host with a later HOST command. Alternatively, the server-FTP process might choose to route all connections with unknown hostnames to a different virtual host, so no connection attempts end up failing. This design would be implementation specific and is outside the scope of this specification π§
3.2.1. REIN Command Semantics π
As [RFC959] specifies, the REIN command returns the state of the connection to what it was right after the transport connection was opened. This spec makes no changes to that behaviour π The effect of a HOST command MUST be reset if a REIN command is performed, and a new HOST command MUST be issued afterwards to connect to a virtual host. Non-negotiable, bestie π€
3.2.2. User-PI Usage of HOST π¦
A user-PI MUST send the HOST command after opening the transport connection, or after any REIN command, and before it tries to authenticate the user with the USER command. Here's what a typical login sequence might look like when HOST is used π
C> HOST ftp.example.com
S> 220 Host accepted
C> USER foo
S> 331 Password required
C> PASS bar
S> 230 User logged in
If a user-PI sends another HOST command before trying to authenticate the user, a server-FTP process MUST treat the additional HOST command as though no previous HOST command had been sent, and return the appropriate reply for the new HOST command. This is so useful, ngl. For example, if a user accidentally types the wrong virtual hostname, sending a subsequent HOST command fixes the mistake π Here's what the login sequence might look like when HOST is sent twice before the user is authenticated:
C> HOST foo.example.com
S> 220 Host accepted
C> HOST bar.example.com
S> 220 Host accepted
C> USER foo
S> 331 Password required
C> PASS bar
S> 230 User logged in
The HOST command can be combined with the ACCT command to tell apart a user's various accounts on a specific virtual host π In this scenario, the user-PI sends a HOST command, which the server-PI uses to route activity to the correct virtual host. The user-PI then sends credentials using the USER and PASS commands, which the server-PI validates. Then, the user-PI sends an ACCT command to specify any extra account information for the server-PI implementation. Here's a sequential series of client commands that send both HOST and ACCT, with the server responses left out for brevity:
C> HOST ftp.example.com
C> USER foo
C> PASS bar
C> ACCT project1
This is also true when HOST is used with the AUTH and ADAT commands discussed in [RFC2228] and [RFC4217] π«Ά In this scenario, the user-PI sends a HOST command, which the server-PI uses to route activity to the correct virtual host. Then the user-PI uses the AUTH and ADAT commands to negotiate the security mechanism and the relevant authentication token(s) with the server-PI. Next, the user-PI sends user credentials using the USER and PASS commands, which the server-PI validates. After that, the user-PI MAY send an ACCT command to specify any extra account information for the server-PI implementation. Here's a sequential series of client commands that send both HOST and ACCT alongside the security commands discussed in [RFC2228] and [RFC4217], with server responses omitted for brevity:
C> HOST ftp.example.com
C> AUTH <mechanism-name>
C> ADAT <base64data>
C> USER foo
C> PASS bar
C> ACCT project1
There's one exception to the above scenario π¨ It happens when the user-PI provides the hostname in the "server_name" extension of a Transport Layer Security (TLS) extended client hello, as discussed in [RFC6066]. When the user-PI specifies the hostname in the "server_name" extension of a TLS extended client hello, the server-PI MUST verify that the hostname in the HOST command matches the value of the "server_name" extension. Here's a sequential series of client commands that use HOST alongside the TLS extensions discussed in [RFC6066], with server responses omitted for brevity:
C> AUTH TLS
C> HOST ftp.example.com
C> USER foo
C> PASS bar
Additional security information about using the HOST command with the security extensions discussed in [RFC2228], [RFC4217], and [RFC6066] is in Section 4 of this document π
3.2.3. State Diagrams β¨
okay so this section is the visual part of the RFC π and honestly the diagrams are giving main character energy π they show the typical back-and-forth between the user-PI and the server-PI, and they're modeled on the similar diagrams in Section 6 of [RFC959] π§
quick setup before we dive in π«Ά in every diagram, the (B) "begin" state is assumed to happen after the transport connection has opened, or after a REIN command has succeeded πΈ and other commands that don't need authentication, like FEAT [RFC2389], may have slipped in before that π
some decoder rings for reading the diagrams π₯ a three-digit reply means a precise server reply code π― but a single digit on a reply path means ANY reply starting with that digit, unless a precise code is already defined on another path π so a single "5" covers "500", "501", "502", and so on, when those codes aren't explicitly drawn in the diagram π every command has three possible outcomes: success (S), failure (F), or error (E) β¨ and in the diagrams we use "B" for "begin" and "W" for "wait for reply" π¦
one more thing that's lowkey important π for each of these diagrams, even when no state transitions are shown, a REIN command will send the diagram from ANY wait state back to the (B) "begin" state π
Figure 1 is the typical login sequence when HOST is used with USER and PASS to log in to a particular FTP virtual host π
+---+ HOST +---+ 1,3,5
| B |---------->| W |-----------------
+---+ +---+ |
| | |
2,500,502 | | 4,501,503,504 |
-------------- ----------- |
| | V
V 1 | +---+
+---+ USER +---+-------------->| E |
| |---------->| W | 2 | +---+
+---+ +---+------- | ^
| | | | |
3 | | 4,5 | | |
-------------- ----- | | |
| | | | |
| -------------------
| 1| | | |
V | | ------>+---+
+---+ PASS +---+ 2 | | | S |
| |---------->| W |-------------->+---+
+---+ +---+ | |
| | |
|4,5 | |
| | --->+---+
| --------->| F |
---------------->+---+
Figure 1: Typical Login Sequence with HOST Command πΈ
after a user has logged in, the server might want an extra account too π¦ and the client can specify it using the ACCT command π so Figure 2 shows the typical flow when HOST is used with USER and PASS to log in to an FTP virtual host AND ACCT is used to specify an account π«Ά
+---+ HOST +---+ 1,3,5
| B |---------->| W |-----------------
+---+ +---+ |
| | |
2,500,502 | | 4,501,503,504 |
-------------- ------------- |
| | |
V 1 | V
+---+ USER +---+-------------->+---+
| |---------->| W | 2 ----->| E |
+---+ +---+------ | --->+---+
| | | | | |
3 | | 4,5 | | | |
-------------- ----- | | | |
| | | | | |
| | | | | |
| ---------- | |
| 1| | | | |
V | | | | |
+---+ PASS +---+ 2 | ------->+---+
| |---------->| W |-------------->| S |
+---+ +---+ ----------->+---+
| | | | | |
3 | |4,5| | | |
-------------- -------- | ----
| | | | | |
| | | | | |
| ------------ |
| 1,3| | | | |
V | 2| | | V
+---+ ACCT +---+-- | ------>+---+
| |---------->| W | 4,5 --------->| F |
+---+ +---+-------------->+---+
Figure 2: Login Sequence with HOST and ACCT Commands π
Figure 3 is the one for when HOST is used with the AUTH and ADAT commands discussed in [RFC2228] π and yes there's a NOTE here that's important π Section 4 has extra details about using the HOST command with TLS π
+---+ HOST +---+ 1,3,5
| B |---------->| W |------------------
+---+ +---+ |
| | |
2,500,502 | | 4,501,503,504 |
-------------- ------------- |
| | |
V | |
+---+ AUTH +---+ 4,5 | |
| |---------->| W |----------->| |
+---+ +---+ | |
334 | | | |
-------------- | | |
| 234 | | |
| ------------ | |
V | 4,5 | |
+---+ | ADAT +---+----------->| |
| |---------->| W | 335 | |
+---+ | +---+----- | |
^ | | | | |
| | | | | |
----------------------- | |
| | | |
---- 235 | | |
| -------------- | |
| | | V
V V 1 | +---+
+---+ USER +---+--------------->| E |
| |---------->| W | 2 | +---+
+---+ +---+------- | ^
| | | | |
3 | | 4,5 | | |
-------------- ------ | | |
| | | | |
| --------------------
| 1| | | |
V | | ------->+---+
+---+ PASS +---+ 2 | | | S |
| |---------->| W |--------------->+---+
+---+ +---+ | |
| | |
|4,5 | |
| | -->+---+
| --------->| F |
----------------->+---+
Figure 3: Login Sequence with HOST and AUTH/ADAT Commands π
last one, and it's a whole vibe π after logging in with the security commands discussed in [RFC2228], the server might want an extra account, and the client can specify it with ACCT π so Figure 4 shows the typical flow when HOST is used with AUTH and ADAT to log in to an FTP virtual host and ACCT is used to specify an account π
+---+ HOST +---+ 1,3,5
| B |---------->| W |------------------
+---+ +---+ |
| | |
2,500,502 | | 4,501,503,504 |
+-------------- -------------- |
| | |
V | |
+---+ AUTH +---+ 4,5 | |
| |---------->| W |------------>| |
+---+ +---+ | |
334 | | | |
-------------- | | |
| 234 | | |
| ------------ | |
V | 4,5 | |
+---+ | ADAT +---+------------>| |
| |---------->| W | 335 | |
+---+ | +---+----- | |
^ | | | | |
| | | | | |
----------------------- | |
| | | |
---- 235| | |
| -------------- | |
| | | |
V V 1 | V
+---+ USER +---+--------------->+---+
| |---------->| W | 2 ----->| E |
+---+ +---+------- | --->+---+
| | | | | |
3 | | 4,5 | | | |
-------------- ------ | | | |
| | | | | |
| ----------- | |
| 1| | | | |
V | | | | |
+---+ PASS +---+ 2 | ------->+---+
| |---------->| W |--------------->| S |
+---+ +---+ ------------>+---+
| | | | | |
3 | |4,5| | | |
-------------- --------- | ----
| | | | | |
| ------------- |
| 1,3| | | | |
V | 2| | | V
+---+ ACCT +---+-- | ------>+---+
| |---------->| W | 4,5 --------->| F |
+---+ +---+--------------->+---+
Figure 4: Login Sequence with HOST and AUTH/ADAT/ACCT Commands π
3.2.3. State Diagrams β¨
3.3. HOST Command Errors β¨
okay bestie, so the server-PI SHOULD return a 500 or 502 reply if it doesn't recognize or implement the HOST command, as specified in [RFC959] π . Like, a server-PI that's older or just doesn't follow this spec would be expected to send back a 500 or 502 reply. Totally normal, no cap π
As we talked about in Section 3 of this document, if someone sends a HOST command AFTER a user has been authenticated, the server MUST treat it as an invalid sequence of commands and send back a 503 reply. Not me sending HOST late to the party π
A 501 reply SHOULD be sent if the hostname is syntactically invalid π«Ά, and a 504 reply SHOULD be sent if the hostname is syntactically valid but isn't a valid virtual hostname for that server πΈ. In all of these cases, the server-FTP process MUST do one of the following:
a. Ignore the HOST command and act as if it was never sent. A user-FTP process MAY then send a new HOST command with a different hostname π¦. b. Close the connection π₯.
When a user-PI gets a 500 or 502 reply to a HOST command, it SHOULD assume the server-PI doesn't do virtual servers via the HOST command π. The user-PI MAY then keep going and log in as if the HOST command was never sent. Lowkey iconic fallback behavior β¨.
If a user-PI gets an error reply that's different from the ones described here, it SHOULD assume the virtual HOST is unavailable and end communications π.
A server-PI that gets a USER command to start authentication without having received a HOST command SHOULD NOT reject the USER command π«Ά. Clients that follow earlier FTP specs don't send HOST commands at all, so it's giving "be nice to the old clients" energy π. In this case, the server MAY act as if some default virtual host had been explicitly selected π, or the server MAY enter an environment that's different from any supported virtual hosts. Like, maybe one where all the accounts are combined, and the NVFS looks like it has subdirectories holding the NVFS for every supported virtual host π§. Main character server energy π.
3.4. FEAT Response for HOST Command β¨
When replying to the FEAT command [RFC2389], a server-FTP process that supports the HOST command MUST include a line containing the single word "HOST" π. This word is case insensitive, but it SHOULD be sent in upper case so it's easiest for different implementations to understand each other π. So the response SHOULD be:
C> FEAT
S> 211- <any descriptive text>
S> ...
S> HOST
S> ...
S> 211 End
The ellipses are placeholders where other features can go, but they're not required π¦. The one-space indentation of the feature lines is mandatory [RFC2389] π .
4. Security Considerations π₯
Okay this section is SERIOUS, so pay attention π. As we talked about in Section 3 of this document, a server implementation MUST treat an extra HOST command that was sent before a user has been authenticated as though no previous HOST command was sent π. The server implementation MUST reset the authentication environment, because that's what lets each virtual host on an FTP server stay segregated from the others π. How the security environments are built can vary a lot depending on each server implementation and operating system, and those details are outside the scope of the protocol itself π. For example, a virtual host "foo.example.com" might use one username and password list, while "bar.example.com" on the same FTP server uses a different one π. In that kind of setup, resetting the security environment is necessary so the virtual servers look like they behave independently from the client's side, even though the actual implementation details don't matter at the protocol level πΈ.
Section 15.1.1 of [RFC4217] talks about using X.509 certificates for server authentication π. Keeping that info in mind, when securing FTP sessions with the mechanisms defined in [RFC4217], client implementations SHOULD verify that the hostname they put in the HOST command parameter matches the identity in the server's X.509 certificate, so man-in-the-middle attacks get blocked π‘οΈβ¨.
When the HOST command is used together with the FTP security extensions introduced in [RFC2228] and [RFC4217], the HOST command SHOULD come before the security handshake when the user-PI is NOT providing the "server_name" in the extended client hello defined in [RFC6066] π . This lets both the user-FTP and server-FTP processes map an FTP HOST to the correct server name in the server's certificate π. If the HOST command is sent AFTER the security handshake, mapping an FTP HOST to the correct certificate won't happen before the secure session is already established π¬.
For example, if a server-FTP process has several virtual hosts defined and no hostname was sent from a user-FTP process, the server-FTP process can't route the connection to the right virtual host when the connection is established π. So it's forced to pick a virtual host that will respond. When the user-PI tries to negotiate a secure connection, the virtual host the connection got routed to will respond with its server certificate during the security handshake π. If that isn't the virtual host the user-FTP process meant to connect to, the user-PI won't be able to verify the server's identity from the certificate message π.
However, if the user-PI IS providing the "server_name" in the extended client hello defined in Section 3 of [RFC6066], the user-PI MAY provide the HOST command after the security handshake π¦. That's because the server can route the connection to the right virtual host based on the "server_name" extension, and the client can verify the server's identity from the matching server certificate message β¨. Even so, the server-PI MUST verify that the name in the HOST command matches the "server_name" provided in the extended client hello π«Ά.
In general, client implementations SHOULD protect user credentials by using the FTP security extensions introduced in [RFC2228] and [RFC4217] π. A detailed discussion of securing FTP sessions is in those documents, and a general discussion of FTP security issues is in [RFC2577] π.
5. IANA Considerations π
IANA has registered the following FTP extension according to the procedure established by [RFC5797] π:
+------+---------+-------------+------+------+----------------------+
| cmd | FEAT | description | type | conf | RFC#s/References and |
| | Code | | | | Notes |
+------+---------+-------------+------+------+----------------------+
| HOST | HOST | Hostname | a | o | RFC 7151 |
+------+---------+-------------+------+------+----------------------+
6. References π
6.1. Normative References
[RFC959] Postel, J. and J. Reynolds, "File Transfer Protocol
(FTP)", STD 9, RFC 959, October 1985.
[RFC1034] Mockapetris, P., "Domain Names - Concepts and Facilities",
STD 13, RFC 1034, November 1987.
[RFC1035] Mockapetris, P., "Domain Names - Implementation and
Specification", STD 13, RFC 1035, November 1987.
[RFC1123] Braden, R., "Requirements for Internet Hosts - Application
and Support", STD 3, RFC 1123, October 1989.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC2228] Horowitz, M. and S. Lunt, "FTP Security Extensions", RFC
2228, October 1997.
[RFC2389] Hethmon, P. and R. Elz, "Feature negotiation mechanism for
the File Transfer Protocol", RFC 2389, August 1998.
[RFC2640] Curtin, B., "Internationalization of the File Transfer
Protocol", RFC 2640, July 1999.
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
Resource Identifier (URI): Generic Syntax", STD 66, RFC
3986, January 2005.
[RFC4217] Ford-Hutchinson, P., "Securing FTP with TLS", RFC 4217,
October 2005.
[RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", STD 68, RFC 5234, January 2008.
[RFC5890] Klensin, J., "Internationalized Domain Names for
Applications (IDNA): Definitions and Document Framework",
RFC 5890, August 2010.
[RFC6066] Eastlake, D., "Transport Layer Security (TLS) Extensions:
Extension Definitions", RFC 6066, January 2011.
6.2. Informative References
[RFC1945] Berners-Lee, T., Fielding, R., and H. Nielsen, "Hypertext
Transfer Protocol -- HTTP/1.0", RFC 1945, May 1996.
[RFC2577] Allman, M. and S. Ostermann, "FTP Security
Considerations", RFC 2577, May 1999.
[RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext
Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.
[RFC3875] Robinson, D. and K. Coar, "The Common Gateway Interface
(CGI) Version 1.1", RFC 3875, October 2004.
[RFC5797] Klensin, J. and A. Hoenes, "FTP Command and Extension
Registry", RFC 5797, March 2010.
Appendix A. Unworkable Alternatives π§
Because adding a new command to FTP is such a big deal, it's worth going over some suggested alternatives to a HOST command and why they don't work π . These ideas have been floated before, but each one got rejected for the reasons listed in its section of this appendix π«Ά.
A.1. Overloading the CWD Command π¦
One suggested method to fake virtual hosts is for the client to just send a CWD command after connecting, using the virtual hostname as the argument πΈ. That would let the server-FTP process set up each virtual host's file store as a subdirectory in its NVFS. It's simple in concept, and most server-FTP implementations support it without any code changes β¨. But while it's simple to describe and build, it has a few drawbacks π¬:
a. The CWD command is only available after the user-PI has authenticated itself to the server-FTP process. So all virtual hosts would need to share one authentication scheme if they used this method π.
b. To make the virtual host truly transparent, one of these has to be true π€: the server-FTP process gets modified to show the special nature of this first CWD command (which kinda defeats the whole point π), or all users see the exact same NVFS view when they connect (they have to connect to the same initial directory), or the NVFS implements the full set of virtual host directories at every possible initial directory for any possible user π.
c. Unless the server is specially modified, a user connecting this way to a virtual host could easily move to any other virtual host on the same server-FTP process, which exposes what the virtual host really is π.
A.2. Overloading the ACCT Command π
okay so the next idea was to just overload the ACCT command for FTP virtual hosts π§ but ngl it's a no from me, and the problem is when ACCT gets sent in the request flow. USER -> PASS -> ACCT is the login order from Sections 5.4 and 6 of [RFC959], and honestly it kinda works if one user just has a bunch of accounts on one server π. It falls apart for virtual hosts for two reasons:
a. The first problem is certificate negotiation when you're using the FTP security extensions in [RFC2228] and [RFC4217] π₯. To protect user credentials, the security mechanism and certificate have to be negotiated before the client sends any login credentials. The issue with using ACCT here is that nothing makes sure the certificate matches the right virtual host before the credentials go out π.
b. The second problem is how user credentials work for FTP virtual hosts. FTP server implementations can let each virtual host have its own custom user credentials πΈ. In one implementation, for example, the virtual host negotiation happens first, and then the credentials are looked up through that virtual host's own account mechanism. So again, the virtual host negotiation has to happen before the user credentials are sent π«Ά.
A.3. Overloading the USER Command π¦
another suggestion was to overload syntax that's already well known, by piggybacking on the existing USER command. Here's the example:
C> USER foo@example.com
S> 331 Password required
C> PASS bar
S> 230 User logged in
in this one, the user "foo" might be trying to log in to the virtual host "example.com" on an FTP server β¨. It sounds plausible at first, but it causes a bunch of implementation problems π:
a. Some network environments already use the "username@hostname" syntax for network credentials, where the "hostname" part points to where the user's credentials live in the network hierarchy π. With "foo@example.com", it gets really hard to tell apart two things: user "foo" logging in to a virtual host named "example.com" on an FTP server, and user "foo@example.com" logging in to an FTP server with no virtual host specified π΅.
b. When you use the FTP security extensions in [RFC2228] and [RFC4217], the security mechanism and certificate have to be negotiated before the client sends login credentials π. More specifically, the AUTH/ADAT commands must be sent before the USER command so the user credentials stay safe π‘οΈ. If you overload the USER command, there's no way to make sure the certificate matches the right virtual host before the client sends the user credentials π.
A.4. Conclusion π
after looking at all those alternatives, the group concluded that to get a proper emulation of "real" FTP servers, supporting virtual hosts needs changes on both the client and the server π. So a brand-new FTP command is the most likely solution to give us the level of support we need β.
Appendix B. Acknowledgements π«Ά
Robert Elz and Paul Hethmon gave a super detailed discussion of the HOST command in their Internet-Draft called "Extensions to FTP", written while they were working with the FTPEXT Working Group of the IETF π. Their work formed the basis for a lot of this document, and we are so grateful for their help π. They also want to credit Bernhard Rosenkraenzer for first suggesting and describing the HOST command π.
A bunch of people gave a ton of constructive feedback on earlier versions of this document, and that feedback really shaped where it ended up πΈ. Lots of their suggestions got put in, and their contributions are gratefully acknowledged π. There are way too many people to name here, but the authors specifically want to thank Alexey Melnikov, Alfred Hoenes, John Klensin, Joe Touch, Paul Ford-Hutchinson, Daniel Stenberg, Mykyta Yevstifeyev, Alec Rowell, Jaroslav Dunajsky, Wade Hilmo, Anthony Bryan, and Barry Leiba for their help β¨π.
Authors' Addresses ποΈ
Paul Hethmon
Hethmon Brothers
2305 Chukar Road
Knoxville, TN 37923
USA
EMail: phethmon@hethmon.com
Robert McMurray
Microsoft Corporation
One Microsoft Way
Redmond, WA 98052
USA
EMail: robmcm@microsoft.com
π¦ where this page comes from
- ietf: rfc7151 2014-03
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms