roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 1 | module ietf-ssh-server { |
| 2 | yang-version 1.1; |
| 3 | namespace "urn:ietf:params:xml:ns:yang:ietf-ssh-server"; |
| 4 | prefix sshs; |
| 5 | |
| 6 | import iana-crypt-hash { |
| 7 | prefix ianach; |
| 8 | reference |
| 9 | "RFC 7317: A YANG Data Model for System Management"; |
| 10 | } |
| 11 | |
| 12 | import ietf-netconf-acm { |
| 13 | prefix nacm; |
| 14 | reference |
| 15 | "RFC 8341: Network Configuration Access Control Model"; |
| 16 | } |
| 17 | |
| 18 | import ietf-crypto-types { |
| 19 | prefix ct; |
| 20 | reference |
| 21 | "RFC AAAA: YANG Data Types and Groupings for Cryptography"; |
| 22 | } |
| 23 | |
| 24 | import ietf-truststore { |
| 25 | prefix ts; |
| 26 | reference |
| 27 | "RFC BBBB: A YANG Data Model for a Truststore"; |
| 28 | } |
| 29 | |
| 30 | import ietf-keystore { |
| 31 | prefix ks; |
| 32 | reference |
| 33 | "RFC CCCC: A YANG Data Model for a Keystore"; |
| 34 | } |
| 35 | |
| 36 | import ietf-ssh-common { |
| 37 | prefix sshcmn; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 38 | reference |
| 39 | "RFC EEEE: YANG Groupings for SSH Clients and SSH Servers"; |
| 40 | } |
| 41 | |
| 42 | organization |
| 43 | "IETF NETCONF (Network Configuration) Working Group"; |
| 44 | |
| 45 | contact |
| 46 | "WG Web: https://datatracker.ietf.org/wg/netconf |
| 47 | WG List: NETCONF WG list <mailto:netconf@ietf.org> |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 48 | Author: Kent Watsen <mailto:kent+ietf@watsen.net>"; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 49 | |
| 50 | description |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 51 | "This module defines a reusable grouping for SSH servers that |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 52 | can be used as a basis for specific SSH server instances. |
| 53 | |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 54 | Copyright (c) 2023 IETF Trust and the persons identified |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 55 | as authors of the code. All rights reserved. |
| 56 | |
| 57 | Redistribution and use in source and binary forms, with |
| 58 | or without modification, is permitted pursuant to, and |
| 59 | subject to the license terms contained in, the Revised |
| 60 | BSD License set forth in Section 4.c of the IETF Trust's |
| 61 | Legal Provisions Relating to IETF Documents |
| 62 | (https://trustee.ietf.org/license-info). |
| 63 | |
| 64 | This version of this YANG module is part of RFC EEEE |
| 65 | (https://www.rfc-editor.org/info/rfcEEEE); see the RFC |
| 66 | itself for full legal notices. |
| 67 | |
| 68 | The key words 'MUST', 'MUST NOT', 'REQUIRED', 'SHALL', |
| 69 | 'SHALL NOT', 'SHOULD', 'SHOULD NOT', 'RECOMMENDED', |
| 70 | 'NOT RECOMMENDED', 'MAY', and 'OPTIONAL' in this document |
| 71 | are to be interpreted as described in BCP 14 (RFC 2119) |
| 72 | (RFC 8174) when, and only when, they appear in all |
| 73 | capitals, as shown here."; |
| 74 | |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 75 | revision 2023-04-17 { |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 76 | description |
| 77 | "Initial version"; |
| 78 | reference |
| 79 | "RFC EEEE: YANG Groupings for SSH Clients and SSH Servers"; |
| 80 | } |
| 81 | |
| 82 | // Features |
| 83 | |
| 84 | feature ssh-server-keepalives { |
| 85 | description |
| 86 | "Per socket SSH keepalive parameters are configurable for |
| 87 | SSH servers on the server implementing this feature."; |
| 88 | } |
| 89 | |
| 90 | feature local-users-supported { |
| 91 | description |
| 92 | "Indicates that the configuration for users can be |
| 93 | configured herein, as opposed to in an application |
| 94 | specific location."; |
| 95 | } |
| 96 | |
| 97 | feature local-user-auth-publickey { |
| 98 | if-feature "local-users-supported"; |
| 99 | description |
| 100 | "Indicates that the 'publickey' authentication type, |
| 101 | per RFC 4252, is supported for locally-defined users. |
| 102 | |
| 103 | The 'publickey' authentication type is required by |
| 104 | RFC 4252, but common implementations enable it to |
| 105 | be disabled."; |
| 106 | reference |
| 107 | "RFC 4252: |
| 108 | The Secure Shell (SSH) Authentication Protocol"; |
| 109 | } |
| 110 | |
| 111 | feature local-user-auth-password { |
| 112 | if-feature "local-users-supported"; |
| 113 | description |
| 114 | "Indicates that the 'password' authentication type, |
| 115 | per RFC 4252, is supported for locally-defined users."; |
| 116 | reference |
| 117 | "RFC 4252: |
| 118 | The Secure Shell (SSH) Authentication Protocol"; |
| 119 | } |
| 120 | |
| 121 | feature local-user-auth-hostbased { |
| 122 | if-feature "local-users-supported"; |
| 123 | description |
| 124 | "Indicates that the 'hostbased' authentication type, |
| 125 | per RFC 4252, is supported for locally-defined users."; |
| 126 | reference |
| 127 | "RFC 4252: |
| 128 | The Secure Shell (SSH) Authentication Protocol"; |
| 129 | } |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 130 | feature local-user-auth-none { |
| 131 | if-feature "local-users-supported"; |
| 132 | description |
| 133 | "Indicates that the 'none' authentication type, per |
| 134 | RFC 4252, is supported. It is NOT RECOMMENDED to |
| 135 | enable this feature."; |
| 136 | reference |
| 137 | "RFC 4252: |
| 138 | The Secure Shell (SSH) Authentication Protocol"; |
| 139 | } |
| 140 | |
| 141 | // Groupings |
| 142 | |
| 143 | grouping ssh-server-grouping { |
| 144 | description |
| 145 | "A reusable grouping for configuring a SSH server without |
| 146 | any consideration for how underlying TCP sessions are |
| 147 | established. |
| 148 | |
| 149 | Note that this grouping uses fairly typical descendant |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 150 | node names such that a nesting of 'uses' statements will |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 151 | have name conflicts. It is intended that the consuming |
| 152 | data model will resolve the issue (e.g., by wrapping |
| 153 | the 'uses' statement in a container called |
| 154 | 'ssh-server-parameters'). This model purposely does |
| 155 | not do this itself so as to provide maximum flexibility |
| 156 | to consuming models."; |
| 157 | |
| 158 | container server-identity { |
| 159 | nacm:default-deny-write; |
| 160 | description |
| 161 | "The list of host keys the SSH server will present when |
| 162 | establishing a SSH connection."; |
| 163 | list host-key { |
| 164 | key "name"; |
| 165 | min-elements 1; |
| 166 | ordered-by user; |
| 167 | description |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 168 | "An ordered list of host keys (see RFC 4251) the SSH |
| 169 | server will use to construct its ordered list of |
| 170 | algorithms, when sending its SSH_MSG_KEXINIT message, |
| 171 | as defined in Section 7.1 of RFC 4253."; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 172 | reference |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 173 | "RFC 4251: The Secure Shell (SSH) Protocol Architecture |
| 174 | RFC 4253: The Secure Shell (SSH) Transport Layer |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 175 | Protocol"; |
| 176 | leaf name { |
| 177 | type string; |
| 178 | description |
| 179 | "An arbitrary name for this host key"; |
| 180 | } |
| 181 | choice host-key-type { |
| 182 | mandatory true; |
| 183 | description |
| 184 | "The type of host key being specified"; |
| 185 | container public-key { |
| 186 | description |
| 187 | "A locally-defined or referenced asymmetric key pair |
| 188 | to be used for the SSH server's host key."; |
| 189 | reference |
| 190 | "RFC CCCC: A YANG Data Model for a Keystore"; |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 191 | uses ks:inline-or-keystore-asymmetric-key-grouping { |
| 192 | refine "inline-or-keystore/inline/inline-definition" { |
| 193 | must 'derived-from-or-self(public-key-format,' |
| 194 | + ' "ct:ssh-public-key-format")'; |
| 195 | |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 196 | } |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 197 | refine "inline-or-keystore/keystore/" |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 198 | + "keystore-reference" { |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 199 | must 'derived-from-or-self(deref(.)/../ks:public-' |
| 200 | + 'key-format, "ct:ssh-public-key-format")'; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 201 | } |
| 202 | } |
| 203 | } |
| 204 | container certificate { |
| 205 | if-feature "sshcmn:ssh-x509-certs"; |
| 206 | description |
| 207 | "A locally-defined or referenced end-entity |
| 208 | certificate to be used for the SSH server's |
| 209 | host key."; |
| 210 | reference |
| 211 | "RFC CCCC: A YANG Data Model for a Keystore"; |
| 212 | uses |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 213 | ks:inline-or-keystore-end-entity-cert-with-key-grouping{ |
| 214 | refine "inline-or-keystore/inline/inline-definition" { |
| 215 | must 'derived-from-or-self(public-key-format,' |
| 216 | + ' "ct:subject-public-key-info-format")'; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 217 | } |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 218 | refine "inline-or-keystore/keystore/keystore-reference" |
| 219 | + "/asymmetric-key" { |
| 220 | must |
| 221 | 'derived-from-or-self(deref(.)/../ks:public-key-' |
| 222 | + 'format, "ct:subject-public-key-info-format")'; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 223 | } |
| 224 | } |
| 225 | } |
| 226 | } |
| 227 | } |
| 228 | } // container server-identity |
| 229 | |
| 230 | container client-authentication { |
| 231 | nacm:default-deny-write; |
| 232 | description |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 233 | "Specifies how the SSH server can be configured to |
| 234 | authenticate SSH clients. See RFC 4252 for a general |
| 235 | discussion about SSH authentication."; |
| 236 | reference |
| 237 | "RFC 4252: The Secure Shell (SSH) Transport Layer"; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 238 | container users { |
| 239 | if-feature "local-users-supported"; |
| 240 | description |
| 241 | "A list of locally configured users."; |
| 242 | list user { |
| 243 | key "name"; |
| 244 | description |
| 245 | "A locally configured user. |
| 246 | |
| 247 | The server SHOULD derive the list of authentication |
| 248 | 'method names' returned to the SSH client from the |
| 249 | descendant nodes configured herein, per Sections |
| 250 | 5.1 and 5.2 in RFC 4252. |
| 251 | |
| 252 | The authentication methods are unordered. Clients |
| 253 | must authenticate to all configured methods. |
| 254 | Whenever a choice amongst methods arises, |
| 255 | implementations SHOULD use a default ordering |
| 256 | that prioritizes automation over human-interaction."; |
| 257 | leaf name { |
| 258 | type string; |
| 259 | description |
| 260 | "The 'user name' for the SSH client, as defined in |
| 261 | the SSH_MSG_USERAUTH_REQUEST message in RFC 4253."; |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 262 | reference |
| 263 | "RFC 4253: The Secure Shell (SSH) Transport Layer |
| 264 | Protocol"; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 265 | } |
| 266 | container public-keys { |
| 267 | if-feature "local-user-auth-publickey"; |
| 268 | presence |
| 269 | "Indicates that public keys have been configured. |
| 270 | This statement is present so the mandatory descendant |
| 271 | nodes do not imply that this node must be |
| 272 | configured."; |
| 273 | description |
| 274 | "A set of SSH public keys may be used by the SSH |
| 275 | server to authenticate this user. A user is |
| 276 | authenticated if its public key is an exact |
| 277 | match to a configured public key."; |
| 278 | reference |
| 279 | "RFC BBBB: A YANG Data Model for a Truststore"; |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 280 | uses ts:inline-or-truststore-public-keys-grouping { |
| 281 | refine "inline-or-truststore/inline/inline-definition/" |
| 282 | + "public-key" { |
| 283 | must 'derived-from-or-self(public-key-format,' |
| 284 | + ' "ct:ssh-public-key-format")'; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 285 | } |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 286 | refine "inline-or-truststore/truststore/truststore-" |
| 287 | + "reference" { |
| 288 | must 'not(deref(.)/../ts:public-key/ts:public-key-' |
| 289 | + 'format[not(derived-from-or-self(., "ct:ssh-' |
| 290 | + 'public-key-format"))])'; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 291 | } |
| 292 | } |
| 293 | } |
| 294 | leaf password { |
| 295 | if-feature "local-user-auth-password"; |
| 296 | type ianach:crypt-hash; |
| 297 | description |
| 298 | "The password for this user."; |
| 299 | } |
| 300 | container hostbased { |
| 301 | if-feature "local-user-auth-hostbased"; |
| 302 | presence |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 303 | "Indicates that hostbased [RFC4252] keys have been |
| 304 | configured. This statement is present so the |
| 305 | mandatory descendant nodes do not imply that this |
| 306 | node must be configured."; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 307 | description |
| 308 | "A set of SSH host keys used by the SSH server to |
| 309 | authenticate this user's host. A user's host is |
| 310 | authenticated if its host key is an exact match |
| 311 | to a configured host key."; |
| 312 | reference |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 313 | "RFC 4252: The Secure Shell (SSH) Transport Layer |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 314 | RFC BBBB: A YANG Data Model for a Truststore"; |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 315 | uses ts:inline-or-truststore-public-keys-grouping { |
| 316 | refine "inline-or-truststore/inline/inline-definition/" |
| 317 | + "public-key" { |
| 318 | must 'derived-from-or-self(public-key-format,' |
| 319 | + ' "ct:ssh-public-key-format")'; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 320 | } |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 321 | refine "inline-or-truststore/truststore/truststore-" |
| 322 | + "reference" { |
| 323 | must 'not(deref(.)/../ts:public-key/ts:public-key-' |
| 324 | + 'format[not(derived-from-or-self(., "ct:ssh-' |
| 325 | + 'public-key-format"))])'; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 326 | } |
| 327 | } |
| 328 | } |
| 329 | leaf none { |
| 330 | if-feature "local-user-auth-none"; |
| 331 | type empty; |
| 332 | description |
| 333 | "Indicates that the 'none' method is configured |
| 334 | for this user."; |
| 335 | reference |
| 336 | "RFC 4252: The Secure Shell (SSH) Authentication |
| 337 | Protocol."; |
| 338 | } |
| 339 | } |
| 340 | } |
| 341 | container ca-certs { |
| 342 | if-feature "sshcmn:ssh-x509-certs"; |
| 343 | presence |
| 344 | "Indicates that CA certificates have been configured. |
| 345 | This statement is present so the mandatory descendant |
| 346 | nodes do not imply this node must be configured."; |
| 347 | description |
| 348 | "A set of certificate authority (CA) certificates used by |
| 349 | the SSH server to authenticate SSH client certificates. |
| 350 | A client certificate is authenticated if it has a valid |
| 351 | chain of trust to a configured CA certificate."; |
| 352 | reference |
| 353 | "RFC BBBB: A YANG Data Model for a Truststore"; |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 354 | uses ts:inline-or-truststore-certs-grouping; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 355 | } |
| 356 | container ee-certs { |
| 357 | if-feature "sshcmn:ssh-x509-certs"; |
| 358 | presence |
| 359 | "Indicates that EE certificates have been configured. |
| 360 | This statement is present so the mandatory descendant |
| 361 | nodes do not imply this node must be configured."; |
| 362 | description |
| 363 | "A set of client certificates (i.e., end entity |
| 364 | certificates) used by the SSH server to authenticate |
| 365 | the certificates presented by SSH clients. A client |
| 366 | certificate is authenticated if it is an exact match |
| 367 | to a configured end-entity certificate."; |
| 368 | reference |
| 369 | "RFC BBBB: A YANG Data Model for a Truststore"; |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 370 | uses ts:inline-or-truststore-certs-grouping; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 371 | } |
| 372 | } // container client-authentication |
| 373 | |
| 374 | container transport-params { |
| 375 | nacm:default-deny-write; |
| 376 | if-feature "sshcmn:transport-params"; |
| 377 | description |
| 378 | "Configurable parameters of the SSH transport layer."; |
| 379 | uses sshcmn:transport-params-grouping; |
| 380 | } // container transport-params |
| 381 | |
| 382 | container keepalives { |
| 383 | nacm:default-deny-write; |
| 384 | if-feature "ssh-server-keepalives"; |
| 385 | presence |
| 386 | "Indicates that the SSH server proactively tests the |
| 387 | aliveness of the remote SSH client."; |
| 388 | description |
| 389 | "Configures the keep-alive policy, to proactively test |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 390 | the aliveness of the SSH client. An unresponsive SSH |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 391 | client is dropped after approximately max-wait * |
| 392 | max-attempts seconds. Per Section 4 of RFC 4254, |
| 393 | the SSH server SHOULD send an SSH_MSG_GLOBAL_REQUEST |
| 394 | message with a purposely nonexistent 'request name' |
| 395 | value (e.g., keepalive@ietf.org) and the 'want reply' |
| 396 | value set to '1'."; |
| 397 | reference |
| 398 | "RFC 4254: The Secure Shell (SSH) Connection Protocol"; |
| 399 | leaf max-wait { |
| 400 | type uint16 { |
| 401 | range "1..max"; |
| 402 | } |
| 403 | units "seconds"; |
| 404 | default "30"; |
| 405 | description |
| 406 | "Sets the amount of time in seconds after which |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 407 | if no data has been received from the SSH client, |
| 408 | a SSH-level message will be sent to test the |
| 409 | aliveness of the SSH client."; |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 410 | } |
| 411 | leaf max-attempts { |
| 412 | type uint8; |
| 413 | default "3"; |
| 414 | description |
| 415 | "Sets the maximum number of sequential keep-alive |
| 416 | messages that can fail to obtain a response from |
roman | 7fdc84d | 2023-06-06 13:14:53 +0200 | [diff] [blame] | 417 | the SSH client before assuming the SSH client is |
roman | c1d2b09 | 2023-02-02 08:58:27 +0100 | [diff] [blame] | 418 | no longer alive."; |
| 419 | } |
| 420 | } |
| 421 | } // grouping ssh-server-grouping |
| 422 | |
| 423 | } |