Manage decryption policy and automatically decrypt storage when specified conditions are met, by using NBDE.
In many environments, the default workflow to decrypt devices that are encrypted by using Linux Unified Key Setup (LUKS) is to manually type the password for disk decryption. When a system starts, the password must be entered manually to allow the system to mount the encrypted disk. Typing a passphrase is either not convenient or not possible for large data centers or cloud VM instances. Network-bound Disk Encryption (NBDE) securely automates the decryption of those encrypted disks without manually entering any passphrase at boot time, by ensuring that certain criteria are met. You can use NBDE to automatically decrypt LUKS storage devices that contain root and non-root file systems.
The architecture of NBDE uses two key components: the Clevis framework and the Tang server.
The Clevis framework is a pluggable framework that supports NBDE on the client side and automates unlocking LUKS-encrypted block devices.
The Tang server supports NBDE on the server side, and makes data available on a system when that system can reach the Tang server over a specific secure network.
The Clevis framework supports plug-ins, also called pins, to interact with Tang servers.
Both the Clevis framework and the Tang server use the JOSE framework as their back end for encryption and decryption.
Clevis gets a list of the keys for each Tang server, and uses one of those keys to generate an encryption key.
The Clevis pin then uses that encryption key to encrypt the data.
The encryption generates some state information, which is stored in the LUKS header.
That state information is accessible with the luksmeta show command.
The RHEL System Roles collection provides Ansible roles and modules to create consistent configurations for RHEL systems.
The rhel-system-roles package contains the nbde_client and nbde_server roles to automate the deployment of NBDE by using Clevis and Tang in one or more servers.
To use the RHEL System Roles, you must install the ansible-core and rhel-system-roles packages on the control node, and you must grant permissions and access to the managed nodes.
Use the nbde_server role to deploy and configure Tang servers:
---
- hosts: all
vars:
nbde_server_rotate_keys: yes
nbde_server_manage_firewall: true
nbde_server_manage_selinux: true
roles:
- rhel-system-roles.nbde_serverThe nbde_client role configures the Clevis client.
This role requires the volumes to be already encrypted with LUKS, and that the role can bind a volume to one or more NBDE servers.
You can preserve the existing passphrase or delete it.
If you remove the original passphrase, then the volume can be unlocked by using only NBDE.
If you provide a passphrase and a key file in the playbook, then the role uses the first entry and ignores all other entries.
You can use a Tang binding to map a device to one or more servers.
You can have multiple bindings for the same device.
To create or update a binding, set the state variable to the present value.
To remove a binding, set the state variable to the absent value.
The following example configures the Clevis client for two devices with two Tang servers:
---
- hosts: all
vars:
nbde_client_bindings:
- device: /dev/rhel/root
encryption_key_src: /etc/luks/keyfile
servers:
- http://server1.example.com
- http://server2.example.com
- device: /dev/rhel/swap
encryption_key_src: /etc/luks/keyfile
servers:
- http://server1.example.com
- http://server2.example.com
roles:
- rhel-system-roles.nbde_clientThe Clevis client requires networking to be available when mounting Tang bindings.
You can use the grubby tool to ensure that networking is available during the early boot process.
[root@host ~]# grubby --update-kernel=ALL --args="rd.neednet=1"If the RHEL System Role configuration method is not possible, then you can instead manually install and configure NBDE.
To begin configuring a Tang server, install the tang package.
This package installs the tangd service, which uses systemd socket activation, so it starts with the first connection.
Use the following command to enable socket activation for the tangd service:
[root@host ~]# systemctl enable tangd.socket --now
Created symlink from /etc/systemd/system/multi-user.target.wants/tangd.socket to /usr/lib/systemd/system/tangd.socket.By default, the tangd service binds to the 80/TCP port.
Red Hat Enterprise Linux blocks this port by default.
To stop the tangd service, disable the socket activation for that service as follows:
[root@host ~]# systemctl disable tangd.socket --now
Removed symlink /etc/systemd/system/multi-user.target.wants/tangd.socket.You can test whether a Tang server is accessible:
[root@host ~]# curl -f http://demotang.lab.example.com/advRed Hat recommends that you periodically rotate the signature and exchange keys that a Tang server uses.
The rotation interval for those keys depends on your application, key sizes, and organizational policies.
The Tang server stores the signature and exchange keys in the /var/db/tang directory.
To rotate the Tang server keys, rename the existing keys to include a dot as a prefix, and then generate new keys with the jose command for the JOSE framework, as follows:
[root@host ~]#cd /var/db/tang[root@host tang]#jose jwk gen -i '{"alg":"ES512"}' \ -o signature.jwk[root@host tang]#jose jwk gen -i '{"alg":"ECMR"}' \ o exchange.jwk
Existing client connections use the earlier keys and the Tang server uses the new keys automatically for new client bindings. When all existing client connections finish, you can safely remove the earlier keys.
You must update the clients to use the new keys. To refresh the client keys usage, bind the encrypted device with the tang server again by using the following command:
[root@host ~]# clevis luks bind -d /dev/DEVICE tang '{"url":"http://demotang.lab.example.com"}'To configure the Clevis framework with LUKS support, install the clevis, clevis-luks, and clevis-dracut packages.
The clevis luks bind command binds a block device to a Tang server.
The command also associates a binding policy with the device, which decrypts the device based on the Tang server availability.
Available binding policies include the REST HTTP escrow server policy, Shamir's Secret Sharing (SSS) policy, and the Tang binding server policy.
The following example binds the /dev/vda1 device to the demotang.lab.example.com Tang server:
[root@host ~]# clevis luks bind -d /dev/vda1 tang '{"url":"http://demotang.lab.example.com"}'The previous example uses the -d option to specify the device that binds to the Tang server.
The example also associates a binding policy, the Tang binding policy, to bind the device to the Tang server. A Tang binding server policy definition requires the base URL for the Tang server. Other policies are also available, such as the SSS policy.
If the policy requirements are not met, such as if the Tang server is unavailable, then the Clevis framework prompts for the LUKS passphrase during the boot process.
If you are configuring Clevis to decrypt a block device that contains the root file system, then you must re-create the initramfs image with the dracut -f command.
For other block devices, you must configure path-based execution by enabling the clevis-luks-askpass.path systemd unit as follows:
[root@host ~]# systemctl enable clevis-luks-askpass.path
Created symlink from /etc/systemd/system/remote-fs.target.wants/clevis-luks-askpass.path to /usr/lib/systemd/system/clevis-luks-askpass.path.The SSS policy supports the definition of complex policies with multiple Tang servers. You can define a policy with SSS that requires a minimum number of Tang servers to be available before a LUKS-encrypted block device can be decrypted.
The following example binds the /dev/vdb1 device to an SSS policy that defines three Tang servers and requires at least two of them to be available for automatic decryption to occur.
[root@host ~]#cfg=$'{"t":2,"pins":{"tang":[\n {"url":"http://demotang1.lab.example.com"},\n {"url":"http://demotang2.lab.example.com"},\n {"url":"http://demotang3.lab.example.com"}]}}'[root@host ~]#clevis luks bind -d /dev/vdb1 sss "$cfg"The advertisement contains the following signing keys:4R1tkfaTw-67bW0uxTAmTprUPooDo you wish to trust these keys? [ynYN]YThe advertisement contains the following signing keys:gks_IaVo1yog0KuQei95rg_yGnsDo you wish to trust these keys? [ynYN]YThe advertisement contains the following signing keys:vA5xAeUiKPqvkg4UyR4TemzXoAwDo you wish to trust these keys? [ynYN]YYou are about to initialize a LUKS device for metadata storage. Attempting to initialize it may result in data loss if data was already written into the LUKS header gap in a different format. A backup is advised before initialization is performed. Do you wish to initialize /dev/vdb1? [yn]yEnter existing LUKS password:demopass
For each Tang server, you must trust the key for that server.
Edit the /etc/crypttab file to specify the encrypted block devices to open, decrypt, and map at boot time.
This file contains an entry for each encrypted block device.
Two entries in /etc/crypttab might appear as follows:
decrypted1 /dev/vdb1 none _netdev decrypted2 UUID=43d8995e-b876-4385-b124-7e402446d6c7 none _netdev
The first field contains the name to use for the decrypted block device.
This name maps to the corresponding /dev/mapper/ device file.
In the example, name/dev/mapper/decrypted1 is the name of the first mapped and decrypted block device.
The second field includes either the device name or the LUKS UUID (from the cryptsetup luksUUID command) for the encrypted LUKS device.
In this example, the encrypted <device>/dev/vdb1 block device maps to the decrypted /dev/mapper/decrypted1 device mapping.
The encrypted block device that is labeled with the 43d8995e-b876-4385-b124-7e402446d6c7 LUKS UUID maps to the decrypted /dev/mapper/decrypted2 device mapping.
The third field specifies the absolute path to a file that contains the encryption password.
The field is set to none in the example, which has special meaning.
In this case, either the boot process pauses for the manual entry of the encryption password on the machine's console, or the boot process triggers block device decryption with NBDE.
Finally, the last field includes a comma-separated list of options, and in this case specifies only the _netdev option.
At boot time, NBDE attempts to unlock all block devices with the _netdev option.
If you are using NBDE Tang Servers to decrypt devices, include the _netdev option in the /dev/fstab file.
NBDE uses the network to contact those servers, and so decryption cannot occur until networking is available.
If you are not using NBDE and the device does not need the network to be available to be decrypted, then you can omit the fourth field or use other options such as the discard option.
When the LUKS-encrypted block device maps to the /dev/mapper/ device mapping, you can use the device mapping to mount this device to a specific mount point with the name/etc/fstab file.
The following example mounts the file system of the decrypted /dev/mapper/decrypted1 device mapping to the /encrypted directory.
This example assumes that the underlying file system on the device is XFS.
...output omitted...
/dev/mapper/decrypted1 /encrypted xfs _netdev 1 2You can use the /etc/crypttab file alone to configure device decryption at boot time with LUKS.
LUKS decrypts the device by prompting you to manually enter passwords into the console at boot time or by storing passwords in plain text on a decrypted device.
This way of decryption is inadequate for use cases where servers must boot unattended and still keep the decryption password secure.
NBDE provides a mechanism to automatically decrypt LUKS devices at boot time securely. This mechanism is based on two key components:
The Clevis client, which runs on the system, decrypts devices, and defines the policy whose conditions must be met for the data to be decrypted.
The Tang server, which Clevis clients contact to determine whether they are booting with access to a secure network and therefore decrypt their LUKS devices.
By using NBDE, you can prevent automatic decryption of a device that is removed from the data center.
clevis-encrypt-tang(1), clevis-encrypt-sss(1), and the jose-jwk-gen(1) man pages
For more information, refer to the Network-bound Disk Encryption chapter in the Red Hat Enterprise Linux 9 Security Hardening Guide at https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/security_hardening/configuring-automated-unlocking-of-encrypted-volumes-using-policy-based-decryption_security-hardening#network-bound-disk-encryption_configuring-automated-unlocking-of-encrypted-volumes-using-policy-based-decryption