RFC 6242

Using the NETCONF Protocol over Secure Shell (SSH)

πŸ“… published June 2011, from ietf

RFC 6242: Using the NETCONF Protocol over Secure Shell (SSH) ✨

Okay bestie, so this is RFC 6242 πŸŽ€, written by M. Wasserman over at Painless Security, LLC, and dated June 2011. It's a Standards Track doc, which means it's the real deal πŸ‘‘. It obsoletes RFC 4742, so if you're still reading that one, it's time to switch πŸ’…. It's part of the IETF stream and carries ISSN 2070-1721.

Abstract πŸ’œ

So the big idea is this: the doc explains how to run NETCONF (the Network Configuration Protocol) inside an SSH session, as an SSH subsystem. It also says it obsoletes RFC 4742. Iconic ✨

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's had public review, and the Internet Engineering Steering Group (IESG) approved it for publication. If you want more on Internet Standards, check out Section 2 of RFC 5741 🧚.

For the latest status, errata, and how to send feedback, head to http://www.rfc-editor.org/info/rfc6242 πŸ¦‹.

The copyright line reads Copyright (c) 2011 IETF Trust and the persons identified as the document authors. All rights reserved. So the IETF Trust and the authors own it, and all rights are reserved πŸ”’.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, which you can find at http://trustee.ietf.org/license-info as they stood on the publication date. Please read those carefully, because they spell out your rights and restrictions for this doc πŸ™ˆ. Any Code Components pulled out of this document need to include Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions. They come with no warranty, as the Simplified BSD License describes.

Table of Contents πŸ—‚οΈ

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  2
2.  Requirements Terminology . . . . . . . . . . . . . . . . . . .  2
3.  Starting NETCONF over SSH  . . . . . . . . . . . . . . . . . .  2
  3.1.  Capabilities Exchange  . . . . . . . . . . . . . . . . . .  3
4.  Using NETCONF over SSH . . . . . . . . . . . . . . . . . . . .  4
  4.1.  Framing Protocol . . . . . . . . . . . . . . . . . . . . .  5
  4.2.  Chunked Framing Mechanism  . . . . . . . . . . . . . . . .  5
  4.3.  End-of-Message Framing Mechanism . . . . . . . . . . . . .  7
5.  Exiting the NETCONF Subsystem  . . . . . . . . . . . . . . . .  8
6.  Security Considerations  . . . . . . . . . . . . . . . . . . .  8
7.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . .  9
8.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 10
9.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 10
  9.1.  Normative References . . . . . . . . . . . . . . . . . . . 10
  9.2.  Informative References . . . . . . . . . . . . . . . . . . 10
Appendix A.  Changes from RFC 4742 . . . . . . . . . . . . . . . . 11

1. Introduction 🌸

Okay so NETCONF [RFC6241] is an XML-based protocol that's used to manage the configuration of networking equipment 🧚. It's designed to be session-layer and transport independent, which is the whole point, because it lets people define mappings for lots of different session-layer or transport protocols πŸ¦‹.

This document is the one that defines how NETCONF runs inside a Secure Shell (SSH) session. It uses the SSH connection protocol [RFC4254] on top of the SSH transport protocol [RFC4253]. This mapping lets a user or an application run NETCONF from a secure shell session, which is giving secure and sleek ✨.

Now, the document gives specific examples of how NETCONF messages get sent over an SSH connection. But you're not stuck with just those messages. This transport works for any NETCONF message πŸ’….

2. Requirements Terminology πŸ“š

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 RFC 2119 [RFC2119] 🫢.

3. Starting NETCONF over SSH πŸš€

Alright, so to run NETCONF over SSH, the SSH client first sets up an SSH transport connection using the SSH transport protocol. The SSH client and SSH server then swap keys for message integrity and encryption πŸ”. Next, the SSH client invokes the "ssh-userauth" service to authenticate the user, as covered in the SSH authentication protocol [RFC4252]. Once the user is successfully authenticated, the SSH client invokes the "ssh-connection" service, which is also known as the SSH connection protocol πŸ’œ.

The username that the SSH implementation provides goes to the NETCONF message layer as the NETCONF username, with no changes at all πŸ™ˆ. Now, if the username doesn't follow the NETCONF requirements on usernames [RFC6241], meaning it can't be represented in XML, then the SSH session MUST be dropped πŸ’€. And any transformations the SSH server applies to the authenticated identity of the SSH client (like through authentication services or mappings to system accounts) are outside the scope of this document 🧚.

After the ssh-connection service is up, the SSH client opens a channel of type "session", and that gives you an SSH session πŸŽ€.

Once the SSH session is established, the NETCONF client invokes NETCONF as an SSH subsystem called "netconf". Subsystem support is a feature of SSH version 2 (SSHv2) and is not included in SSHv1 ⚠️. Running NETCONF as a subsystem means the script doesn't have to recognize shell prompts or skip over extra stuff, like a system message that pops up at shell start-up πŸ™Œ.

Here's the firewall part, and it's a big deal πŸ”₯. So NETCONF traffic is easy to spot and filter for firewalls and other network devices, NETCONF servers MUST default to providing access to the "netconf" SSH subsystem only when the SSH session is established using the IANA-assigned TCP port 830. Servers SHOULD be configurable to allow access to the netconf SSH subsystem over other ports πŸ¦‹.

A user (or application) could use this command line to invoke NETCONF as an SSH subsystem on the IANA-assigned port:

[user@client]$ ssh -s server.example.org -p 830 netconf

Quick note: the -s option is what makes the command ("netconf") run as an SSH subsystem πŸ’–.

3.1. Capabilities Exchange πŸŽ€

As [RFC6241] specifies, the NETCONF server shows off its capabilities by sending an XML document with a <hello> element as soon as the NETCONF session is established πŸ‘‘. The NETCONF client can parse that message to figure out which NETCONF capabilities the server supports 🧐.

As [RFC6241] says, the NETCONF client also sends its own XML document with a <hello> element, to tell the server what its capabilities are πŸ’…. That document is the first XML document the NETCONF client sends after the NETCONF session is established.

Here's an example of a capability exchange. Data sent by the NETCONF client is marked with "C:", and data sent by the NETCONF server is marked with "S:" 🌈.

S: <?xml version="1.0" encoding="UTF-8"?>
S: <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
S:   <capabilities>
S:     <capability>
S:       urn:ietf:params:netconf:base:1.1
S:     </capability>
S:     <capability>
S:       urn:ietf:params:ns:netconf:capability:startup:1.0
S:     </capability>
S:   </capabilities>
S:   <session-id>4</session-id>
S: </hello>
S: ]]>]]>

C: <?xml version="1.0" encoding="UTF-8"?>
C: <hello xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
C:   <capabilities>
C:     <capability>
C:       urn:ietf:params:netconf:base:1.1
C:     </capability>
C:   </capabilities>
C: </hello>
C: ]]>]]>

The example has the server sending its <hello> message first, then the client's <hello>. But honestly, both sides send their messages as soon as the NETCONF subsystem is initialized, and they might even do it at the same time πŸ™ƒ.

4. Using NETCONF over SSH 🧚

So a NETCONF over SSH session is basically a NETCONF client and a NETCONF server swapping complete XML documents πŸ’œ. Once the session is established and capabilities have been exchanged, the NETCONF client sends complete XML documents containing <rpc> elements to the server. The server answers with complete XML documents containing <rpc-reply> elements πŸ’Œ.

4.1. Framing Protocol 🧩

Okay, plot twist. The previous version of this document defined the character sequence ]]>]]> as a message separator. It was based on the assumption that this sequence couldn't show up in well-formed XML documents. But that assumption is wrong 😭. It can legally show up in XML attributes, comments, and processing instructions.

So to fix this, and still play nice with existing implementations, this document defines the following framing protocol πŸ› οΈ.

The <hello> message MUST be followed by the character sequence ]]>]]>. When the receiving peer's SSH Transport layer gets the <hello> message, it conceptually passes it up to the Messages layer πŸ¦‹. If both peers advertise the :base:1.1 capability, then the chunked framing mechanism (see Section 4.2) gets used for the rest of the NETCONF session. Otherwise, the old end-of-message-based mechanism (see Section 4.3) is used 🌸.

4.2. Chunked Framing Mechanism πŸŽ€

okay so this is the chunked framing mechanism and it is GIVING πŸ“ Every NETCONF message gets wrapped in chunks, and the format is written as an ABNF [RFC5234] rule called Chunked-Message, so here's the whole thing:

Chunked-Message = 1*chunk
                  end-of-chunks

chunk           = LF HASH chunk-size LF
                  chunk-data
chunk-size      = 1*DIGIT1 0*DIGIT
chunk-data      = 1*OCTET

end-of-chunks   = LF HASH HASH LF

DIGIT1          = %x31-39
DIGIT           = %x30-39
HASH            = %x23
LF              = %x0A
OCTET           = %x00-FF

The chunk-size field is a string of decimal digits that tells you how many octets are in chunk-data. Leading zeros are prohibited πŸ™…β€β™€οΈ, and the biggest allowed chunk-size value is 4294967295 πŸ’….

As an example, say we have this message:

<rpc message-id="102"
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <close-session/>
</rpc>

It could be encoded like this (using '\n' as a visible way to show the LineFeed character) ✨:

