Note:
- This tutorial is available in an Oracle-provided free lab environment.
- It uses example values for Oracle Cloud Infrastructure credentials, tenancy, and compartments. When completing your lab, substitute these values with ones specific to your cloud environment.
Use Network Bound Disk Encryption on Oracle Linux
Introduction
The following tutorial shows you how to configure an Oracle Linux system with disk encryption that is dependent on a network based key service.
Background
In this lab you create an encrypted XFS file system that is automatically unlocked at boot when on the same network as your key server. This tutorial is targeted at users of Oracle Linux 8 or later.
Components
- Linux Unified Key Setup (LUKS) is a disk encryption standard.
- Cryptsetup configures disk based encryption and includes support for LUKS
- Tang is a network service that provides cryptographic services over HTTP
- Clevis is an encryption framework. Clevis can use keys provided by Tang as a passphrase to unlock LUKS volumes
What Do You Need?
- Two systems with Oracle Linux 8 installed.
- A disk or block device attached to one system to use for encrypted storage.
Install and Configure Tang on the Server Instance
Note: When using the free lab environment, see Oracle Linux Lab Basics for connection and other usage instructions.
Install Tang, allow it to receive requests on port 80 and start the service.
-
Open a terminal and connect to your server instance.
-
Install the Tang package
sudo dnf install -y tang
-
Note the IP address of the server instance in the local network:
ip addr sh|grep inet
In this lab environment, the server IP address is configured to be 10.0.0.150 by default.
-
Add a trusted zone for the network and allow the required port through the firewall for systems in the trusted zone
sudo firewall-cmd --zone=trusted --add-source=10.0.0.0/24 sudo firewall-cmd --zone=trusted --add-service=http sudo firewall-cmd --runtime-to-permanent
-
Enable the service
sudo systemctl enable --now tangd.socket
Create an Encrypted File System on the Client Instance
Create a passphrase based encrypted disk device, a file system on top of that device and mount it as /encrypted
.
-
Open a terminal and connect to your client instance.
-
Install the
cryptsetup
packagesudo dnf install -y cryptsetup
-
Check the available block devices to make sure that an empty disk is available to host the encrypted file system.
lsblk
The output displays similarly to the following:
```shell
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 46.6G 0 disk
????/sda1 8:1 0 100M 0 part /boot/efi
????/sda2 8:2 0 1G 0 part /boot
????/sda3 8:3 0 45.5G 0 part
????/ocivolume-root 252:0 0 35.5G 0 lvm /
????/ocivolume-oled 252:1 0 10G 0 lvm /var/oled
sdb 8:16 0 50G 0 disk
```
Note that sdb
is listed as an empty disk. This block device is preconfigured and attached to the client compute instance for this tutorial.
-
Encrypt the disk by using LUKS.
sudo cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 \ --key-size 512 --hash sha256 --use-random --force-password /dev/sdb
The following warning is displayed and you must confirm that you wish to continue by entering ‘YES’ in uppercase. You must also specify a LUKS passphrase that can be used to decrypt the disk. Make sure you note down this passphrase for future use.
```
WARNING!
========
This will overwrite data on /dev/sdb irrevocably.
Are you sure? (Type uppercase yes): YES
Enter passphrase for /dev/sdb:
Verify passphrase:
Key slot 0 created.
Command successful.
```
The options presented in this example are demonstrative and you may need to alter the cipher, hash and key size to fit your environment on a production system. Note that we used the --force-password
option in this tutorial to allow you to specify a low quality passphrase for the LUKS key. If this option is not specified, LUKS uses the pwquality.so
module to enforce passphrase complexity.
-
Unlock the block device using the passphrase that you created in the previous step.
sudo cryptsetup --verbose luksOpen /dev/sdb demodisk
You are prompted for your passphrase:
```shell
Enter passphrase for /dev/sdb:
Key slot 0 unlocked.
Command successful.
```
A device named demodisk is available under /dev/mapper.
```shell
ls -la /dev/mapper/demodisk
```
The following output is displayed:
```shell
lrwxrwxrwx. 1 root root 7 Jun 7 10:20 /dev/mapper/demodisk -> ../dm-2
```
-
Create a file system on the encrypted disk
sudo mkfs.xfs /dev/mapper/demodisk
-
Identify the UUID of the new filesytem
blkid -s UUID /dev/mapper/demodisk
The UUID is displayed as follows:
```
/dev/mapper/demodisk: UUID="4057664e-122f-421d-bcb6-2cb5a068a4d8"
```
Note the UUID for the next step. The easiest way to do this is to store the value in an environment variable that can be re-used in subsequent steps. For example:
```shell
DEMODISK_ID=$(sudo blkid -s UUID /dev/mapper/demodisk |grep -oP 'UUID="\K[^"]+')
```
-
Create a fstab entry for the file system using the UUID for the new file system that you created
echo "UUID=$DEMODISK_ID /encrypted xfs defaults 0 0" | sudo tee -a /etc/fstab
-
Mount the file system
sudo mkdir /encrypted sudo mount /encrypted
Add a remote key to the encrypted device
Use Clevis to add an additional passphrase to open the encrypted device.
-
Install the required Clevis packages
sudo dnf install -y clevis-systemd clevis-luks
-
View the keys
Note there is one keyslot in use, keyslot 0. In the next step you use an additional keyslot.
sudo cryptsetup luksDump /dev/sdb
The following output is displayed
```shell
LUKS header information
Version: 2
Epoch: 3
Metadata area: 16384 [bytes]
Keyslots area: 16744448 [bytes]
UUID: 61ff409e-6e38-4172-8756-e9f6fadf58c1
Label: (no label)
Subsystem: (no subsystem)
Flags: (no flags)
Data segments:
0: crypt
offset: 16777216 [bytes]
length: (whole device)
cipher: aes-xts-plain64
sector: 512 [bytes]
Keyslots:
0: luks2
Key: 512 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: argon2i
Time cost: 4
Memory: 609527
Threads: 2
Salt: b4 3c b8 ac 9a ff 50 c1 5a 4d 3b 61 23 6f 0b 12
bf 63 1f c5 7b db 17 2f d1 a4 63 98 02 80 8c e7
AF stripes: 4000
AF hash: sha256
Area offset:32768 [bytes]
Area length:258048 [bytes]
Digest ID: 0
Tokens:
Digests:
0: pbkdf2
Hash: sha256
Iterations: 81209
Salt: 8f 67 0e e1 4f 4f 25 c6 6e 9a 4c 39 17 8a 7d 72
d3 6e 60 fd e6 19 81 69 d5 0b 92 9f 8a 5c f5 80
Digest: 8c 1d c2 13 cf a6 91 9c 01 37 9c 42 a9 7e 4d e1
22 94 7d 63 44 8b e2 5a 5c b7 a0 ab dc 4a 32 99
```
-
Bind the remote tang key to a LUKS slot using Clevis.
sudo clevis luks bind -d /dev/sdb tang '{"url":"http://10.0.0.150"}'
You are prompted to confirm that you trust the key provided by the Tang server. Note that you connect to the Tang server on a trusted network IP address. If you bind the LUKS slot to the Tang server on a public IP address the disk can be unlocked from anywhere on the Internet, which is more than likely not desirable.
```shell
The advertisement contains the following signing keys:
9PZH7moczWcBukwc8esiW-dMAJs
Do you wish to trust these keys? [ynYN] y
Enter existing LUKS password:
```
Because no private keys are exchanged between the keyserver and the host with the encrypted disk you may determine TLS is not required in your environment. A reverse proxy may be used to do SSL/TLS termination for Tang as Clevis supports HTTPS.
If you choose to use HTTPS then your host with the encrypted disk must trust the Certificate Authority used to sign the reverse proxy, see update-ca-trust(8)
-
Show that a new keyslot in use by Clevis in slot 1
sudo cryptsetup luksDump /dev/sdb
Output similar to the following is displayed.
```shell
LUKS header information
Version: 2
Epoch: 5
Metadata area: 16384 [bytes]
Keyslots area: 16744448 [bytes]
UUID: 61ff409e-6e38-4172-8756-e9f6fadf58c1
Label: (no label)
Subsystem: (no subsystem)
Flags: (no flags)
Data segments:
0: crypt
offset: 16777216 [bytes]
length: (whole device)
cipher: aes-xts-plain64
sector: 512 [bytes]
Keyslots:
0: luks2
Key: 512 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: argon2i
Time cost: 4
Memory: 609527
Threads: 2
Salt: b4 3c b8 ac 9a ff 50 c1 5a 4d 3b 61 23 6f 0b 12
bf 63 1f c5 7b db 17 2f d1 a4 63 98 02 80 8c e7
AF stripes: 4000
AF hash: sha256
Area offset:32768 [bytes]
Area length:258048 [bytes]
Digest ID: 0
1: luks2
Key: 512 bits
Priority: normal
Cipher: aes-xts-plain64
Cipher key: 512 bits
PBKDF: argon2i
Time cost: 4
Memory: 475561
Threads: 2
Salt: d8 fb 40 68 9c ed fa 65 c5 53 a3 3a f6 25 75 98
c9 39 9d e2 b8 78 56 6a 02 24 60 55 96 8d 68 18
AF stripes: 4000
AF hash: sha256
Area offset:290816 [bytes]
Area length:258048 [bytes]
Digest ID: 0
Tokens:
0: clevis
Keyslot: 1
Digests:
0: pbkdf2
Hash: sha256
Iterations: 81209
Salt: 8f 67 0e e1 4f 4f 25 c6 6e 9a 4c 39 17 8a 7d 72
d3 6e 60 fd e6 19 81 69 d5 0b 92 9f 8a 5c f5 80
Digest: 8c 1d c2 13 cf a6 91 9c 01 37 9c 42 a9 7e 4d e1
22 94 7d 63 44 8b e2 5a 5c b7 a0 ab dc 4a 32 99
```
Mount the encrypted file system on boot
Configure the system to unlock the encrypted device and mount the file system on boot.
-
Identify the block device UUID for later use
sudo blkid -s UUID /dev/sdb
Output similar to the following is displayed:
/dev/sdb: UUID="74f0faf1-9cb9-45f9-a3d8-ef276263d729"
Note the UUID for the next step. The easiest way to do this is to store the value in an environment variable that can be re-used in subsequent steps. For example:
```shell
SDB_ID=$(sudo blkid -s UUID /dev/sdb |grep -oP 'UUID="\K[^"]+')
```
-
Enable the
clevis-luks-askpass
Systemd service:sudo systemctl enable clevis-luks-askpass.path
-
Have the block device unlocked during boot
The file /etc/crypttab
defines how encrypted devices are handled during boot
```shell
echo "encrypteddisk UUID=$SDB_ID - _netdev" | sudo tee -a /etc/crypttab
```
-
Mount the file system later in the boot
To ensure the disk is unlocked before the file system is mounted, update the
/etc/fstab
sudo vi /etc/fstab
and change the line for the /encrypted
mount from
```shell
UUID=4057664e-122f-421d-bcb6-2cb5a068a4d8 /encrypted xfs defaults 0 0
```
to
```shell
/dev/mapper/encrypteddisk /encrypted xfs _netdev 0 0
```
Use the /dev/mapper
path for readability and ensure systemd dependencies are generated and _netdev
to indicate it is dependent on network devices being available.
This step can be achieved directly from the command line by running:
```shell
sudo sed -i '/\/encrypted/d' /etc/fstab
echo '/dev/mapper/encrypteddisk /encrypted xfs _netdev 0 0'|sudo tee -a /etc/fstab
```
-
Restart the client instance to verify the file system is mounted at boot
sudo reboot
Once the instance has restarted and you are able to reconnect, confirm that the encrypted file system is mounted correctly.
```shell
df -h /encrypted/
```
The following output is displayed:
```shell
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/demodisk 50G 389M 50G 1% /encrypted
```
Appendix: Unlock encrypted root during boot
If you have a system with an encrypted root disk you can register a key with the clevis luks bind
command described above. To allow an early unlocking you must install a RPM and rebuild the initramfs image as described in the following step.
The Oracle Linux Cloud Infrastructure instances used in this lab do not have an encrypted root disks so it is not possible to demonstrate this functionality in this lab.
-
Install the
clevis-dracut
packagesudo dnf install -y clevis-dracut
-
Rebuild boot files
sudo dracut -fv
If your system does not use DHCP then you must also pass network configuration information to initramfs so it can access your Tang server before root is mounted. For more information see the Network section of dracut.cmdline(7)
For More Information
Other resources specific to this tutorial:
More Learning Resources
Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.
For product documentation, visit Oracle Help Center.
Use Network Bound Disk Encryption on Oracle Linux
F43831-05
May 2022
Copyright © 2021, Oracle and/or its affiliates.