Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TACACSPLUS_PASSKEY_ENCRYPTION.md #1471

Merged
merged 12 commits into from
May 22, 2024
75 changes: 39 additions & 36 deletions doc/TACACSPLUS_PASSKEY_ENCRYPTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
|:---:|:-----------:|:-----------------------:|:----------------------------------|
| 0.1 | | Nikhil Moray (nmoray) | Initial version |
| 0.1 | | Madhu Paluru (madhupalu)| Updated |
| 0.1 | 11/09/2023| Madhu Paluru (madhupalu)| Addressed review comments |
### Scope
This document describes the High Level Design of "TACACS+ Passkey Encryption" feature support in SONiC. It encompasses design and implementation considerations for enhancing the security of TACACS+ (Terminal Access Controller Access-Control System) authentication by introducing an encrypted passkey.
### Abbreviations
Expand All @@ -41,60 +42,62 @@ The revised data handling procedure among the modules is outlined as follows:
| |
+----------v-----------v---------+ +---------------------+
| AUTHENTICATION | | |
| +-------------------------+ | Decrypted passkey | +------------+ |
| | PAM Configuration Files <-----------------------------------------+ | AAA Config | |
| +-------------------------+ | | +------------+ |
| | | |
| +-------------+ | | HostCfg Enforcer |
| | PAM | | +----------^----------+
| | Libraries | | |
| +-------------+ | | Encrypted passkey
+---------------+----------------+ |
| |
+----v----+ +-------+--------+
| | Encrypted passkey | |
| CLI +------------------------------------------------------> ConifgDB |
| | | |
| +-------------------------+ | Decrypted passkey | +------------+ |
| | PAM Configuration Files <------------+ +-----------------+ | AAA Config | |
| +-------------------------+ | | | | +------------+ |
| | | | | |
| +-------------+ | +-------------+ | HostCfg Enforcer |
| | PAM | | | | key-store +----------^----------+
| | Libraries | | +----> Master key | __ |
| +-------------+ | | | Manager |----|r | | Encrypted passkey
+---------------+----------------+ | | | |o | |
| | +-------------+ |o | |
+----v----+ | | |t | +-------+--------+
| | | | -- | |
| CLI +----------------+ +------------------------> ConifgDB |
| | Encrypted passkey | |
Copy link
Collaborator

Choose a reason for hiding this comment

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

Fix the typo. ConifgDB

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed it. @venkatmahalingam can you merge this PR? or should I ask @zhangyanzhao ?

+---------+ +----------------+
```
This decryption step is crucial because the login or SSH daemon references the PAM config file to verify the TACACS secret / passkey. If it remains encrypted, the SSH daemon will be unable to recognize the passkey, leading to login failures. The depicted block diagram clearly showcases the enhanced capabilities of the existing submodules.

### Approach 1:
1. A runtime flag (via config_db) for Enable / disable feature: "key_encrypt"
2. Use admin password from shadow file to encrypt the TACACS passkey
3. Use the same password to decrypt the TACACS paskey

### Approach 2:
### Approach
1. A runtime flag (via config_db) for Enable / disable feature: "key_encrypt"
Copy link
Contributor

@liuh-80 liuh-80 Jan 9, 2024

Choose a reason for hiding this comment

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

Yang model need update to include this change.

because this is config_db change, please also add schema and yang model to this HLD.

When device already has passkey and key_encrypt is false, then user set this flag to true, the passkey need encrypt in config DB, which component will do that?

Also, how to rollout this feature? there still backward compatibility issue:
Before rollout, passkey was plaintext and key_encrypt is false.
After rollout, passkey need encrypt and key_encrypt is true.

The gap is passkey need change from plaintext to encrypted when set key_encrypt flag.

Will load_minigraph command do the migration when apply the new config?
if not migrate, current hostcfgd code will report error because passkey decrypt failed.
#Closed

Copy link

Choose a reason for hiding this comment

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

@liuh-80 I have already updated the yang model in the PR. I will also add the new schema in this HLD.

Copy link

Choose a reason for hiding this comment

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

The passkey encryption in CONFIG_DB will be done during the configuration part (in aaa.py).
No Liuh, we don't need to have 'key_encrypt' flag in the existing schema. It is optional. If this flag is absent, encryption will not happen and the passkey will be pushed in plain text format only inside CONFIG_DB.

After rollout, if the user wants to enable this feature, he / she needs to simply enable "key_encrypt" flag and re-configure the passkey so that it will get encrypted and further replaced the same in CONFIG_DB.

Copy link

Choose a reason for hiding this comment

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

When user enable the "key_encrypt" flag, he / she needs to reconfigure the passkey. This is the requirement. Two steps are required to be followed if anyone wants to use this feature. But this will certainly not hamper the back-compatibility. It is backward compatible.

Copy link

Choose a reason for hiding this comment

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

It is like, if we need to configure SVI, we first need to add a vlan interface and later mark it as L3 interface by assigning an IP. Two steps. :-)

Copy link

Choose a reason for hiding this comment

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

BTW, if we are using CLI to encrypt the passkey, it will take care of updating the same into CONFIG_DB.

Copy link

Choose a reason for hiding this comment

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

You want me to add CLI to enable 'key_encrypt' flag for TACACS?

Copy link

@nmoray nmoray Jan 9, 2024

Choose a reason for hiding this comment

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

@liuh-80 I have now provided an option to set the key_encrypt flag in TACPLUS table via CLI. Please check the PR-Part I. Now user need to provide -e option for enabling encryption feature. If not used, it will internally mark key_encrypt flag as false. Thus, post rollout of this feature, that flag will automatically be added in during the configuration itself.

sonic/# config tacacs passkey -h
Usage: config tacacs passkey [OPTIONS] <secret_string>

  Specify TACACS+ server global passkey <STRING>

Options:
  -e, --encrypt   Enable passkey encryption feature
  -h, -?, --help  Show this message and exit.

And as I mentioned in the previous message, hostcfgd will take care of handling the backward compatibility by doing the decryption only when key_encrypt flag is present and it is set to true. Please refer PR - Part II

2. CLI will ask for a encryption password while configuring the TACACS passkey and at the backend it will be stored at /etc/encrypt_pass file
2. CLI will ask for a encryption master key/password while configuring the TACACS passkey and at the backend it will be stored at /etc/cipher_pass file which is accessible to only root user with read only permissions
Copy link
Contributor

Choose a reason for hiding this comment

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

master key

This is a disruptive behavior change on CLI. From network operators' point of view, it is ideal that each device could figure out a unique and random master key and just use it internally.

Could you also check other industry NOS implementation and follow the similar practice?

Copy link

Choose a reason for hiding this comment

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

FYI :

  • Cisco devices running IOS (-XE or -XR flavors) rely on a very poor encryption (type 7) that can be easily reversed using online tools (https://packetlife.net/toolbox/type7/). AFAIK there's no master key on IOS, therefore configuration backups can be easily redeployed on another box.
  • Juniper devices running Junos rely by default on an obfuscation algorithm (type 9), which is also a weak encryption for shared secrets stored in configuration. Such passwords can be decoded using online tools (https://www.m00nie.com/juniper-type-9-password-tool/) or even using a tool provided in Junos (request system decrypt password) so that configuration backup files can be restored on RMA'ed devices for example. Nevertheless, Juniper introduced new CLI commands to configure a system master password to provide stronger encryption for configuration secrets (the master password itself is not saved as part of the configuration). The master password is used as input to the password based key derivation function (PBKDF2) to generate an encryption key. The key is used as input to the Advanced Encryption Standard in Galois/Counter Mode (AES256-GCM). The plain text that the user enters is processed by the encryption algorithm (with key) to produce the encrypted text (cipher text). More details avaible here : https://www.juniper.net/documentation/us/en/software/junos/user-access/topics/topic-map/master-password-configuration-encryption.html#id-hardening-shared-secrets-in-junos-os

HTH.

Copy link

Choose a reason for hiding this comment

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

Thanks @ludal35 for the references from the popular NOSs.

@qiluo-msft If we want to have unique encrypted key for every device, it is possible with or without changing the password too.

But the pain point here is, if we have to vary the password for every device, network operator has to keep track of those many passwords (in case he / she wants to change it in the future).

Note: Here the encryption is solely based on two things, original passkey (in plaintext) and the associated password.

Copy link

Choose a reason for hiding this comment

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

Junos approach seems to be a good compromise:

  • by default, password is not stored in plain text in the config file (obfuscated format) so that a config file can be redeployed on another device (in case of RMA for exemple).
  • if needed, the network administrator can use a master key to encrypt the secrets (not only the TACACS server key, but also the Radius one, the OSPF/BGP neighbor passwords, IKE preshared keys...). There are no restrictions on the master password (@nmoray reusing the same master password across all devices is possible).
  • Moreover, Junos can optionnaly rely on the TPM chip of the Juniper device (if available) to protects secrets such as private keys, system primary passwords, and other sensitive data by storing it in an AES256 encrypted format (instead of storing sensitive data in a clear text format).

Copy link

Choose a reason for hiding this comment

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

@ludal35 you mean single master password for all?

Copy link

Choose a reason for hiding this comment

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

@nmoray Yes, a single master password for all secrets stored in the SONiC config file (TACACS / Radius server keys and maybe the SNMP communities/secrets as well). Regarding the OSPF/BGP neighbor passwords, I assume this is handled by FRR so this is probably out of the SONiC scope.

Copy link

Choose a reason for hiding this comment

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

Yeah @ludal35 as I mentioned in the community review meeting, I intentionally kept the design flexible so that either we can have single master password for all or can keep different passwords for different features.

3. Same file will be read while decrypting the passkey at hostcfgd
4. The infra (encrypt/decrypt and master key/password storage & retrieval) will be common for all the features like TACACS, RADIUS, LDAP etc..

### Implementation details
The implementation stands on four key pillars.
The implementation as follows
1. OPENSSL toolkit is used for encryption / decryption.
2. aes-128-cbc is the encoding format used for encryption / decryption.
3. A unique device admin password (encrypted hash from linux shadow file) will be used as a salt/password to encrypt/decrypt the configured pass key in ConfigDB.
4. In absence of configured admin password (default behaviour), a fixed / hardcoded hash will be used as a salt/password for encryption/decryption and it will be saved locally not in any of the databases.
Following is the snippet captured from a sample shadow file.
<snip_from_shadow_file>
admin:$6$YTJ7JKnfsB4esnbS$5XvmYk2.GXVWhDo2TYGN2hCitD/wU9Kov.uZD8xsnleuf1r0ARX3qodIKiDsdoQA444b8IMPMOnUWDmVJVkeg1:19446:0:99999:7:::
<snip_from_shadow_file>
Here, "YTJ7JKnfsB4esnbS$5XvmYk2.GXVWhDo2TYGN2hCitD/wU9Kov.uZD8xsnleuf1r0ARX3qodIKiDsdoQA444b8IMPMOnUWDmVJVkeg1" is the encrypted version of the admin level password.
2. base64 is the encoding format used for encryption / decryption.
4. sonic_utilities extended to passkey encyption using the master key/passwd manager.
5. User has to enter master key/passwd at the time of configuring the passkey, this is mandatory requirement only if "key_encrypt" run time flag is enabled.
6. The encrypted passkey stored in config_db
7. The master key/paswd used for encryption/decryption and will be stored in the same device with root access previleges.
8. HostCfg will use the master key/passwd to decrypt the encrypted passkey and further store it in PAM configuration files.

#### CLI Changes
config tacacs passkey TEST1

Password:

#### Show CLI changes
Furthermore, aside from encrypting the passkey stored within CONFIG_DB, this infrastructure ensures that the passkey itself remains concealed from any of the displayed CLI outputs. Consequently, the passkey field has been eliminated from the "show tacacs" output, and it will now solely indicate the status whether the passkey is configured or not. For instance,
liuh-80 marked this conversation as resolved.
Show resolved Hide resolved
show tacacs
["TACPLUS global passkey configured Yes / No"]

Copy link
Collaborator

Choose a reason for hiding this comment

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

Add a section for limitations/restrictions, mention that if the MAC address of the device is known, we could decrypt the key and add some thoughts for the future work if you are not planning to fix in the initial release.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Addressed. Added a section to the HLD describing the limitations and release plan.

Copy link

Choose a reason for hiding this comment

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

@venkatmahalingam the reason behind choosing system MAC as the encryption salt is, it will be known only to the network admin. Additionally, it will be readily accessible within the Redis so, can be pulled in different modules without hardcoding anything.

Moreover, we could consider other alternate salt too but again it will be an overhead of creating that uniquely for every node and also maintaining the same some where so that it can be consumed during the orchestration process.

### DB migration
A DB migration script will be added for users to migrate existing config_db to convert tacacs passkey plaintext to encrypted.
### Yang Changes
Increase existing passkey leaf length to 256.

### Config DB changes
A new run time flag to enable/disable the tacacs passkey encryption feature - "key_encrypt".

### Benefits
TACACS passkey encryption adds an extra layer of security to safeguard the passkey on each device throughout the network. Furthermore, the implementation of shadow file-based encryption ensures that encrypted passkeys can be reused across network nodes without any complications. Consequently, there are no obstacles when it comes to utilizing the config_db.json file from one device on another. Additionally, the use of a shadow file effectively reduces the risk of exposing the encryption/decryption salt since it is only accessible to root users and remains inaccessible to external entities.
### Limitation
The chosen way to encrypt the passkey is using an already encrypted admin password from the shadow file. Thus, the network admin needs to regenerate the encrypted passkey in ConfigDB only if there is a change in the admin password of the network.
For now we are planning to go ahead with this approach. However we are open to new ideas and thoughts to harden the security and we should be able to accommodate that with later releases.
TACACS passkey encryption adds an extra layer of security to safeguard the passkey on each device throughout the network. Furthermore, the implementation of master key/password manager encryption ensures that encrypted passkeys can be reused across network nodes without any complications. Consequently, there are no obstacles when it comes to utilizing the config_db.json file from one device on another. Additionally, the use of a root protected config file effectively reduces the risk of exposing the encryption/decryption master key/passwd since it is only accessible to root users and remains inaccessible to external entities.

### Testing Requirements
Need to add new / update the existing TACACS test cases to incorporate this new feature
Test cases to unit test encrypt and decrypt functions
Test cases to add test the TACACS+ functionality with passkey encryption
Test cases to cover DB migration