Skip to content
118 changes: 118 additions & 0 deletions doc/TACACSPLUS_PASSKEY_ENCRYPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# TACACS+ Passkey Encryption #


## Table of Contents

- [Revision](#revision)
- [Scope](#scope)
- [Abbreviations](#abbreviations)
- [Overview](#overview)
- [Requirements](#requirements)
- [High-Level Design](#high-level-design)
- [Implementation Details](#implementation-details)
- [Show CLI changes](@show-cli-changes)
- [Benifits](#benifits)
- [Testing Requirements](#testing-requirements)



### Revision

| Rev | Date | Author | Change Description |
|:---:|:-----------:|:--------------------:|-----------------------------------|
| 0.1 | | Nikhil Moray (nmoray)| Initial version |
| 0.1 | | Madhu Paluru (madhupalu)| Updated |


### 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

| Term | Meaning |
|:-------:|:-------------------------------------------------------|
| TACACS | Terminal Access Controller Access Control System Plus) |

### Overview

This addition constitutes a substantial improvement in bolstering the security of the TACACS+ authentication protocol. TACACS+ has a well-established reputation as a reliable means of managing access to network devices. However, the previous practice of utilising a sensitive passkey in plaintext during the authentication process posed security concerns. With this enhancement, the vulnerability is effectively mitigated by introducing robust passkey encryption mechanisms (on the client side), ensuring the safeguarding of authentication credentials and an overall strengthening of network security."


### Requirements

The primary objective of this feature is to safeguard the TACACS passkey, which is stored in its plaintext format within CONFIG_DB.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you add the section for DB migrator?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you add the YANG change for the new TACACS passkey?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@venkatmahalingam passkey is already part of yang model, no new schema introduced part of HLD - https://github.com/sonic-net/sonic-buildimage/blob/master/src/sonic-yang-models/yang-models/sonic-system-tacacs.yang
Only the backend will use system mac as unique salt to encrypt/decrypt the passkey.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't need DB migrator as no change to the schema.

Copy link
Collaborator

Choose a reason for hiding this comment

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

How about existing plaintext passkey to encrypted key migration in the config-db during image upgrade?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@venkatmahalingam The current yang model description already reflect the change you requested - ' description "Shared secret used for encrypting the communication";' Is the sufficient or do we think still need an update?

leaf passkey {
type string {
length "1..65";
pattern "[^ #,]*" {
error-message 'TACACS shared secret (Valid chars are ASCII printable except SPACE, "#", and ",")';
}
}
description "Shared secret used for encrypting the communication";
}

Copy link

Choose a reason for hiding this comment

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

@venkatmahalingam is sonic-system-tacacs.yang a pull model or push? If we need to configure the passkey via this model, we don't need any change as it will still be in a plaintext format only.

Copy link
Contributor

Choose a reason for hiding this comment

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

@nmoray , I think the length part need change, because when you encrypt a text to binary then convert to text, the length will usually be much longer, currently sonic already enable yang validation, if the length not change, yang validation will failed with some TACACS key.

Copy link

@nmoray nmoray Nov 2, 2023

Choose a reason for hiding this comment

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

@liuh-80 one question related to sonic-system-tacacs.yang model. Is it being used for pushing the TACACS configs or pulling the telemetry data related to TACACS or both?

And in case of increasing the length of passkey leaf, do I need to make any other backward compatibility changes or nothing?

Copy link
Contributor

Choose a reason for hiding this comment

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

sonic-system-tacacs.yang is used for push TACACS config, also when change TACACS config on device with CLI, the model also will be used for validation.

Increase the length of passkey is backward compatibility. No need other change.



### High-Level Design

In line with the TACACS+ architecture, when a user initiates a SSH connection to a device with TACACS+ authentication enabled, they must utilize the TACACS+ login password. Conversely, the corresponding device must have the passkey provided by the TACACS+ server properly configured within its configDB. Should either of these elements be missing or incorrect, the user will be unable to access the device. Thus to meet the given requirement, passkey will be encrypted is the configuration phase itself.

The current data flow among the various TACACS modules operates in the following manner.

1. When a user configures the TACACS passkey using the SONIC CLI, it is initially stored in the CONFIG_DB.
2. Subsequently, the same key is retrieved by the HostCfg Enforcer module to update the PAM configuration file(s). This configuration file is inherently included in the authentication processes for login or SSH within the Linux operating system.
3. When TACACS+ Authentication is activated on the device, a new PAM configuration file (common-auth-sonic) is generated and substituted in the login and SSH daemons. Importantly, the pre-existing configuration file remains unchanged.

The revised data handling procedure among the modules is outlined as follows:

1. When a user configures the TACACS passkey using the SONIC CLI, it will now be securely stored in encrypted format instead of plaintext.
2. Subsequently, the HostCfg Enforcer module retrieves this encrypted key. However, before writing it into the PAM configuration file(s), the hostCfgd module decrypts it.
```
+-------+ +---------+
| SSH | | Console |
+---+---+ +----+----+
| |
+----------v-----------v---------+ +---------------------+
| AUTHENTICATION | | |
| +-------------------------+ | Decrypted passkey | +------------+ |
| | PAM Configuration Files <------------------------------------------+ | AAA Config | |
| +-------------------------+ | | +------------+ |
| | | |
| +-------------+ | | HostCfg Enforcer |
| | PAM | | +----------^----------+
| | Libraries | | |
| +-------------+ | | Encrypted passkey
+---------------+----------------+ |
| |
+----v----+ +-------+--------+
| | Encrypted passkey | |
| CLI +---------------------------------------------------->| ConifgDB |
| | | |
+---------+ +----------------+
```
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 showcase the enhanced capbalities of the existing submodules.


### Implementation details

The implementation stands on three key pillars.
1. OPENSSL toolkit is used for encryption / decryption
2. aes-128-cbc is the encoding format used for encryption / decryption
3. A unique Device MAC address used as a salt/password to encrypt/decrypt the configured pass key
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this mean that the key will only be the MAC address of the switch? If so - this is not a strong encryption (as it is not a random password or something else).
What if we do not want it to be the MAC address, is there an option to change it?

Copy link

Choose a reason for hiding this comment

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

We have considered system MAC address as a password for encrypting the user entered plaintext passkey. Network admin can change the passkey but not the password (which is system MAC). With this combination, OPENSSL is able to generate the random encrypted hash / passkey.

If we provide a configurable password, we need to store that somewhere (for instance redis which will again defeat the purpose of safe guarding the secret). Additionally, we need to generate unique password for every node within the network which will be a cumbersome job.

Copy link
Contributor

Choose a reason for hiding this comment

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

So the key is not something that is saved on top of the system, but rather a manipulation of the device MAC.
This means the the encryption key consists only of the system MAC (this means that anyone with network proximity to the device can figure out this key) and therefor we don't need to save anything additionally from this feature on top of the system (as device MAC already has a stored location).

Question - isn't using the system MAC (which is exposed via network proximity) not a risk?

Copy link

Choose a reason for hiding this comment

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

I would say, the encrypted key is essentially the manipulation of a passkey done using the system MAC address. And yes, there is an obvious risk if an intruder is having physical network proximity to the device. :-)

Alternatively, we can combine the system MAC with the plaintext user entered passkey and will use that as a password for the encryption.

Lastly, we can certainly consider a user configurable password similar to the TACACS passkey. But then where are we going to store it? and how are we going to create a unique password for all the devices within the network?

Copy link
Contributor

Choose a reason for hiding this comment

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

These are exactly my questions here :)
If we are going to encrypt this passphrase - what are we trying to protect ourselves against? If it's a user without privileges reading the passkey, then this won't suffice (as this user can review the MAC address).
If it's against someone getting the redis dump and figuring out the passkey - I think that is also not sufficient as he can get the MAC address as well from it (or maybe in this case - it is more difficult).

If we are creating some DB encryption key (let's call it like that for now), we can use a shadow file or something similar to protect it.
Question is - what are we trying to achieve here and from who are we trying to protect the passphrase for the tacacs server?

Copy link

Choose a reason for hiding this comment

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

First of all, a secure passphrase is necessary to verify the identity of users or devices seeking access to network resources. Without that unauthorised users could gain access to sensitive systems and data. Thus, encryption of the plaintext passphrase is needed.

But yeah, I understand that the only MAC based encryption won't be enough. Using shadow file is also a good idea.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that creating a secure passphrase is critical for protecting any sensitive data that we have on top of the system.
My question is whether this will suffice, as I have presented different vectors where a user can get this data therefor bypassing this protection that was proposed here.
I'm still trying to understand the original security mitigation proposed here and from what type of attacks/users it protects.
In the case we are going with a shadow file for the DB password/key/secret - we can explore that, but we need to elaborate here what we would like to do with said key, how should we store it, manage it and export it if required.

Copy link

Choose a reason for hiding this comment

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

Presently, we are only targeting the outsiders who doesn't have access to the local network. For instance, if we shared the config_db.json to a third party vendor. In that case, passkey needs to be safe guarded. In the later releases, we will think of enhancing this implementation with the shadow file.

Copy link

Choose a reason for hiding this comment

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

We can make use of shadow file for replacing MAC address (as a salt) with an encrypted user specific password. For
instance,
<snip_from_shadowfile>
admin:$6$YTJ7JKnfsB4esnbS$5XvmYk2.GXVWhDo2TYGN2hCitD/wU9Kov.uZD8xsnleuf1r0ARX3qodIKiDsdoQA444b8IMPMOnUWDmVJVkeg1:19446:0:99999:7:::
<snip_from_shadowfile>

"YTJ7JKnfsB4esnbS$5XvmYk2.GXVWhDo2TYGN2hCitD/wU9Kov.uZD8xsnleuf1r0ARX3qodIKiDsdoQA444b8IMPMOnUWDmVJVkeg1" is the encrypted password for user "admin". We can use the same hash for encrypting the TACACS passkey. What are your thoughts @Yarden-Z ?

Copy link

Choose a reason for hiding this comment

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

This way, salt will only be visible to the root user and it will be same across all the devices. Additionally, same config_db.json can also be loaded on to another device without any intermediate modifications.



#### 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.
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we also remove this password from all log files in the system?
I assume it must remain in the tacplus_nss_conf and also in PAM, but we must make sure that it is not exposed in other files.

Copy link

Choose a reason for hiding this comment

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

Yes @Yarden-Z. The passkey in plaintext format will only be visible in PAM config file. Else where it will be masked.

Copy link
Contributor

Choose a reason for hiding this comment

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

I understand, can we make sure to test that the key is not present in anywhere else in the system once it is configured?
Also, might be worth checking that the files where this key is present is not globally readable.
If it is and an un-privileged user can read it, then encrypting it in the DB will serve minimal purpose.


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 encypted.
Copy link
Contributor

Choose a reason for hiding this comment

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

What about DB sync and DB export?
If we have device A with it's configuration and we would like to copy the configuration to device B, how would the redis export perform in the case we have encrypted the Tacacs password?

Copy link

Choose a reason for hiding this comment

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

If we have to copy configuration from device A to B, there are two ways.

  1. Copy configuration from device A to B and later generate a new encrypted key in device B so that the hostcfgd on device B must be able to decode the encrypted key. This is required as the system MAC address is used as an encryption password.

  2. Generate the configuration for device B (including a new encrypted passkey for device B) and later apply the same.

Code Reference:

1. passkey: User entered passkey in plaintext
2. pswd: system MAC

def encryption(passkey, pswd):
    cmd = [ 'openssl', 'enc', '-aes-128-cbc', -A',  '-a', '-salt', '-pbkdf2', '-pass', 'pass:' + pswd ]
    p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
    encryptedkey, err = p.communicate(input=passkey)
    return encryptedkey, err

Copy link
Contributor

Choose a reason for hiding this comment

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

So there is no seamless transition between devices.
If we export a config file from device A it will be applicable only for device A and not for any other device in the network.

And, therefor - applying this configuration on another device requires some adjustments to the configuration itself (currently, it's only the Tacacs passkey, but this is the current state as this feature might be applied to other items as well in the system such as radius passkey, snmp community string, ntp key, etc')

Copy link

Choose a reason for hiding this comment

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

Yeah. To make the config export seamless between the devices, we have to generate an encrypted passkey which can work on all the devices. And for that we need to use same password for encryption across all the devices as passkey can not be changed per device.


### Benifits

TACACS passkey encryption adds an extra layer of security to safeguard the passkey on each device throughout the network. Moreover, the utilization of MAC address-based encryption ensures that each network device possesses its distinct encrypted passkey. This strategy effectively mitigates the risk of a major network breach in case one of the devices is compromised.
Copy link
Contributor

Choose a reason for hiding this comment

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

This feature enforces password encryption across all tacacs password settings (both global and per-server passwords), correct?

Copy link

Choose a reason for hiding this comment

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

Yes, right.


### Limitation
We choose MAC address is unique and better for management, however if the MAC address of the device is known, we could decrypt the key. If we want to use any other ciper we should manage / stored it in the DB, it is again defeating the purpose. So for now we are going ahead with mac as network admins can orchestartion system to use mac address for passkey encryption. However we are open to new ideas and thoughts to hardened the security and we should be able to accomodate with later releases.

### Testing Requirements

Need to add new / update the existing TACACS testcases to incorporate this new feature
Test cases to unit test encrypt and decrypt fucntions
Test cases to add test the TACACS+ functionality with passkey encryption
Test cases to cover DB migration
Copy link
Contributor

Choose a reason for hiding this comment

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

Upgrade tests should be added, as well as checking on a per server vs global test case

Copy link

@nmoray nmoray Sep 18, 2023

Choose a reason for hiding this comment

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

Noted.

Copy link

Choose a reason for hiding this comment

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

Hello,

Could you please explain how TACACS key encryption is handled during configuration backups & restores ? As far as I understand, in case of RMA, the system MAC will change, therefore the encrypted key stored in the config file won't be usable on the new box :(

Could you please check and advise ?

Thanks.

Note : config backup/restore is explained here : https://github.com/sonic-net/SONiC/blob/master/doc/ztp/SONiC-config-setup.md

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ludal35 for RMA case, Backup the config and while restore the config encrypt the passkey with new system mac, update the config and load it. Typically, customers integrate with ZTP process or orchestrion used.

Copy link

Choose a reason for hiding this comment

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

In case of config restore, we need to write post-hook script to generate a new encrypted passkey based on the new MAC.