| module ietf-netconf-server { |
| yang-version 1.1; |
| namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-server"; |
| prefix ncs; |
| |
| import ietf-yang-types { |
| prefix yang; |
| reference |
| "RFC 6991: Common YANG Data Types"; |
| } |
| |
| import ietf-x509-cert-to-name { |
| prefix x509c2n; |
| reference |
| "RFC 7407: A YANG Data Model for SNMP Configuration"; |
| } |
| |
| import ietf-tcp-client { |
| prefix tcpc; |
| reference |
| "RFC DDDD: YANG Groupings for TCP Clients and TCP Servers"; |
| } |
| |
| import ietf-tcp-server { |
| prefix tcps; |
| reference |
| "RFC DDDD: YANG Groupings for TCP Clients and TCP Servers"; |
| } |
| |
| import ietf-ssh-common { |
| prefix sshcmn; |
| reference |
| "RFC EEEE: YANG Groupings for SSH Clients and SSH Servers"; |
| } |
| |
| import ietf-ssh-server { |
| prefix sshs; |
| reference |
| "RFC EEEE: YANG Groupings for SSH Clients and SSH Servers"; |
| } |
| |
| import ietf-tls-server { |
| prefix tlss; |
| reference |
| "RFC FFFF: YANG Groupings for TLS Clients and TLS Servers"; |
| } |
| |
| organization |
| "IETF NETCONF (Network Configuration) Working Group"; |
| |
| contact |
| "WG Web: https://datatracker.ietf.org/wg/netconf |
| WG List: NETCONF WG list <mailto:netconf@ietf.org> |
| Author: Kent Watsen <mailto:kent+ietf@watsen.net>"; |
| |
| description |
| "This module contains a collection of YANG definitions |
| for configuring NETCONF servers. |
| |
| Copyright (c) 2023 IETF Trust and the persons identified |
| as authors of the code. All rights reserved. |
| |
| Redistribution and use in source and binary forms, with |
| or without modification, is permitted pursuant to, and |
| subject to the license terms contained in, the Revised |
| BSD License set forth in Section 4.c of the IETF Trust's |
| Legal Provisions Relating to IETF Documents |
| (https://trustee.ietf.org/license-info). |
| |
| This version of this YANG module is part of RFC HHHH |
| (https://www.rfc-editor.org/info/rfcHHHH); see the RFC |
| itself for full legal notices. |
| |
| 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 (RFC 2119) |
| (RFC 8174) when, and only when, they appear in all |
| capitals, as shown here."; |
| |
| revision 2023-04-17 { |
| description |
| "Initial version"; |
| reference |
| "RFC HHHH: NETCONF Client and Server Models"; |
| } |
| |
| // Features |
| |
| feature ssh-listen { |
| description |
| "The 'ssh-listen' feature indicates that the NETCONF server |
| supports opening a port to accept NETCONF over SSH |
| client connections."; |
| reference |
| "RFC 6242: |
| Using the NETCONF Protocol over Secure Shell (SSH)"; |
| } |
| |
| feature tls-listen { |
| description |
| "The 'tls-listen' feature indicates that the NETCONF server |
| supports opening a port to accept NETCONF over TLS |
| client connections."; |
| reference |
| "RFC 7589: Using the NETCONF Protocol over Transport |
| Layer Security (TLS) with Mutual X.509 |
| Authentication"; |
| } |
| |
| feature ssh-call-home { |
| description |
| "The 'ssh-call-home' feature indicates that the NETCONF |
| server supports initiating a NETCONF over SSH call |
| home connection to NETCONF clients."; |
| reference |
| "RFC 8071: NETCONF Call Home and RESTCONF Call Home"; |
| } |
| |
| feature tls-call-home { |
| description |
| "The 'tls-call-home' feature indicates that the NETCONF |
| server supports initiating a NETCONF over TLS call |
| home connection to NETCONF clients."; |
| reference |
| "RFC 8071: NETCONF Call Home and RESTCONF Call Home"; |
| } |
| |
| feature central-netconf-server-supported { |
| description |
| "The 'central-netconf-server-supported' feature indicates |
| that the server supports the top-level 'netconf-server' |
| node. |
| |
| This feature is needed as some servers may want to use |
| features defined in this module, which requires this |
| module to be implemented, without having to support |
| the top-level 'netconf-server' node."; |
| } |
| |
| // Groupings |
| |
| grouping netconf-server-grouping { |
| description |
| "A reusable grouping for configuring a NETCONF server |
| without any consideration for how underlying transport |
| sessions are established. |
| |
| Note that this grouping uses a fairly typical descendant |
| node name such that a stack of 'uses' statements will |
| have name conflicts. It is intended that the consuming |
| data model will resolve the issue by wrapping the 'uses' |
| statement in a container called, e.g., |
| 'netconf-server-parameters'. This model purposely does |
| not do this itself so as to provide maximum flexibility |
| to consuming models."; |
| |
| container client-identity-mappings { |
| description |
| "Specifies mappings through which NETCONF client X.509 |
| certificates are used to determine a NETCONF username, |
| per RFC 7407. |
| |
| For TLS-based transports, if no matching and valid |
| cert-to-name list entry can be found, then the NETCONF |
| server MUST close the connection, and MUST NOT accept |
| NETCONF messages over it, per Section 7 in RFC 7589. |
| |
| For SSH-based transports, a matching cert-to-name |
| entry overrides the username provided by the SSH |
| implementation, consistent with the second paragraph |
| of Section 3 in RFC 6242."; |
| reference |
| "RFC 6242: |
| Using the NETCONF Protocol over Secure Shell (SSH) |
| RFC 7589: |
| Using the NETCONF Protocol over Transport Layer |
| Security (TLS) with Mutual X.509 Authentication"; |
| uses x509c2n:cert-to-name { |
| refine "cert-to-name/fingerprint" { |
| mandatory false; |
| description |
| "A 'fingerprint' value does not need to be specified |
| when the 'cert-to-name' mapping is independent of |
| fingerprint matching. A 'cert-to-name' having no |
| fingerprint value will match any client certificate |
| and therefore should only be present at the end of |
| the user-ordered 'cert-to-name' list."; |
| } |
| } |
| } |
| } |
| |
| grouping netconf-server-listen-stack-grouping { |
| description |
| "A reusable grouping for configuring a NETCONF server |
| 'listen' protocol stack for a single connection."; |
| choice transport { |
| mandatory true; |
| description |
| "Selects between available transports."; |
| case ssh { |
| if-feature "ssh-listen"; |
| container ssh { |
| description |
| "SSH-specific listening configuration for inbound |
| connections."; |
| container tcp-server-parameters { |
| description |
| "A wrapper around the TCP client parameters |
| to avoid name collisions."; |
| uses tcps:tcp-server-grouping { |
| refine "local-port" { |
| default "830"; |
| description |
| "The NETCONF server will listen on the |
| IANA-assigned well-known port value |
| for 'netconf-ssh' (830) if no value |
| is specified."; |
| } |
| } |
| } |
| container ssh-server-parameters { |
| description |
| "A wrapper around the SSH server parameters |
| to avoid name collisions."; |
| uses sshs:ssh-server-grouping; |
| } |
| container netconf-server-parameters { |
| description |
| "A wrapper around the NETCONF server parameters |
| to avoid name collisions."; |
| uses ncs:netconf-server-grouping { |
| refine "client-identity-mappings" { |
| if-feature "sshcmn:ssh-x509-certs"; |
| description |
| "Augments in an 'if-feature' statement |
| ensuring the 'client-identity-mappings' |
| descendant is enabled only when SSH |
| supports X.509 certificates."; |
| } |
| augment "client-identity-mappings" { |
| description |
| "Adds a flag indicating if a cert-to-name |
| is required."; |
| leaf mapping-required { |
| type boolean; |
| description |
| "Indicates that the cert-to-name mapping |
| is required (i.e., the SSH-level username |
| is ignored)."; |
| } |
| } |
| } |
| } |
| } |
| } |
| case tls { |
| if-feature "tls-listen"; |
| container tls { |
| description |
| "TLS-specific listening configuration for inbound |
| connections."; |
| container tcp-server-parameters { |
| description |
| "A wrapper around the TCP client parameters |
| to avoid name collisions."; |
| uses tcps:tcp-server-grouping { |
| refine "local-port" { |
| default "6513"; |
| description |
| "The NETCONF server will listen on the |
| IANA-assigned well-known port value |
| for 'netconf-tls' (6513) if no value |
| is specified."; |
| } |
| } |
| } |
| container tls-server-parameters { |
| description |
| "A wrapper around the TLS server parameters to |
| avoid name collisions."; |
| uses tlss:tls-server-grouping { |
| refine "client-authentication" { |
| must 'ca-certs or ee-certs'; |
| description |
| "NETCONF/TLS servers MUST validate client |
| certificates. This configures certificates |
| at the socket-level (i.e. bags), more |
| discriminating client-certificate checks |
| SHOULD be implemented by the application."; |
| reference |
| "RFC 7589: |
| Using the NETCONF Protocol over Transport Layer |
| Security (TLS) with Mutual X.509 Authentication"; |
| } |
| } |
| } |
| container netconf-server-parameters { |
| description |
| "A wrapper around the NETCONF server parameters |
| to avoid name collisions."; |
| uses ncs:netconf-server-grouping { |
| refine "client-identity-mappings/cert-to-name" { |
| min-elements 1; |
| description |
| "The TLS transport requires a mapping."; |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| grouping netconf-server-callhome-stack-grouping { |
| description |
| "A reusable grouping for configuring a NETCONF server |
| 'call-home' protocol stack, for a single connection."; |
| choice transport { |
| mandatory true; |
| description |
| "Selects between available transports."; |
| case ssh { |
| if-feature "ssh-call-home"; |
| container ssh { |
| description |
| "Specifies SSH-specific call-home transport |
| configuration."; |
| container tcp-client-parameters { |
| description |
| "A wrapper around the TCP client parameters |
| to avoid name collisions."; |
| uses tcpc:tcp-client-grouping { |
| refine "remote-port" { |
| default "4334"; |
| description |
| "The NETCONF server will attempt to connect |
| to the IANA-assigned well-known port for |
| 'netconf-ch-ssh' (4334) if no value is |
| specified."; |
| } |
| } |
| } |
| container ssh-server-parameters { |
| description |
| "A wrapper around the SSH server parameters |
| to avoid name collisions."; |
| uses sshs:ssh-server-grouping; |
| } |
| container netconf-server-parameters { |
| description |
| "A wrapper around the NETCONF server parameters |
| to avoid name collisions."; |
| uses ncs:netconf-server-grouping { |
| refine "client-identity-mappings" { |
| if-feature "sshcmn:ssh-x509-certs"; |
| description |
| "Augments in an 'if-feature' statement |
| ensuring the 'client-identity-mappings' |
| descendant is enabled only when SSH |
| supports X.509 certificates."; |
| } |
| augment "client-identity-mappings" { |
| description |
| "Adds a flag indicating if a cert-to-name |
| is required."; |
| leaf mapping-required { |
| type boolean; |
| description |
| "Indicates that the cert-to-name mapping |
| is required (i.e., the SSH-level username |
| is ignored)."; |
| } |
| } |
| } |
| } |
| } |
| } |
| case tls { |
| if-feature "tls-call-home"; |
| container tls { |
| description |
| "Specifies TLS-specific call-home transport |
| configuration."; |
| container tcp-client-parameters { |
| description |
| "A wrapper around the TCP client parameters |
| to avoid name collisions."; |
| uses tcpc:tcp-client-grouping { |
| refine "remote-port" { |
| default "4335"; |
| description |
| "The NETCONF server will attempt to connect |
| to the IANA-assigned well-known port for |
| 'netconf-ch-tls' (4335) if no value is |
| specified."; |
| } |
| } |
| } |
| container tls-server-parameters { |
| description |
| "A wrapper around the TLS server parameters to |
| avoid name collisions."; |
| uses tlss:tls-server-grouping { |
| refine "client-authentication" { |
| must 'ca-certs or ee-certs'; |
| description |
| "NETCONF/TLS servers MUST validate client |
| certificates. This configures certificates |
| at the socket-level (i.e. bags), more |
| discriminating client-certificate checks |
| SHOULD be implemented by the application."; |
| reference |
| "RFC 7589: |
| Using the NETCONF Protocol over Transport Layer |
| Security (TLS) with Mutual X.509 Authentication"; |
| } |
| } |
| } |
| container netconf-server-parameters { |
| description |
| "A wrapper around the NETCONF server parameters |
| to avoid name collisions."; |
| uses ncs:netconf-server-grouping { |
| refine "client-identity-mappings/cert-to-name" { |
| min-elements 1; |
| description |
| "The TLS transport requires a mapping."; |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| grouping netconf-server-app-grouping { |
| description |
| "A reusable grouping for configuring a NETCONF server |
| application that supports both 'listen' and 'call-home' |
| protocol stacks for a multiplicity of connections."; |
| container listen { |
| if-feature "ssh-listen or tls-listen"; |
| presence |
| "Indicates that server-listening ports have been configured. |
| This statement is present so the mandatory descendant |
| nodes do not imply that this node must be configured."; |
| description |
| "Configures listen behavior"; |
| leaf idle-timeout { |
| type uint16; |
| units "seconds"; |
| default "180"; // three minutes |
| description |
| "Specifies the maximum number of seconds that a NETCONF |
| session may remain idle. A NETCONF session will be |
| dropped if it is idle for an interval longer than this |
| number of seconds. If set to zero, then the server |
| will never drop a session because it is idle."; |
| } |
| list endpoint { |
| key "name"; |
| min-elements 1; |
| description |
| "List of endpoints to listen for NETCONF connections."; |
| leaf name { |
| type string; |
| description |
| "An arbitrary name for the NETCONF listen endpoint."; |
| } |
| uses netconf-server-listen-stack-grouping; |
| } |
| } |
| container call-home { |
| if-feature "ssh-call-home or tls-call-home"; |
| presence |
| "Indicates that server-initiated call home connections have |
| been configured. This statement is present so the mandatory |
| descendant nodes do not imply that this node must be |
| configured."; |
| description |
| "Configures the NETCONF server to initiate the underlying |
| transport connection to NETCONF clients."; |
| list netconf-client { |
| key "name"; |
| min-elements 1; |
| description |
| "List of NETCONF clients the NETCONF server is to |
| maintain simultaneous call-home connections with."; |
| leaf name { |
| type string; |
| description |
| "An arbitrary name for the remote NETCONF client."; |
| } |
| container endpoints { |
| description |
| "Container for the list of endpoints."; |
| list endpoint { |
| key "name"; |
| min-elements 1; |
| ordered-by user; |
| description |
| "A non-empty user-ordered list of endpoints for this |
| NETCONF server to try to connect to in sequence. |
| Defining more than one enables high-availability."; |
| leaf name { |
| type string; |
| description |
| "An arbitrary name for this endpoint."; |
| } |
| uses netconf-server-callhome-stack-grouping; |
| } |
| } |
| container connection-type { |
| description |
| "Indicates the NETCONF server's preference for how the |
| NETCONF connection is maintained."; |
| choice connection-type { |
| mandatory true; |
| description |
| "Selects between available connection types."; |
| case persistent-connection { |
| container persistent { |
| presence |
| "Indicates that a persistent connection is to be |
| maintained."; |
| description |
| "Maintain a persistent connection to the NETCONF |
| client. If the connection goes down, immediately |
| start trying to reconnect to the NETCONF client, |
| using the reconnection strategy. |
| |
| This connection type minimizes any NETCONF client |
| to NETCONF server data-transfer delay, albeit at |
| the expense of holding resources longer."; |
| } |
| } |
| case periodic-connection { |
| container periodic { |
| presence "Indicates that a periodic connection is |
| to be maintained."; |
| description |
| "Periodically connect to the NETCONF client. |
| |
| This connection type decreases resource |
| utilization, albeit with increased delay in |
| NETCONF client to NETCONF server interactions. |
| |
| The NETCONF client SHOULD gracefully close the |
| connection using <close-session> upon completing |
| planned activities. If the NETCONF session is |
| not closed gracefully, the NETCONF server MUST |
| immediately attempt to reestablish the connection. |
| |
| Connections are established at the same start |
| time regardless how long the previous connection |
| stayed open. |
| |
| In the case that the previous connection is still |
| active (i.e., the NETCONF client has not closed |
| it yet), establishing a new connection is NOT |
| RECOMMENDED."; |
| leaf period { |
| type uint16; |
| units "minutes"; |
| default "60"; |
| description |
| "Duration of time between periodic connections."; |
| } |
| leaf anchor-time { |
| type yang:date-and-time { |
| // constrained to minute-level granularity |
| pattern '[0-9]{4}-(1[0-2]|0[1-9])-(0[1-9]|[1-2]' |
| + '[0-9]|3[0-1])T(0[0-9]|1[0-9]|2[0-3]):[' |
| + '0-5][0-9]:00(Z|[\+\-]((1[0-3]|0[0-9]):' |
| + '([0-5][0-9])|14:00))?'; |
| } |
| description |
| "Designates a timestamp before or after which a |
| series of periodic connections are determined. |
| The periodic connections occur at a whole |
| multiple interval from the anchor time. |
| |
| If an 'anchor-time' is not provided, then the |
| server may implicitly set it to the time when |
| this configuraton is applied (e.g., on boot). |
| |
| For example, for an anchor time is 15 minutes |
| past midnight and a period interval of 24 hours, |
| then a periodic connection will occur 15 minutes |
| past midnight everyday."; |
| } |
| leaf idle-timeout { |
| type uint16; |
| units "seconds"; |
| default "180"; // three minutes |
| description |
| "Specifies the maximum number of seconds that |
| a NETCONF session may remain idle. A NETCONF |
| session will be dropped if it is idle for an |
| interval longer than this number of seconds. |
| If set to zero, then the server will never |
| drop a session because it is idle."; |
| } |
| } |
| } // case periodic-connection |
| } // choice connection-type |
| } // container connection-type |
| container reconnect-strategy { |
| description |
| "The reconnection strategy directs how a NETCONF server |
| reconnects to a NETCONF client, after discovering its |
| connection to the client has dropped, even if due to a |
| reboot. The NETCONF server starts with the specified |
| endpoint and tries to connect to it max-attempts times |
| before trying the next endpoint in the list (round |
| robin)."; |
| leaf start-with { |
| type enumeration { |
| enum first-listed { |
| description |
| "Indicates that reconnections should start with |
| the first endpoint listed."; |
| } |
| enum last-connected { |
| description |
| "Indicates that reconnections should start with |
| the endpoint last connected to. If no previous |
| connection has ever been established, then the |
| first endpoint configured is used. NETCONF |
| servers SHOULD be able to remember the last |
| endpoint connected to across reboots."; |
| } |
| enum random-selection { |
| description |
| "Indicates that reconnections should start with |
| a random endpoint."; |
| } |
| } |
| default "first-listed"; |
| description |
| "Specifies which of the NETCONF client's endpoints |
| the NETCONF server should start with when trying |
| to connect to the NETCONF client."; |
| } |
| leaf max-wait { |
| type uint16 { |
| range "1..max"; |
| } |
| units "seconds"; |
| default "5"; |
| description |
| "Specifies the amount of time in seconds after which, |
| if the connection is not established, an endpoint |
| connection attempt is considered unsuccessful."; |
| } |
| leaf max-attempts { |
| type uint8 { |
| range "1..max"; |
| } |
| default "3"; |
| description |
| "Specifies the number times the NETCONF server tries |
| to connect to a specific endpoint before moving on |
| to the next endpoint in the list (round robin)."; |
| } |
| } // container reconnect-strategy |
| } // list netconf-client |
| } // container call-home |
| } // grouping netconf-server-app-grouping |
| |
| // Protocol accessible node for servers that implement this module. |
| container netconf-server { |
| if-feature central-netconf-server-supported; |
| uses netconf-server-app-grouping; |
| description |
| "Top-level container for NETCONF server configuration."; |
| } |
| } |