C:  \n#4\n
C:  <rpc
C:  \n#18\n
C:   message-id="102"\n
C:  \n#79\n
C:       xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">\n
C:    <close-session/>\n
C:  </rpc>
C:  \n##\n

Conceptually, the SSH Transport layer encodes the messages that come from the Messages layer, and it decodes the messages it receives on the SSH channel before handing them off to the Messages layer πŸ¦‹.

The examples for this mechanism show every LineFeed, even the ones that aren't part of the framing. The SSH transport doesn't interpret the XML content, so it doesn't care about any optional XML-specific LineFeeds πŸ€·β€β™€οΈ.

In the second and third chunks above, each line ends with a LineFeed. For all the XML lines (except the last one), the example treats that LineFeed as part of the chunk-data, so it counts toward the chunk-size πŸ”’.

Also, there is no LineFeed after the </rpc> end tag in this message. The LineFeed that the start of the end-of-chunks block needs comes right after the last > character in the message 🫢.

If the chunk-size and the chunk-size value are invalid, or if an error happens while decoding, the peer MUST terminate the NETCONF session by closing the corresponding SSH channel 🚫. Implementations MUST ensure they are not vulnerable to a buffer overrun πŸ”₯.

4.3. End-of-Message Framing Mechanism 🌸

this one is the old-school backwards compatibility mechanism πŸ§“ It's only used when the remote peer doesn't advertise a base protocol version that supports chunked encoding. In other words, it's for a NETCONF implementation that only supports :base:1.0.

When this mechanism is used, the special character sequence ]]>]]>, MUST be sent by both the NETCONF client and the NETCONF server after each message (XML document) in the NETCONF exchange πŸ“¨. Conceptually, the SSH Transport layer passes any data found between the ]]>]]> characters to the Messages layer.

Here's what a NETCONF over SSH session using this backwards-compatible end-of-message framing might look like when it's grabbing a set of configuration info πŸ‘€:

C: <?xml version="1.0" encoding="UTF-8"?>
C: <rpc message-id="105"
C: xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
C:   <get-config>
C:     <source><running/></source>
C:     <config xmlns="http://example.com/schema/1.2/config">
C:      <users/>
C:     </config>
C:   </get-config>
C: </rpc>
C: ]]>]]>

S: <?xml version="1.0" encoding="UTF-8"?>
S: <rpc-reply message-id="105"
S: xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
S:   <config xmlns="http://example.com/schema/1.2/config">
S:     <users>
S:       <user><name>root</name><type>superuser</type></user>
S:       <user><name>fred</name><type>admin</type></user>
S:       <user><name>barney</name><type>admin</type></user>
S:     </users>
S:   </config>
S: </rpc-reply>
S: ]]>]]>

5. Exiting the NETCONF Subsystem πŸ‘‹

Leaving NETCONF is done with the <close-session> operation πŸšͺ. A NETCONF server processes NETCONF messages from the NETCONF client in the order they arrive. When the NETCONF server processes a <close-session> operation, the NETCONF server SHALL respond and close the SSH session channel πŸ’Œ. The NETCONF server MUST NOT process any NETCONF messages received after the <close-session> operation πŸ›‘.

To keep going with the example from Section 4.2, an existing NETCONF subsystem session could be closed like this:

C: \n#140\n
C: <?xml version="1.0" encoding="UTF-8"?>\n
C: <rpc message-id="106"\n
C:      xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">\n
C:   <close-session/>\n
C: </rpc>
C: \n##\n

S: \n#139\n
S: <?xml version="1.0" encoding="UTF-8"?>\n
S: <rpc-reply id="106"\n
S:            xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">\n
S:   <ok/>\n
S: </rpc-reply>
S: \n##\n

6. Security Considerations πŸ”

this section is SERIOUS, bestie πŸ˜­πŸ” NETCONF is used to access configuration and state information and to change configuration information. So the ability to reach this protocol should be limited to users and systems that are authorized to view the NETCONF server's configuration and state, or to modify the NETCONF server's configuration 🧐.

The identity of the SSH server MUST be verified and authenticated by the SSH client according to local policy before any password-based authentication data, or any configuration or state data, is sent to or received from the SSH server πŸ•΅οΈβ€β™€οΈ. The identity of the SSH client MUST also be verified and authenticated by the SSH server according to local policy, so the incoming SSH client request is legit before any configuration or state data is sent to or received from the SSH client βœ…. Neither side should establish a NETCONF over SSH connection with an unknown, unexpected, or incorrect identity on the other side 🚨.

Configuration or state data may include sensitive information, like usernames or security keys πŸ”‘. So NETCONF needs communication channels that provide strong encryption for data privacy πŸ”’. This document defines a NETCONF over SSH mapping that supports strong encryption and authentication πŸ’œ.

This document requires that SSH servers default to allowing access to the "netconf" SSH subsystem only when using a specific TCP port assigned by IANA for this purpose. This makes NETCONF over SSH traffic easy to identify and filter for firewalls and other network nodes 🧱. However, it also makes NETCONF over SSH traffic easier for attackers to identify πŸ‘Ύ.

This document also recommends that SSH servers be configurable to allow access to the "netconf" SSH subsystem over other ports. Using that option without matching changes to firewall or network device configuration may accidentally let nodes outside the firewall or other administrative boundaries gain access to the "netconf" SSH subsystem 😱.

RFC 4742 assumed that the end-of-message (EOM) sequence, ]]>]]>, cannot appear in any well-formed XML document, and that turned out to be mistaken πŸ™ˆ. The EOM sequence can cause operational problems and open the door to attacks if it's sent on purpose in RPC messages. It is, however, believed that the associated threat is not very high 🀞. This document still uses the EOM sequence for the initial <hello> message, to avoid incompatibility with existing implementations 🫠. When both peers implement the base:1.1 capability, a proper framing protocol (the chunked framing mechanism; see Section 4.2) is used for the rest of the NETCONF session, to avoid injection attacks πŸ›‘οΈβœ¨.

7. IANA Considerations πŸ“‹

Based on the previous version of this document, RFC 4742, IANA assigned TCP port 830 as the default port for NETCONF over SSH sessions πŸ”Œ.

IANA had also assigned "netconf" as an SSH Subsystem Name, as defined in [RFC4250], like this:

           Subsystem Name                  Reference
           --------------                  ---------
           netconf                         RFC 4742

IANA updated these allocations to refer to this document πŸŽ‰.

8. Acknowledgements 🫢

Ted Goddard was a co-author on earlier versions of this document πŸ’–.

This document was written using the xml2rfc tool described in RFC 2629 [RFC2629] πŸ› οΈ.

Extensive input came from the other members of the NETCONF design team, including: Andy Bierman, Weijing Chen, Rob Enns, Wes Hardaker, David Harrington, Eliot Lear, Simon Leinen, Phil Shafer, Juergen Schoenwaelder, and Steve Waldbusser 🌟. The following people also reviewed this document and gave valuable input: Olafur Gudmundsson, Sam Hartman, Scott Hollenbeck, Bill Sommerfeld, Balazs Lengyel, Bert Wijnen, Mehmet Ersue, Martin Bjorklund, Lada Lothka, Kent Watsen, and Tom Petch πŸ‘‘.

9. References πŸ“š

9.1. Normative References

  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC4250] Lehtinen, S. and C. Lonvick, "The Secure Shell (SSH) Protocol Assigned Numbers", RFC 4250, January 2006.
  • [RFC4252] Ylonen, T. and C. Lonvick, "The Secure Shell (SSH) Authentication Protocol", RFC 4252, January 2006.
  • [RFC4253] Ylonen, T. and C. Lonvick, "The Secure Shell (SSH) Transport Layer Protocol", RFC 4253, January 2006.
  • [RFC4254] Ylonen, T. and C. Lonvick, "The Secure Shell (SSH) Connection Protocol", RFC 4254, January 2006.
  • [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, January 2008.
  • [RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., "Network Configuration Protocol (NETCONF)", RFC 6241, June 2011.

9.2. Informative References

  • [RFC2629] Rose, M., "Writing I-Ds and RFCs using XML", RFC 2629, June 1999.

Appendix A. Changes from RFC 4742 πŸ¦‹

This section lists the major changes between this document and RFC 4742 πŸ’….

  • Introduced the new chunked framing mechanism to solve known security issues with the EOM framing πŸ”₯.
  • Extended the text in Security Considerations and added text on EOM issues πŸ”.
  • Added examples to show the new chunked encoding properly, and highlighted the location of new lines 🌈.
  • Added text for NETCONF username handling, following the requirements on usernames in [RFC6241] πŸ§‘β€πŸ’».
  • Changed the use of the terms "client/server" and "manager/agent" to "SSH client/server" and "NETCONF client/server" πŸŽ€.
  • Consistently used the term "operation", instead of "command" or "message" ✨.
  • Integrated errata verified for RFC 4742 as of the date of publication of this document. See errata for RFC 4742 at http://www.rfc-editor.org 🧚.

Author's Address πŸ’Œ

Margaret Wasserman Painless Security, LLC 356 Abbott Street North Andover, MA 01845 USA

Phone: +1 781 405-7464 EMail: mrw@painless-security.com URI: http://www.painless-security.com

and that's a wrap, bestie πŸŒˆπŸ’–βœ¨

πŸ“¦ where this page comes from