Skip to content

Conversation

@nmoray
Copy link
Contributor

@nmoray nmoray commented May 27, 2025

What I did it

  1. TACACSPLUS_PASSKEY_ENCRYPTION.md SONiC#1471
  2. https://github.com/sonic-net/SONiC/blob/master/doc/ztp/SONiC-config-setup.md#222-config-migration

Now the module / application / feature who wants to use the security cipher module for encryption / decryption, it needs to first register with it by providing a callback function which will be responsible for updating the existing encrypted passkey in the CONFIG_DB table or which ever the storage media used. This way, all the registered parties will be notified and at the same time gets updated with the new password. The security cipher module keeps a list of all the callbacks and at the time of password rotation, it simply notifies and updates everyone one after the other.

How to verify it

  • Encrypt the passkey for multiple TACPLUS / RADIUS servers using same password
  • NOS upgrade to verify backup / restore feature

Test Logs:

1. Encrypt passkey:
sonic# config tacacs passkey nikhil --encrypt
sonic# show run al | jq .TACPLUS
{
  "global": {
    "auth_type": "login",
    "key_encrypt": "True",
    "passkey": "U2FsdGVkX19YTUcG+0r3+d78A5E0zTXEukS3ZNrfyFk=",
    "src_intf": "Loopback0"
  }
}
sonic# cat /etc/pam.d/common-auth-sonic
#THIS IS AN AUTO-GENERATED FILE
#
# /etc/pam.d/common-auth- authentication settings common to all services
# This file is included from other service-specific PAM config files,
# and should contain a list of the authentication modules that define
# the central authentication scheme for use on the system
# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the
# traditional Unix authentication mechanisms.
#
# here are the per-package modules (the "Primary" block)

auth	[success=done new_authtok_reqd=done default=ignore auth_err=die]	pam_tacplus.so server=<> secret=nikhil login=login timeout=5   try_first_pass
auth	[success=done new_authtok_reqd=done default=ignore auth_err=die]	pam_tacplus.so server=<> secret=nikhil login=login timeout=5   try_first_pass
auth	[success=1 default=ignore]	pam_unix.so nullok try_first_pass

#
# here's the fallback if no module succeeds
auth    requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth    required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
sonic# cat /etc/cipher_pass.json
{
  "TACPLUS": {
    "table_info": [
      "TACPLUS|global"
    ],
    "password": "TEST1"
  }

2. Encrypt passkey and update existing password
sonic# config tacacs passkey nikhil --encrypt --rotate
Password:
sonic# cat /etc/cipher_pass.json
{
  "TACPLUS": {
    "table_info": [
      "TACPLUS|global"
    ],
    "password": "TEST3"
  }
sonic# cat /etc/pam.d/common-auth-sonic
#THIS IS AN AUTO-GENERATED FILE
#
# /etc/pam.d/common-auth- authentication settings common to all services
# This file is included from other service-specific PAM config files,
# and should contain a list of the authentication modules that define
# the central authentication scheme for use on the system
# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the
# traditional Unix authentication mechanisms.
#
# here are the per-package modules (the "Primary" block)

auth	[success=done new_authtok_reqd=done default=ignore auth_err=die]	pam_tacplus.so server=<> secret=nikhil login=login timeout=5   try_first_pass
auth	[success=done new_authtok_reqd=done default=ignore auth_err=die]	pam_tacplus.so server=<> secret=nikhil login=login timeout=5   try_first_pass
auth	[success=1 default=ignore]	pam_unix.so nullok try_first_pass

#
# here's the fallback if no module succeeds
auth    requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth    required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
sonic# show run al | jq .TACPLUS
{
  "global": {
    "auth_type": "login",
    "key_encrypt": "True",
    "passkey": "U2FsdGVkX18/8nFrAiCe01pOqgPoUUZFaTpmtawdi8I=",
    "src_intf": "Loopback0"
  }
}

3. Revert back to plaintext passkey
sonic# config tacacs passkey ravi
sonic# cat /etc/pam.d/common-auth-sonic
#THIS IS AN AUTO-GENERATED FILE
#
# /etc/pam.d/common-auth- authentication settings common to all services
# This file is included from other service-specific PAM config files,
# and should contain a list of the authentication modules that define
# the central authentication scheme for use on the system
# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the
# traditional Unix authentication mechanisms.
#
# here are the per-package modules (the "Primary" block)

auth	[success=done new_authtok_reqd=done default=ignore auth_err=die]	pam_tacplus.so server=<> secret=ravi login=login timeout=5   try_first_pass
auth	[success=done new_authtok_reqd=done default=ignore auth_err=die]	pam_tacplus.so server=<> secret=ravi login=login timeout=5   try_first_pass
auth	[success=1 default=ignore]	pam_unix.so nullok try_first_pass

#
# here's the fallback if no module succeeds
auth    requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth    required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
sonic# show run al | jq .TACPLUS
{
  "global": {
    "auth_type": "login",
    "key_encrypt": "False",
    "passkey": "ravi",
    "src_intf": "Loopback0"
  }
}
sonic# cat /etc/cipher_pass.json
{
  "TACPLUS": {
    "table_info": [],
    "password": null
  }

Which release branch to backport (provide reason below if selected)

  • 202205
  • 202211
  • 202305
  • 202311
  • 202405
  • 202411
  • 202505

Tested branch (Please provide the tested image version)

  • 202311

Link to config_db schema for YANG module changes

https://github.com/Azure/sonic-buildimage/blob/master/src/sonic-yang-models/doc/Configuration.md

@nmoray nmoray requested review from lguohan and qiluo-msft as code owners May 27, 2025 09:52
@mssonicbld
Copy link
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@nmoray
Copy link
Contributor Author

nmoray commented May 27, 2025

/azpw ms_conflict

@nmoray
Copy link
Contributor Author

nmoray commented May 27, 2025

@qiluo-msft As per your comment, I have added pre/post migration scripts for Security Cipher module.
cc: @anders-nexthop @madhupalu

@mssonicbld
Copy link
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@nmoray
Copy link
Contributor Author

nmoray commented May 28, 2025

@qiluo-msft please help me understand ms_conflict failure. I don't know why this is failing.
Additionally, please approve the PR in case there are no new comments.

@anders-nexthop
Copy link
Contributor

@qiluo-msft @lguohan are there any further comments on this PR? If not, can we merge it and unblock this feature?

@nmoray this is what the MS-Conflict says:

failure: @StormLiangMS,@liushilongbuaa Conflict already exists in master
Please wait a few hours to run ms_conflict again!
'/azpw ms_conflict'

I don't know what this check is for, but maybe just rebase and push again to re-run it and see if that resolves things?

@nmoray
Copy link
Contributor Author

nmoray commented Jun 13, 2025

@qiluo-msft @lguohan are there any further comments on this PR? If not, can we merge it and unblock this feature?

@nmoray this is what the MS-Conflict says:

failure: @StormLiangMS,@liushilongbuaa Conflict already exists in master
Please wait a few hours to run ms_conflict again!
'/azpw ms_conflict'

I don't know what this check is for, but maybe just rebase and push again to re-run it and see if that resolves things?

Yeah @anders-nexthop, I have already tried this option but no luck.

…urity Cipher module. Additionally, now multiple modules of same feature type can make use of same password for generating their unique encrypted passkey. For instance, now multiple TACPLUS server can have their own passkey encrypted from the same password.
@nmoray nmoray changed the title Security Cipher Module: Enabled Backup and Restore support for NOS Upgrades Security Cipher Module: Added password rotate feature and enabled Backup and Restore support for NOS Upgrades Jun 19, 2025
@mssonicbld
Copy link
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@nmoray
Copy link
Contributor Author

nmoray commented Jun 20, 2025

@anders-nexthop @qiluo-msft Please review the updated code and share the comments if any.

Copy link
Contributor

@anders-nexthop anders-nexthop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, the rotation code is a good change.

@mssonicbld
Copy link
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Collaborator

/azp run Azure.sonic-buildimage

Copy link
Contributor

@anders-nexthop anders-nexthop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am approving this change, as I think this is a workable implementation and would like to see it move forward. However, please consider my point about separating encryption password handling from table registration.

@qiluo-msft can you take another look, or assign another reviewer to get more eyes on this latest version?

@bhouse-nexthop your thoughts would be welcome here given your security background.

@mssonicbld
Copy link
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@mssonicbld
Copy link
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@nmoray
Copy link
Contributor Author

nmoray commented Jul 4, 2025

Thanks @anders-nexthop for the diligent review.
@qiluo-msft @bhouse-nexthop I have addressed the comments. Please approve in case there are no more comments.

@nmoray
Copy link
Contributor Author

nmoray commented Jul 7, 2025

/azp run Azure.sonic-buildimage

@azure-pipelines
Copy link

Commenter does not have sufficient privileges for PR 22711 in repo sonic-net/sonic-buildimage

@mssonicbld
Copy link
Collaborator

/azp run Azure.sonic-buildimage

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@nmoray
Copy link
Contributor Author

nmoray commented Jul 7, 2025

@qiluo-msft please approve in case there are no more comments so that other dependent PRs can also be merged.
sonic-net/sonic-utilities#3936
sonic-net/sonic-host-services#274

@nmoray
Copy link
Contributor Author

nmoray commented Jul 24, 2025

@qiluo-msft will you please help in merging this PR in case there are no more comments?

@anders-nexthop
Copy link
Contributor

@qiluo-msft and @lguohan can we get this PR merged if there are no more comments?

@prabhataravind
Copy link
Contributor

hi @qiluo-msft is this good to be merged?

@arlakshm
Copy link
Contributor

arlakshm commented Oct 8, 2025

@qiluo-msft, please help approve if no other comments.

@anders-nexthop
Copy link
Contributor

@qiluo-msft @lguohan Besides wanting this for TACACS, there are two outstanding feature requests that are dependent on this basic infrastructure getting merged (#22276 and #22277), can we please get this reviewed by an authorized reviewer and merged up?

@lguohan
Copy link
Collaborator

lguohan commented Nov 3, 2025

do we have sonic-mgmt test to test this?

@lguohan
Copy link
Collaborator

lguohan commented Nov 3, 2025

@anders-nexthop , i will ask qiluo to take a look this PR. Thanks for your patience.

# Restore cipher_pass file from persistent storage
if [ -f /host/security_cipher/cipher_pass ]; then
cp /host/security_cipher/cipher_pass.json /etc/cipher_pass.json
chmod 640 /etc/cipher_pass.json
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

640

Is it better to use 600 if the only reader is root?

try:
with open(CIPHER_PASS_FILE, 'r') as f:
return json.load(f)
except Exception as e:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exception

Could you use more specific exception type?

Copy link
Collaborator

@qiluo-msft qiluo-msft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As commented

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants