RFC 8308
Extension Negotiation in the Secure Shell (SSH) Protocol
RFC 8308: Extension Negotiation in the Secure Shell (SSH) Protocol π
okay bestie, this one is a whole spec π¦ It came out in March 2018 from D. Bider at Bitvise Limited, and it's a Standards Track document, so it's the real deal, an official IETF (Internet Engineering Task Force) standard π It also has the ISSN 2070-1721 if you're into that. It updates RFCs 4251, 4252, 4253, and 4254, which means it adds to them, so you have to read them together π§
Abstract
okay so this memo updates RFCs 4251, 4252, 4253, and 4254 by defining a way for Secure Shell (SSH) clients and servers to swap info about which protocol extensions they support, and they do it confidentially after SSH key exchange πβ¨
Status of This Memo
this is an Internet Standards Track document π
it's a product of the Internet Engineering Task Force (IETF), so it represents the consensus of the IETF community. it got public review and was approved for publication by the Internet Engineering Steering Group (IESG). if you want more on Internet Standards, check Section 2 of RFC 7841 πΈ
for the current status, any errata, and how to give feedback, go to https://www.rfc-editor.org/info/rfc8308 π
Copyright Notice
Copyright (c) 2018 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 (https://trustee.ietf.org/license-info) as they stood on the publication date. please read these carefully, because they describe your rights and restrictions for this document π«Ά
if you pull Code Components out of this document, they have to include the Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions. they come without warranty, as the Simplified BSD License says π
Table of Contents
1. Overview and Rationale ..........................................3
1.1. Requirements Terminology ...................................3
1.2. Wire Encoding Terminology ..................................3
2. Extension Negotiation Mechanism .................................3
2.1. Signaling of Extension Negotiation in SSH_MSG_KEXINIT ......3
2.2. Enabling Criteria ..........................................4
2.3. SSH_MSG_EXT_INFO Message ...................................4
2.4. Message Order ..............................................5
2.5. Interpretation of Extension Names and Values ...............6
3. Initially Defined Extensions ....................................6
3.1. "server-sig-algs" ..........................................6
3.2. "delay-compression" ........................................7
3.2.1. Awkwardly Timed Key Re-Exchange .....................9
3.2.2. Subsequent Re-Exchange ..............................9
3.2.3. Compatibility Note: OpenSSH up to Version 7.5 .......9
3.3. "no-flow-control" .........................................10
3.3.1. Prior "No Flow Control" Practice ...................10
3.4. "elevation" ...............................................11
4. IANA Considerations ............................................12
4.1. Additions to Existing Registries ..........................12
4.2. New Registry: Extension Names .............................12
4.2.1. Future Assignments to Extension Names Registry .....12
5. Security Considerations ........................................12
6. References .....................................................13
6.1. Normative References ......................................13
6.2. Informative References ....................................13
Acknowledgments ...................................................14
Author's Address ..................................................14
1. Overview and Rationale β¨
okay so Secure Shell (SSH) is a super common protocol for secure communication on the Internet π the original design of the SSH transport layer [RFC4253] doesn't have proper extension negotiation, which is kind of a big deal π meanwhile, lots of implementations work really hard to make sure known message types don't contain any unrecognized info.
so it's hard for implementations to signal their capabilities and negotiate extensions without risking a disconnection π this problem came up while SSH was being updated to support RSA signatures using SHA-256 and SHA-512 [RFC8332]. to avoid trial and error (and authentication penalties), a client has to be able to figure out which public key algorithms a server accepts. this extension mechanism is what makes that discovery possible π¦
this memo updates RFCs 4251, 4252, 4253, and 4254 π
1.1. Requirements Terminology
the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. π
1.2. Wire Encoding Terminology
the wire encoding types in this document ("byte", "uint32", "string", "boolean", "name-list") have the meanings described in [RFC4251]. π§
2. Extension Negotiation Mechanism πΈ
2.1. Signaling of Extension Negotiation in SSH_MSG_KEXINIT
applications implementing this mechanism MUST add one of the following indicator names to the kex_algorithms field in the SSH_MSG_KEXINIT message they send in the first key exchange:
- When acting as server:
"ext-info-s" - When acting as client:
"ext-info-c"
the indicator name gets added without quotes, and it MAY be added at any position in the name-list, as long as it's properly separated from other names per name-list conventions. β¨
the names go into the kex_algorithms field because it's one of two name-list fields in SSH_MSG_KEXINIT that don't have a separate copy for each data direction π
the indicator names inserted by the client and the server are different, so they won't produce a match and won't affect the algorithm chosen in key exchange algorithm negotiation. π
putting textual indicator names in there is meant to give implementers a clue for finding this mechanism π¦
2.2. Enabling Criteria
if a client or server offers "ext-info-c" or "ext-info-s" respectively, it MUST be prepared to accept an SSH_MSG_EXT_INFO message from the peer. π«Ά
a server only needs to send "ext-info-s" if it intends to process SSH_MSG_EXT_INFO from the client. a client only needs to send "ext-info-c" if it plans to process SSH_MSG_EXT_INFO from the server. π
if a server receives an "ext-info-c", or a client receives an "ext-info-s", it MAY send an SSH_MSG_EXT_INFO message, but it is not required to do so. β
neither party needs to wait for the other's SSH_MSG_KEXINIT before deciding whether to send the right indicator in its own SSH_MSG_KEXINIT. π
implementations MUST NOT send an incorrect indicator name for their role. implementations MAY disconnect if the counterparty sends an incorrect indicator. if"ext-info-c"or"ext-info-s"ends up being negotiated as a key exchange method, the parties MUST disconnect. π
2.3. SSH_MSG_EXT_INFO Message
a party that received the "ext-info-c" or "ext-info-s" indicator MAY send the following message:
byte SSH_MSG_EXT_INFO (value 7)
uint32 nr-extensions
repeat the following 2 fields "nr-extensions" times:
string extension-name
string extension-value (binary)
implementers should pay close attention to Section 2.5, especially the requirement to tolerate any sequence of bytes (including null bytes at any position) in an unknown extension's extension-value. π
2.4. Message Order
if a client sends SSH_MSG_EXT_INFO, it MUST send it as the next packet after the client's first SSH_MSG_NEWKEYS message to the server. π§
if a server sends SSH_MSG_EXT_INFO, it MAY send it at zero, one, or both of the following opportunities:
- As the next packet following the server's first SSH_MSG_NEWKEYS.
okay so where clients need info from the server's SSH_MSG_EXT_INFO to authenticate, it's helpful if the server sends its SSH_MSG_EXT_INFO not only as the next packet after SSH_MSG_NEWKEYS, but without delay. β°
clients can't rely on this, because the server isn't required to send the message at this time, and if it does send it, the network might delay it. π but if a timely SSH_MSG_EXT_INFO comes in, a client can pipeline an authentication request right after its SSH_MSG_SERVICE_REQUEST, even when it needs extension info. π
- Immediately preceding the server's SSH_MSG_USERAUTH_SUCCESS, as defined in [RFC4252].
the server MAY send SSH_MSG_EXT_INFO at this second opportunity, whether or not it sent one at the first. a client that sent "ext-info-c" MUST accept a server's SSH_MSG_EXT_INFO at both opportunities, but it MUST NOT require one. π
this lets a server reveal support for extra extensions it didn't want to show an unauthenticated client π¦ if a server sends a second SSH_MSG_EXT_INFO, it replaces any initial one, and both the client and the server re-evaluate the extensions in effect. the server's second SSH_MSG_EXT_INFO is matched against the client's original. π
the timing of this second opportunity was chosen for a reason. if the message went out earlier, the server couldn't hold back information until the client has authenticated. if it went out later, a client that needs info from the second SSH_MSG_EXT_INFO right after it authenticates would have no reliable way to know whether to expect the message. π
2.5. Interpretation of Extension Names and Values
each extension is identified by its extension-name and defines the conditions under which it's considered to be in effect. applications MUST ignore unrecognized extension-names. πΈ
when it's specified, an extension MAY dictate that both parties must include it in their SSH_MSG_EXT_INFO for it to take effect, or that it's enough for only one party to include it. other rules MAY be specified too. the relative order in which extensions appear in an SSH_MSG_EXT_INFO message MUST be ignored. β¨
extension-value fields are interpreted as defined by their respective extension. this field MAY be empty if the extension permits it. applications that don't implement or recognize an extension MUST ignore its extension-value, no matter its size or content. applications MUST tolerate any sequence of bytes (including null bytes at any position) in an unknown extension's extension-value. π«Ά
the cumulative size of an SSH_MSG_EXT_INFO message is limited only by the maximum packet length an implementation may apply under [RFC4253]. implementations MUST accept well-formed SSH_MSG_EXT_INFO messages up to the maximum packet length they accept. π
3. Initially Defined Extensions π§
3.1. "server-sig-algs" β¨
Okay bestie, this one is the server telling you which public key algorithms it's willing to deal with π It's giving "here's my guest list" energy π
This extension is sent with the following extension name and value:
string "server-sig-algs"
name-list public-key-algorithms-accepted
The name-list type is a strict subset of the string type, so it's totally allowed as an extension-value π«Ά See [RFC4251] for more information.
The server is the one who sends this extension. It's a list of public key algorithms the server can process as part of a "publickey" authentication request ποΈ If a client sends this extension, the server MAY ignore it and MAY disconnect π
Here's the vibe check: in this extension, a server MUST enumerate all public key algorithms it might accept during user authentication. Ngl though, some early server implementations don't list every algorithm they accept, and those are still out there π So a client MAY send a user authentication request using a public key algorithm that isn't included in server-sig-algs.
A client that wants to do public key authentication MAY wait for the server's SSH_MSG_EXT_INFO. That way it can send a "publickey" request with an appropriate algorithm, instead of guessing and hoping for the best π―
Servers that implement public key authentication SHOULD implement this extension β¨
If a server doesn't send this extension, a client MUST NOT make any assumptions about the server's public key algorithm support, and it MAY proceed with authentication requests using trial and error. Also, implementations are known to exist that apply authentication penalties if the client tries an unexpected public key algorithm π
Authentication penalties are how servers stop brute-force password guessing, username enumeration, and other behavior that the administrators or implementers find sus π¨ Penalties may include automatic IP address throttling or blocking, and they may trigger email alerts or auditing. Very dramatic, very real π
3.2. "delay-compression" πΈ
This extension MAY be sent by both parties, like a group project where everyone gets to contribute π«Ά
string "delay-compression"
string:
name-list compression_algorithms_client_to_server
name-list compression_algorithms_server_to_client
The extension-value is a string that encodes two name-lists, and each name-list is encoded as a string too. For example, if you want to say you prefer "foo,bar" in the client-to-server direction and "bar,baz" in the server-to-client direction, you encode the extension-value like this (length included):
00000016 00000007 666f6f2c626172 00000007 6261722c62617a
Either party can send this exact same encoding, client or server. No favorites here π¦
This extension lets the server and client renegotiate compression algorithm support without doing a full key re-exchange. The new algorithms take effect immediately upon successful authentication, which is so efficient, I'm obsessed π₯
This extension only takes effect if both parties send it. Name-lists MAY include any compression algorithm that could have been negotiated in SSH_MSG_KEXINIT, except algorithms that define their own delayed compression semantics. So "zlib,none" is a valid algorithm list in this context, but "zlib@openssh.com" is not π
ββοΈ
If both parties send this extension but the name-lists don't contain a common algorithm in either direction, the parties MUST disconnect the same way they would if negotiation failed as part of SSH_MSG_KEXINIT. Rough, but that's the rule π
If this extension takes effect, the renegotiated compression algorithm gets activated for the very next SSH message after the trigger message. The trigger message depends on who's sending:
- Sent by the server, the trigger message is SSH_MSG_USERAUTH_SUCCESS.
- Sent by the client, the trigger message is SSH_MSG_NEWCOMPRESS.
If this extension takes effect, the client MUST send the following message within a reasonable number of outgoing SSH messages after receiving SSH_MSG_USERAUTH_SUCCESS. It doesn't have to be the first outgoing message, though π§
byte SSH_MSG_NEWCOMPRESS (value 8)
So why does SSH_MSG_NEWCOMPRESS even exist? It's to avoid a race condition πββοΈ The server can't reliably know whether a message from the client was sent before or after it received SSH_MSG_USERAUTH_SUCCESS. For example, clients may send keep-alive messages during logon processing, and that's where the mess comes from π€·ββοΈ
As is the case for all extensions unless otherwise noted, the server MAY delay including this extension until its secondary SSH_MSG_EXT_INFO, which gets sent before SSH_MSG_USERAUTH_SUCCESS. This lets the server hold off on advertising compression until the client has authenticated π
If the parties renegotiate compression using this extension in a session where compression is already enabled, and the renegotiated algorithm is the same in one or both directions, then the internal compression state MUST be reset for each direction at the time the renegotiated algorithm takes effect. Clean slate, bestie π§Ή
3.2.1. Awkwardly Timed Key Re-Exchange π¬
A party that has signaled, or intends to signal, support for this extension in an SSH session MUST NOT initiate key re-exchange in that session until one of the following happens:
- This extension was negotiated, and the party that's about to start key re-exchange already sent its trigger message for compression.
- The party has sent (if server) or received (if client) the message SSH_MSG_USERAUTH_SUCCESS, and this extension was not negotiated.
If a party breaks this rule, the other party MAY disconnect πͺ
In general, parties SHOULD NOT start key re-exchange before successful user authentication, but they MAY tolerate it if they aren't using this extension π€
3.2.2. Subsequent Re-Exchange π
In subsequent key re-exchanges that unambiguously begin after the compression trigger messages, the compression algorithms negotiated in the re-exchange override the algorithms negotiated with this extension. The newest negotiation wins, iykyk π
3.2.3. Compatibility Note: OpenSSH up to Version 7.5 π«
This extension uses a binary extension-value encoding. OpenSSH clients up to and including version 7.5 advertise support to receive SSH_MSG_EXT_INFO, but they disconnect when they receive an extension-value containing null bytes. This is an error that was fixed in OpenSSH version 7.6 β
Implementations that want to interoperate with OpenSSH 7.5 and earlier are advised to check the remote party's SSH version string, and to omit this extension if an affected version is detected. Affected versions don't implement this extension, so there's no harm in leaving it out π· The extension SHOULD NOT be omitted if the detected OpenSSH version is 7.6 or higher. Leaving it out there would make it harder for the OpenSSH project to implement this extension in a higher version, and nobody wants that π ββοΈ
3.3. "no-flow-control" π¦
This extension is sent with the following extension name and value:
string "no-flow-control"
string choice of: "p" for preferred | "s" for supported
A party SHOULD send "s" if it supports "no-flow-control" but doesn't prefer to enable it. A party SHOULD send "p" if it prefers to enable the extension when the other party supports it too. Parties MAY disconnect if they receive a different extension value π
For this extension to take effect, the following must occur:
- This extension MUST be sent by both parties.
- At least one party MUST have sent the value "p" (preferred).
If this extension takes effect, the "initial window size" fields in SSH_MSG_CHANNEL_OPEN and SSH_MSG_CHANNEL_OPEN_CONFIRMATION, as defined in [RFC4254], become meaningless π«₯ The values of these fields MUST be ignored, and a channel behaves as if all window sizes are infinite. Neither side is required to send any SSH_MSG_CHANNEL_WINDOW_ADJUST messages, and if one is received, it MUST be ignored. Basically, the flow control gets turned off for the vibe π
This extension is intended for (but not limited to) file transfer applications that only use one channel, where the flow control SSH provides is more of an impediment than a feature π
Implementations MUST refuse to open more than one simultaneous channel when this extension is in effect. Nevertheless, server implementations SHOULD support clients opening more than one non-simultaneous channel. Rules are rules, but we still get to be nice π₯°
3.3.1. Prior "No Flow Control" Practice π
Before this extension, some applications just didn't implement SSH flow control. They sent an initial channel window size of 2^32 - 1 instead. Applications SHOULD NOT do this, for these reasons:
- It's plausible to transfer more than 2^32 bytes over a channel. A channel like that will hang if the other party implements SSH flow control according to [RFC4254] π
- Some implementations can't handle large channel window sizes, and they can exhibit non-graceful behaviors, including disconnect π
3.4. "elevation" π‘οΈ
Okay, so "elevation" and "elevated" refer to an operating system mechanism where an administrator's logon session is linked to two security contexts: one limited and one with administrative rights π To "elevate" a session means to activate the security context with full administrative rights. For more info about this mechanism on Windows, check out [WINADMIN] and [WINTOKEN] πͺ
This extension MAY be sent by the client as follows:
string "elevation"
string choice of: "y" | "n" | "d"
A client sends "y" to say it prefers the session to be elevated, "n" to say it doesn't want elevation, and "d" to tell the server to use its default behavior π The server MAY disconnect if it receives a different extension value. If a client doesn't send the "elevation" extension, the server SHOULD act as if "d" was sent.
If a client has included this extension, then after authentication, a server that supports this extension SHOULD tell the client whether elevation was done. It does that by sending this global request:
byte SSH_MSG_GLOBAL_REQUEST
string "elevation"
boolean want reply = false
boolean elevation performed
Clients that implement this extension help reduce the attack surface for Windows servers that handle administrative logins, which is a whole main character move π¦ΈββοΈ Where clients don't support this extension, servers must elevate sessions to allow full access by administrative users always. Where clients do support it, sessions can be created without elevation unless someone requests it π
4. IANA Considerations π
4.1. Additions to Existing Registries ποΈ
IANA has added the following entries to the "Message Numbers" registry [IANA-M], under the "Secure Shell (SSH) Protocol Parameters" registry [RFC4250]:
Value Message ID Reference
-----------------------------------------
7 SSH_MSG_EXT_INFO RFC 8308
8 SSH_MSG_NEWCOMPRESS RFC 8308
IANA has also added the following entries to the "Key Exchange Method Names" registry [IANA-KE]:
Method Name Reference Note
------------------------------------------
ext-info-s RFC 8308 Section 2
ext-info-c RFC 8308 Section 2
4.2. New Registry: Extension Names π
Also under the "Secure Shell (SSH) Protocol Parameters" registry, IANA has created a brand new "Extension Names" registry, with the following initial content. Slay π
Extension Name Reference Note
------------------------------------------------
server-sig-algs RFC 8308 Section 3.1
delay-compression RFC 8308 Section 3.2
no-flow-control RFC 8308 Section 3.3
elevation RFC 8308 Section 3.4
4.2.1. Future Assignments to Extension Names Registry π
okay bestie, looking ahead π names in the "Extension Names" registry MUST follow the naming conventions from [RFC4250], Section 4.6.1. no skipping this one π
if you want a brand-new non-local name (aka one that does not include the '@' character π), it MUST go through the IETF Review policy described in [RFC8126]. that's the vibe check for the registry, and it's giving careful gatekeeping β¨
5. Security Considerations π
okay the security part is SERIOUS bestie ππ security considerations are discussed throughout this whole document, not just in one sneaky corner, so keep your eyes peeled π
this document updates the SSH protocol as defined in [RFC4251] and related documents, so it's literally the SSH protocol getting a glow-up π and the security considerations of [RFC4251] apply. no exceptions, no excuses π
6. References π
6.1. Normative References π
here are the normative references, all of them, no cap π«Ά
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC4250] Lehtinen, S. and C. Lonvick, Ed., "The Secure Shell (SSH)
Protocol Assigned Numbers", RFC 4250,
DOI 10.17487/RFC4250, January 2006,
<https://www.rfc-editor.org/info/rfc4250>.
[RFC4251] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH)
Protocol Architecture", RFC 4251, DOI 10.17487/RFC4251,
January 2006, <https://www.rfc-editor.org/info/rfc4251>.
[RFC4252] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH)
Authentication Protocol", RFC 4252, DOI 10.17487/RFC4252,
January 2006, <https://www.rfc-editor.org/info/rfc4252>.
[RFC4253] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH)
Transport Layer Protocol", RFC 4253, DOI 10.17487/RFC4253,
January 2006, <https://www.rfc-editor.org/info/rfc4253>.
[RFC4254] Ylonen, T. and C. Lonvick, Ed., "The Secure Shell (SSH)
Connection Protocol", RFC 4254, DOI 10.17487/RFC4254,
January 2006, <https://www.rfc-editor.org/info/rfc4254>.
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for
Writing an IANA Considerations Section in RFCs", BCP 26,
RFC 8126, DOI 10.17487/RFC8126, June 2017,
<https://www.rfc-editor.org/info/rfc8126>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
6.2. Informative References π§
and now the informative ones, which are still very much worth your time β¨
[IANA-KE] IANA, "Key Exchange Method Names",
<https://www.iana.org/assignments/ssh-parameters/>.
[IANA-M] IANA, "Message Numbers",
<https://www.iana.org/assignments/ssh-parameters/>.
[RFC8332] Bider, D., "Use of RSA Keys with SHA-256 and SHA-512 in
the Secure Shell (SSH) Protocol", RFC 8332,
DOI 10.17487/RFC8332, March 2018,
<https://www.rfc-editor.org/info/rfc8332>.
[WINADMIN] Microsoft, "How to launch a process as a Full
Administrator when UAC is enabled?", March 2013,
<https://blogs.msdn.microsoft.com/winsdk/2013/03/22/
how-to-launch-a-process-as-a-full-administrator-when-
uac-is-enabled/>.
[WINTOKEN] Microsoft, "TOKEN_ELEVATION_TYPE enumeration",
<https://msdn.microsoft.com/en-us/library/windows/desktop/
bb530718.aspx>.
Acknowledgments π«Ά
huge thank-yous to Markus Friedl and Damien Miller for the comments and the initial implementation π and a big group hug for Peter Gutmann, Roumen Petrov, Mark D. Baushke, Daniel Migault, Eric Rescorla, Matthew A. Miller, Mirja Kuehlewind, Adam Roach, Spencer Dawkins, Alexey Melnikov, and Ben Campbell for the reviews and feedback πΈ you all are literally the reason this is so good πβ¨
Author's Address πΈ
the person behind it all, with contact details right here π¦
Denis Bider
Bitvise Limited
4105 Lombardy Court
Colleyville, TX 76034
United States of America
Email: ietf-ssh3@denisbider.com
URI: https://www.bitvise.com/
π¦ where this page comes from
- ietf: rfc8308 2018-03
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms