openconfig/system: Add password-mode-type for special behaviors regarding passwords
Change Scope
In current OpenConfig public model, to configure passwords for root/non-root users, the following YANG path is being used respectively:
root user:
/system/aaa/authentication/admin-user/config/admin-password-hashed
/system/aaa/authentication/admin-user/state/admin-password-hashed
non-root users:
/system/aaa/authentication/users/user/config/password-hashed
/system/aaa/authentication/users/user/state/password-hashed
Other than the normal use case where they contain a hashed value of the password, there are 2 special semantics related to passwords:
- User can’t use password to login
- User can login without entering a password
These semantics can be achieved by overloading the existing leaf for passwords(make them not present/present but value is empty string), but that will be not ideal/user friendly.
So we propose to add a new leaf password-mode to explicitly indicate these special behaviors. It's a enum with 3 values: PASSWORD_DISABLED indicates that user can't use password to log in; PASSWORD_NOT_REQUIRED indicates that user can log in without a password; and PASSWORD_REQUIRED for normal cases.
This new leaf will become sibling to password-hashed and admin-password-hashed to explicitly describe the password behavior. So the YANG tree will have the following newly added leafs:
module: openconfig-system
+--rw system
+--rw aaa
+--rw authentication
+--rw admin-user
+--rw config
| +--rw admin-password-mode? oc-aaa-types:password-mode-type
+--ro state
+--ro admin-password-mode? oc-aaa-types:password-mode-type
module: openconfig-system
+--rw system
+--rw aaa
+--rw authentication
+--rw users
+--rw user* [username]
+--rw username -> ../config/username
+--rw config
| +--rw password-mode? oc-aaa-types:password-mode-type
+--ro state
+--ro password-mode? oc-aaa-types:password-mode-type
This change is backwards compatible.
Platform Implementations
- Arista EOS User Security: https://www.arista.com/en/um-eos/eos-user-security/
- Cisco
usernameCLI reference: https://www.cisco.com/E-Learning/bulk/public/tac/cim/cib/using_cisco_ios_software/cmdrefs/username.htm - Junos CLI Reference: https://www.juniper.net/documentation/us/en/software/junos/cli-reference/topics/ref/statement/root-login-jdm-junos-node-slicing.html
/gcbrun
@marcushines would you like to comment on this? Or perhaps @morrowc ?
No major YANG version changes in commit b07deb908b2f6b50e9cb5f4906feaa3f365520c1
/gcbrun
/gcbrun
Do we need three enum values?
Wouldn't a cleaner approach be something like
leaf passwordless_access {
type boolean;
default false;
}
and then the combination of false and unset password field will be equivalent to enum PASSWORD_DISABLED?
Also, you listed three references, but I didn't find the equivalent commands in there. Can you link/quote specific paragraphs if there are existing implementations available? If there are no current implementations, please remove the non-existing references from the PR description.
Thanks for the review.
I do believe the combination of (password is empty) && password_less==false <=> PASSWORD_DISABLED can work, but it feels less clear and more hacky to me, as it's actually overloading the leaf password. If we really want to go this way, we can overload password even harder: 1. password not exist <=> PASSWORD_DISABLED; 2. password equals empty string <=> PASSWORD_NOT_REQUIRED; 3. password not empty string <=> PASSWORD_REQUIRED. But is this really what we want? I'm open to go this direction, but I'm a little concerned as this is the direction of being less clear and assuming more.
I think it's more clear and user-friendly to have a single enum type defined, and make it well-documented & self-explanatory(as the name suggests, PASSWORD_DISABLED and PASSWORD_NOT_REQUIRED). Besides, in this way it's easier to extend the model if we ever need more semantics.
Regarding the platform implementation: Sorry for the confusion. I won't be referencing vendors other than Arista. I have removed those from the PR description. For EOS, we have:
- The PASSWORD_NOT_REQUIRED mode is implemented as the following (quoting Arista EOS User Manual):
This command creates the username jane without securing it with a password. It also removes a password if the jane username exists. switch(config)# username jane nopassword
- The PASSWORD_DISABLED mode is implemented by the following CLI:
(config)#username jane secret ?
0 Specify an UNENCRYPTED password will follow
5 Specify an ENCRYPTED MD5 password will follow
LINE The UNENCRYPTED (cleartext) password
scrypt Specifies an ENCRYPTED SCRYPT password will follow
sha512 Specifies an ENCRYPTED SHA512 password will follow
yescrypt Specifies an ENCRYPTED YESCRYPT password will follow
* Specify a password that cannot be used to login <----- this option disables password login
- This is not in the EOS User Manual yet, but the manual will be updated to contain this information within a couple of days
Here are the closest implementation references I could find.
Cisco security guide for IOSXR describes user and aaa policy configurations supported. But it is not clear any of these map to PASSWORD_DISABLED, PASSWORD_NOT_REQUIRED. PASSWORD_REQUIRED seems to be the only (implicit) option.
Junos root-login supports enable/disable login for an admin account. But I don't see options equivalent to PASSWORD_DISABLED or PASSWORD_NOT_REQUIRED.
EOS user security does show some support:
This command removes the password from the root account.
switch(config)# aaa root nopassword
This command disables the root login.
switch(config)# no aaa root
Reviewed at April 9th 2024 OC Operators meeting. Rough consensus is we do need to see at least 2 implementations and/or plans from other implementors to add this feature. Until then, this should be a private augment to the OC models.
I hadn't noticed the question :( #2muchMail but, i expect there are use-cases like: (some of these may be going away as other methods replace them)
-
enable an account for use with an mTLS authenticated connection type do not permit that user to have a password and possibly login on the serial console (or over ssh)
-
provide an account where there is no passwd useable for SSH but a key or certificate would be permitted
If you were going to support this I'd be in favor of the clear messaging an ENUM provides. Trying to divine the intention from some set of whacky booleans is bad news. Trying to divine the intention from a possibly empty string is also bad news.
is an enum costly or something?
Trying to divine the intention from some set of whacky booleans is bad news. is an enum costly or something?
I'd argue that the enum in the proposed form has some ambiguity as well :-) For example
enum PASSWORD_NOT_REQUIRED {
description
"The user can log in without entering a password.";
}
This implies the enum can be combined with the password, but, at the same time, the user may skip the password if he chooses to..? what if the user enters a wrong password?
or,
enum PASSWORD_REQUIRED {
is it really required if there's another way to authenticate the user (e.g. mTLS)?
fwiw, openssh uses booleans for this purpose (passwordAuthentication/permitEmptyPasswords)
I think
/system/aaa/authentication/users/user/config/password-hashed /system/aaa/authentication/users/user/config/password-mode
password-mode: PASSWORD_MODE_UNSPECIFIED = default <- password required would make the most sense for the action PASSWORD_MODE_DISABLED <- user cannot use a password to login (this would be same as password hashed == "" AND unspecified) PASSWORD_MODE_NOPASSWORD <- user can login with password hashed == ""
i hate to be difficult, but to me:
PASSWORD_MODE_NOPASSWORD <- user can login with password hashed == ""
could mean: "you can't set or use a passwd to login, you MUST provide a certificate or ssh-key"
unless we're really only talking about 'serial console'?
i hate to be difficult, but to me:
PASSWORD_MODE_NOPASSWORD <- user can login with password hashed == ""could mean: "you can't set or use a passwd to login, you MUST provide a certificate or ssh-key"
unless we're really only talking about 'serial console'?
Actually thinking about this a bit more ... i am not clear this actually gets to where we want to without more confusion
The start of this conversation appears to say: "Hey, I want to better model authentication for users, here's how!"
That seems like a great goal, but we managed to really just talk about 'is passwd?'.
Is it more reasonable to discuss this in the context of 'authentication method' than 'passwd'?
For instance, what if the user yang path could tell us:
"User X can authenticate with: 'password
That might be a (in proto form) one-of, or a repeated list of things.. If we talk about this problem as a 'how to authenticate a user' instead of 'has passwd?' is it easier to reason about this? (it is for me!)
I think likely we need to walk in a new auth model and probably need to figure out the right steps to take to there. Right now I do feel we have a gap in ability to express what we need to configure a device so likely we need an interim step then a longer term fix
I think Chris your view is mainly right around have a better defined "authentication-type" container
Closing the PR, as at least 2 implementations are needed to add this feature. This model change will remain as a private OC augmentation.