In this article I will share the steps to configure CentOS/Red Hat Network Bound Disk Encryption (NBDE).
In our earlier articles we studied all about encrypting different types of disk devices and auto mount those LUKS devices to boot without password by using a key (/etc/crypttab
) instead of passphrase.
Now with those steps you have an overhead to create a key on individual Linux server (luksAddkey
) to boot without password. Assuming you have 100s of server then it will be very time consuming task.
Starting with RHEL 7.4 we can configure Network Bound Disk Encryption to use key from a specific LUKS Server to auto unmount LUKS device on client nodes within a network and boot without password.
We will cover below topics in this article
- Installing and enabling tang server
- Configuring the firewall for tang
- Showing the tang keys under
/var/db/tang
- Installing the clevis, clevis-luks, and clevis-dracut packages on the client
- Using "
clevis luks bind
" to bind to the tang server - Using "
dracut -f
" to generate a new initramfs - Simulating the client being removed from the environment, and no longer being able to connect to the tang server
Policy Based Decryption
The Policy-Based Decryption (PBD) is a collection of technologies that enable unlocking encrypted root and secondary volumes of hard drives on physical and virtual machines. The Network Bound Disk Encryption (NBDE) is a subcategory of PBD that allows binding encrypted volumes to a special network server to boot without password. The current implementation of the NBDE uses Clevis and Tang encryption which includes a Clevis pin for Tang server and the Tang server itself.
Let us understand some new terminologies we will use in this article
Tang:
Tang is a server for binding data to network presence. It makes a system containing your data available when the system is bound to a certain secure network. Tang is stateless and does not require TLS or authentication.
Clevis:
Clevis is a pluggable framework for automated decryption. In NBDE, Clevis provides automated unlocking of LUKS volumes. The clevis package provides the client side of the feature.
Clevis and Tang encryption are generic client and server components that provide network bound disk encryption. In Red Hat Enterprise Linux, they are used in conjunction with LUKS to encrypt and decrypt root and non-root storage volumes to accomplish Network Bound Disk Encryption (NBDE).
Both client- and server-side components use the José library to perform encryption and decryption operations.
How Network Bound Disk Encryption (NBDE) works?
- The Clevis pin for Tang Server uses one of the public keys to generate a unique, cryptographically-strong encryption key.
- Once the data is encrypted using this key, the key is discarded. This process of encrypting data is the provisioning step.
- When the client is ready to access its data, it loads the metadata produced in the provisioning step and it responds to recover the encryption key. This process is the recovery step.
- In NBDE, Clevis binds a LUKS volume using a pin so that it can be automatically unlocked.
- After successful completion of the binding process, the disk can be unlocked using the provided Dracut unlocker.
Lab Environment
I have created two Virtual Machines to configure Clevis and Tang Encryption on Oracle VirtualBox wherein the server is installed with RHEL 8.1 while client is installed with CentOS 8.0
On my client node centos-8
, I have already migrated my entire root file system to LUKS encrypted device which now requires a key every time I reboot the node. So on my client I will install and configure clevis while on my server, rhel-8
I will configure tang server to perform Network Bound Disk Encryption (boot without password) every time my client centos-8
reboots.
Server → rhel-8.example.com → 192.168.0.121 → RHEL 8.1
Client → centos-8.example.com → 192.168.0.119 → CentOS 8.0
Below are the OS installed on my client and server node.
[root@centos-8 ~]# cat /etc/redhat-release CentOS Linux release 8.0.1905 (Core) [root@rhel-8 ~]# cat /etc/redhat-release Red Hat Enterprise Linux release 8.1 (Ootpa)
Configure Server (RHEL 8)
We will configure tang server using it's default port and settings on rhel-8
which will act as our server. By default tang is configured to use port 80 but you can also configure tang server to use a different custom port for enhanced security.
Install and Configure Tang server
To enable Clevis and tang Encryption, we will first install tang rpm on our server node using yum
[root@rhel-8 ~]# yum -y install tang
Next start and enable the tangd
socket. Because tangd
uses the systemd
socket activation mechanism, the server starts as soon as the first connection comes in. A new set of cryptographic keys is automatically generated at the first start.
[root@rhel-8 ~]# systemctl enable tangd.socket --now Created symlink /etc/systemd/system/multi-user.target.wants/tangd.socket → /usr/lib/systemd/system/tangd.socket.
For testing purpose I have disabled firewalld
, nftables
and selinux
in my setup
[root@rhel-8 ~]# systemctl disable firewalld --now
But if you wish to use firewalld
, then you can add below rule
# firewall-cmd --add-port=80/tcp # firewall-cmd --runtime-to-permanent
firewalld
rule assuming the port you select is 7500
# firewall-cmd --add-port=7500/tcp # firewall-cmd --runtime-to-permanent
Similarly for selinux use semanage port -a -t tangd_port_t -p tcp 7500
Also, you must add below content in /etc/systemd/system/tangd.socket.d/override.conf
[Socket] ListenStream= ListenStream=7500
And reload the changed configuration:
# systemctl daemon-reload
Check that your configuration is working:
[root@rhel-8 ~]# systemctl show tangd.socket -p Listen
Listen=[::]:80 (Stream)
List tang server keys
The keys from tang server are available under /var/db/tang
which will be used for Network Bound Disk Encryption (NBDE) by client.
[root@rhel-8 ~]# ls -l /var/db/tang/ total 8 -rw-r--r-- 1 root tang 349 Nov 21 11:36 7VXZSkDbTEqqIh7TqoXG6u82LK0.jwk -rw-r--r-- 1 root tang 354 Nov 21 11:36 -NYm6-gTZ9dquHe6zy9ynGU8SAI.jwk
Now we will open a terminal of our tang server and execute journalctl -f
to monitor the live incoming logs on our tang server i.e. rhel-8.example.com
[root@rhel-8 ~]# journalctl -f -- Logs begin at Wed 2019-11-20 17:52:06 IST. -- Nov 21 11:46:12 rhel-8.example.com tangd[4454]: 192.168.0.119 POST /rec/7VXZSkDbTEqqIh7TqoXG6u82LK0 => 200 (src/tangd.c:168) Nov 21 11:48:33 rhel-8.example.com systemd[1]: Started Tang Server (192.168.0.119:53408). Nov 21 11:48:33 rhel-8.example.com tangd[4461]: 192.168.0.119 POST /rec/7VXZSkDbTEqqIh7TqoXG6u82LK0 => 200 (src/tangd.c:168) Nov 21 11:49:49 rhel-8.example.com systemd[1]: Started Tang Server (192.168.0.119:60284). Nov 21 11:49:49 rhel-8.example.com tangd[4465]: 192.168.0.119 POST /rec/7VXZSkDbTEqqIh7TqoXG6u82LK0 => 200 (src/tangd.c:168)
Configure Client
Next continue with the clevis and tang encryption configuration on client node centos-8
. Connect to client node centos-8
using a terminal or ssh client.
Now we have already migrated our entire file system to LUKS encrypted device which now prompts for password in every reboot. Here we wish to configure Network Based Disk Encryption to enable boot without password using the keys from tang server (rhel-8
) to unlock the LUKS device.
Install and configure Clevis
To automatically unlock an existing LUKS-encrypted root volume and boot without password install these packages on client node which contains the LUKS encrypted partition:
[root@centos-8 ~]# yum -y install clevis clevis-luks clevis-dracut
Verify the available key slots using luksDump
. As you see highlighted section we currently only have one key slot used i.e. 0:luks2
[root@centos-8 ~]# cryptsetup luksDump /dev/sdb1 <Output trimmed> Keyslots: 0: luks2 Key: 256 bits Priority: normal Cipher: aes-xts-plain64 PBKDF: argon2i Time cost: 4 Memory: 572835 Threads: 1 Salt: 2b f5 65 0e 50 36 d9 5a 2c 90 e9 e6 61 c8 db bc ba 86 1b cd ea 79 cd b8 b1 cc 8d 20 84 29 fb 87 AF stripes: 4000 Area offset:32768 [bytes] Area length:131072 [bytes] Digest ID: 0 <Output trimmed>
Identity the LUKS device
Identify the LUKS-encrypted volume for Policy Based Decryption using NBDE. In the following example, the block device is referred as /dev/sdb1
:
[root@centos-8 ~]# blkid -t TYPE=crypto_LUKS -o device /dev/sdb1
So our LUKS encrypted device is /dev/sdb1
To enable Clevis and tang Encryption, bind the encrypted volume to a tang server using the clevis luks bind
command:
[root@centos-8 ~]# clevis luks bind -d /dev/sdb1 tang '{"url":"192.168.0.121"}'
The advertisement contains the following signing keys:
-NYm6-gTZ9dquHe6zy9ynGU8SAI
Do you wish to trust these keys? [ynYN] Y
Enter existing LUKS password:
This command performs four steps:
- Creates a new key with the same entropy as the LUKS master key.
- Encrypts the new key with Clevis.
- Stores the Clevis JWE object in the LUKS2 header token or uses LUKSMeta if the non-default LUKS1 header is used.
- Enables the new key for use with LUKS.
luks bind
command takes one of the slots.The LUKS encrypted volume can now be unlocked with your existing password as well as with the Clevis policy.
Now if you verify we have two keys installed for our LUKS encrypted device as highlighted:
[root@centos-8 ~]# cryptsetup luksDump /dev/sdb1 <Output trimmed> Keyslots: 0: luks2 Key: 256 bits Priority: normal Cipher: aes-xts-plain64 PBKDF: argon2i Time cost: 4 Memory: 572835 Threads: 1 Salt: 2b f5 65 0e 50 36 d9 5a 2c 90 e9 e6 61 c8 db bc ba 86 1b cd ea 79 cd b8 b1 cc 8d 20 84 29 fb 87 AF stripes: 4000 Area offset:32768 [bytes] Area length:131072 [bytes] Digest ID: 0 1: luks2 Key: 256 bits Priority: normal Cipher: aes-xts-plain64 PBKDF: argon2i Time cost: 4 Memory: 560933 Threads: 1 Salt: 11 4b dd b5 f7 c9 72 74 90 a5 3e b2 7e 37 37 fa e0 42 d5 7d 7e 18 19 56 ec c4 31 e3 cb 4b 25 d6 AF stripes: 4000 Area offset:163840 [bytes] Area length:131072 [bytes] Digest ID: 0 <Output trimmed>
To enable the early boot system to process the disk binding and boot without password, enter the following commands on an already installed system:
[root@centos-8 ~]# dracut -f
We are all set up here, now you can reboot the client node centos-8
and observe the node console.
Here as you see, during boot up stage the client prompts for LUKS encrypted passphrase for our root file system. But after waiting for few seconds it gets the key from the tang server (rhel-8
) and continues to boot without password.
Lastly I hope the steps from the article to configure Network Bound Disk Encryption and enable boot without password using clevis and tang encryption on CentOS/RHEL 7/8 Linux was helpful. So, let me know your suggestions and feedback using the comment section.
References:
How to set up Network Bound Disk Encryption with multiple LUKS devices (Clevis and Tang encryption)
Configuring Automated Unlocking Of Encrypted Volumes Using Policy-Based Decryption (Boot without Password)
On Oracle Linux 8.7 I’m getting this:
The advertisement contains the following signing keys:
I’ve tried the Red Hat automated solution in Chapter 10.10 of the RHEL8 admin guide in my kickstart script.
It is failing. Notice the “-k-” below in Red Hat’s example.
Perhaps they have a typo.
The I believe expect script should be the way to go.
I’ve been trying to automate this into kickstart, or a post-kickstart script, for touch-free installs, but cannot get past the “clevis luks bind” prompting for a “y/Y/n/N? to trust the key”.
Do you wish to trust these keys? [ynYN] Y
Any ideas?
You can check the man page of clevis tool to perform task forcefully. For example for bind operation you can use
-f
or you will have to write an expect script to provide the response and automate.After installing tang and enabling it —
the keys in path /var/db/tang was not auto created and getting below error :
entry added in iptables to accept tcp connections on port 3212 as well.
What did I miss ? Please help.
you can try disabling firewall and selinux for testing purpose and check
Thanks admin. Issue was resolved once I used the hostname and custom port combination for tang url param.
But, may i know if we still need to add the entries in the cryptab n fstab. Note: my encryptedFS is the data FS n not root.
I can’t remember if I tried, it is quiet some time since I verified and wrote this article. If possible you can test and share your observation for data partition.
If you have a static IP for your client, you need to use the following:
dracut -f –kernel-cmdline “ip=client_ip netmask= client_netmask gateway= client_gateway_ip nameserver= client_DNS_ip”
instead of just
dracut -f
Otherwise you will continue to be prompted for the root disk password.