UniConfig supports encryption and hashing of leaf/leaf-list values via SSH and RESTCONF API. The following sections describe the supported security models in depth.
UniConfig uses asymmetric encryption to ensure confidentiality of selected leaf and leaf-list values. Currently only RSA ciphers are supported, both global UniConfig and device-level key-pairs. Encryption is supported for the uniconfig, unistore, and templates topologies.
Both the UniConfig and device sides use PKI for data encryption:
UniConfig side: All selected leaves are encrypted using a global public key when the data enters UniConfig via RESTCONF API or UniConfig SSH shell API. Afterwards, the data is stored in the database in encrypted format. UniConfig also has access to a private key used internally for decrypting data that is already encrypted.
Device side: The device exposes a public key, which UniConfig uses to re-encrypt data before it is sent to the device (commit and checked-commit operations). However, the device does not expose its private key, and UniConfig is therefore not able to detect changes to encrypted data (updated leaves/leaf-lists) but can only detect if data was removed or created. Because of this, UniConfig assumes that encrypted data read from the device was encrypted using the same public key as that used by UniConfig.
The figure below depicts data transformations performed on UniConfig interfaces:
In contrast to the global-device encryption architecture, this model uses only a global key-pair to encrypt data. Devices contain only plaintext data.
A public key is used to encrypt data received via RESTCONF, UniConfig shell API and when syncing configurations from device to UniConfig transaction (sync-from-network operation).
A private key is used to decrypt encrypted data before forwarding this configuration to a device (commit and checked-commit operations).
The figure below depicts data transformations performed on UniConfig interfaces:
Global-only encryption model
Reading operational data directly from the device (GET under yang-ext:mount) shows data in unencrypted format. Application gateways should restrict access to mountpoints for such use cases.
Leaves and leaf-lists whose values should be encrypted must be marked using a YANG extension with no parameters. Currently, only leaves of the string type are supported (direct/indirect with custom type definitions), as encrypted values are base64 encoded. Also, be aware that type constraints must accept encrypted values.
Example - YANG module that defines one encrypt extension:
Oftentimes it is not possible to modify existing YANG files, as they are already deployed on a device (for example, a device running with a NETCONF server). In this case, you can still mark which leaves should be encrypted using an additional YANG module that contains deviations.
Afterwards, there are two options to couple this module with modules from the device (NETCONF):
Explicitly specifying the side-loaded module in the install-node request using the netconf-node-topology:yang-module-capabilities settings. See Device installation section below for more information.
Automatically detecting the side-loaded module - UniConfig looks for the specific capability on the NETCONF server, inherits its revision and looks for a side-loaded module with a specific name and inherited revision (see Configuration section below). This option is preferred if the deployment contains multiple versions of devices and the list of encrypted paths is different on each version.
The global RSA key-pair is stored inside PEM-encoded files in the rsa directory under UniConfig root. The private key must be named encrypt_key and the public key encrypt_key.pub. If these files are not provided, UniConfig automatically generates its own key-pair with a length of 2048 bits. All UniConfig instances in the cluster must use the same key-pair.
Encryption settings are stored in the config/application.properties file.
encrypt-enabled - If false, encryption is disabled regardless of other settings or install-node parameters. If true, encryption is enabled. The default value is true.
encrypt-extension-id - If not specified, encryption is disabled regardless of other settings or install-node parameters. Uses the format [module-name]:[extension-name], which specifies the extension used to mark encrypted leaves/leaf-lists in YANG modules. The corresponding YANG module containing this extension can be part of device/unistore YANG schemas or, alternatively, can be side-loaded during installation of the NETCONF device as an imported module from the default repository.
netconf-reference-module - Name of the module that the NETCONF client looks for during the mounting process. If UniConfig finds a module with this name in the list of received capabilities, it uses its revision in the lookup process for the correct YANG module with encrypted paths (using deviations).
netconf-encrypted-paths-module-name - Name of the module which contains deviations with paths to encrypted leaves/leaf-lists. There can be multiple revisions of this file prepared in the default NETCONF repository. The NETCONF client in UniConfig chooses the correct revision based on the netconf-reference-module-name setting. Together, netconf-reference-module-name and netconf-encrypted-paths-module-name can be used to autoload encrypted paths for different versions of devices.
If the default YANG repository contains a module with encrypted-paths and without defined YANG revision, and the device does not already provide encryption capability, the encrypted-paths module is used as last resort during device installation (netconfReferenceModuleName and matching of revisions are ignored).
After this command is called, all UniConfig instances will set this parameter using the notification service to the value sent via RPC (in this case, true).
Correspondingly, the following request can be used to disable encryption:
If it is necessary to change the encryption keys, use the change-encryption-keys RPC.
The process of changing encryption keys requires rebooting one of the UniConfig instances or enabling a new instance of UniConfig after calling the change-encryption-keys RPC. Rotation of encrypted data in the database for new encryption keys occurs if UniConfig is started after the change-encryption-keys RPC is executed. During key rotation, if some data in the database cannot be decrypted with the old key, those data will remain unchanged.
RPC request: change-encryption-keys to new public and private keys
After key rotation and when UniConfig is started, data encrypted with the old key is overwritten with the new encryption keys and all other UniConfig instances in the cluster will use the new keys for encryption.
During key rotation, UniConfig reads and updates encrypted configurations in batches. The size of these batches is set by the following parameter:
There are two settings related to encryption in the install-node RPC request:
uniconfig-config:device-crypto - Specifies a path to the public key on the device:
public-key-path - Leaf with RFC-8040 path. If a path to the public key is specified and exists on the device, the global-device encryption model is used. Otherwise, the global-only encryption model is used.
public-key-cipher-type - Cipher type (RSA is used by default).
netconf-node-topology:yang-module-capabilities - If autoloading of YANG modules with encrypted paths is not used and the device itself does not specify encrypted leaves, it is necessary to side-load the YANG module with encrypted paths. This parameter is relevant only for NETCONF nodes. Side-loaded modules must be expressed in the format of NETCONF capabilities.
The following request shows an install-node request that specifies a path to the public key and the side-loaded YANG module encrypted-paths with revision 2021-12-15 and namespace urn:ietf:params:xml:ns:yang:encrypted-paths.
Encrypted values are stored and displayed via RESTCONF or UniConfig shell with the rsa_ prefix. The prefix is used by UniConfig to see if posted data needs to be encrypted or is encrypted already.
The encrypted string is encoded using Base64 encoding.
GET request: reading encrypted leaf
curl --location --request GET 'http://127.0.0.1:8181/rests/data/network-topology:network-topology/topology=uniconfig/node=dev01/config/secret'\
--header 'Accept: application/json'
This example shows encryption of values marked by the frinx-encrypt:encrypt extension on both UniConfig server side and device side. The NETCONF device directly exposes the frinx-encrypt YANG module and leaves with applied extension (side-loading of encrypted paths is not necessary).
This example shows encryption of values marked by the frinx-encrypt:encrypt extension only on the UniConfig server side. The NETCONF device directly exposes the frinx-encrypt YANG module and leaves with applied extension (side-loading of encrypted paths is not necessary).
The YANG model used for simulation of the YANG device is the same as in the previous example.
UniConfig supports the iana-crypt-hash YANG model for specificying hashed values in the data-tree using the type definition crypt-hash. Hashing works in the uniconfig and unistore topologies.
Only NETCONF devices are currently supported, as CLI cannot be natively used to report device capabilities that would contain supported the hashing function.
Hashing is done only in the RESTCONF layer after writing data that contains leaves/leaf-lists with the crypt-hash type. Afterwards, UniConfig stores, uses, and writes to the device only the hashed representation of these values.
All three hash functions are implemented (MD5, SHA-256 and SHA-512). For the uniconfig topology, the hashing function is selected based on the reported feature in the NETCONF capability. For the unistore topology, UniConfig enforces the SHA-512 hashing function.
Hashing is enabled by default on NETCONF devices that report the iana-crypt-hash model-based capability. It is not necessary to add the entry setting in the install-node request.
After successfully installing the device, you can check the loaded hashing function that will be used to store hashed values. Use the following GET request:
Read synced hashing function from device
curl --location --request GET 'http://127.0.0.1:8181/rests/data/network-topology:network-topology/topology=uniconfig/node=dev01/crypto:hash?content=nonconfi'\
--header 'Accept: application/json'