Use Network Bound Disk Encryption on Oracle Linux
Introduction
This tutorial demonstrates how to configure an Oracle Linux system with Linux Unified Key Setup (LUKS) disk encryption that is dependent on a network-based key service consisting of Tang and Clevis . You will create an encrypted XFS file system that is automatically unlocked at boot when on the same network as your key server.
Objectives
In this tutorial, you'll learn how to:
- Set up LUKS using cryptsetup , which provides the tooling for disk-based encryption and includes support for LUKS.
- Configure Tang as a network service that provides cryptographic services over HTTP.
- Use Clevis for the network encryption framework. Clevis can use keys provided by Tang as a passphrase to unlock LUKS volumes.
Prerequisites
Minimum of two Oracle Linux systems
Each system should have Oracle Linux installed and configured with:
- A non-root user account with sudo access
- Access to the Internet
- A disk or block device attached to the system to use for encrypted storage
Deploy Oracle Linux
Note: If running in your own tenancy, read the linux-virt-labs
GitHub project README.md and complete the prerequisites before deploying the lab environment.
Open a terminal on the Luna Desktop.
Clone the
linux-virt-labs
GitHub project.git clone https://github.com/oracle-devrel/linux-virt-labs.git
Change into the working directory.
cd linux-virt-labs/ol
Install the required collections.
ansible-galaxy collection install -r requirements.yml
Update the Oracle Linux instance configuration.
cat << EOF | tee instances.yml > /dev/null compute_instances: 1: instance_name: "ol-node-01" type: "server" 2: instance_name: "ol-node-02" type: "server" use_nginx: true passwordless_ssh: true EOF
Deploy the lab environment.
ansible-playbook create_instance.yml -e localhost_python_interpreter="/usr/bin/python3.6" -e "@instances.yml" -e add_block_storage=true -e block_count=1
The free lab environment requires the extra variable
local_python_interpreter
, which setsansible_python_interpreter
for plays running on localhost. This variable is needed because the environment installs the RPM package for the Oracle Cloud Infrastructure SDK for Python, located under the python3.6 modules.The default deployment shape uses the AMD CPU and Oracle Linux 8. To use an Intel CPU or Oracle Linux 9, add
-e instance_shape="VM.Standard3.Flex"
or-e os_version="9"
to the deployment command.Important: Wait for the playbook to run successfully and reach the pause task. At this stage of the playbook, the installation of Oracle Linux is complete, and the instances are ready. Take note of the previous play, which prints the public and private IP addresses of the nodes it deploys and any other deployment information needed while running the lab.
Install and Configure Tang on the Server Instance
Open a terminal and connect via SSH to the ol-node-01 instance.
ssh oracle@<ip_address_of_instance>
Install the Tang package.
sudo dnf install -y tang
Note the IP address of the server instance in the local network.
hostname -I | awk '{print $1}'
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
Open a terminal and connect via SSH to the ol-node-02 instance.
ssh oracle@<ip_address_of_instance>
Install the cryptsetup package.
sudo 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
Example Output:
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 you can use to decrypt the disk. Make sure you note down this passphrase for future use.
Example Output:
WARNING! ======== This will overwrite data on /dev/sdb irrevocably. Are you sure? (Type 'yes' in capital letters): YES Enter passphrase for /dev/sdb: Verify passphrase:
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. LUKS uses the pwquality.so module to enforce passphrase complexity if this option is not specified.Unlock the block device using the passphrase that you created in the previous step.
sudo cryptsetup --verbose luksOpen /dev/sdb demodisk
Provide a passphrase when prompted.
Example Output:
Enter passphrase for /dev/sdb: Key slot 0 unlocked. Command successful.
A device named demodisk is available under /dev/mapper.
ls -la /dev/mapper/demodisk
Example Output:
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 filesystem.
blkid -s UUID /dev/mapper/demodisk
Example Output:
/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 we can reuse in subsequent steps.
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 newly created file system.
echo "UUID=$DEMODISK_ID /encrypted xfs defaults 0 0" | sudo tee -a /etc/fstab
Reload
systemd
to pick up the change to fstab.sudo systemctl daemon-reload
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
Example Output:
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://ol-node-01"}'
A prompt appears asking you to confirm you trust the key the Tang server provides. Note that you connect to the Tang server using a trusted network IP address. If you bind the LUKS slot to the Tang server on a public IP address, you can unlock the disk from anywhere on the Internet, which is more than likely undesirable.
Example Output:
The advertisement contains the following signing keys. 9PZH7moczWcBukwc8esiW-dMAJs Do you wish to trust these keys? [ynYN] y Enter existing LUKS password:
Since the keyserver and the host with the encrypted disk do not exchange private keys, you may not require TLS in your environment. However, using TLS is recommended. Therefore, you can use a reverse proxy to terminate Tang's SSL/TLS, as Clevis supports HTTPS.
If you choose to use HTTPS, your host with the encrypted disk must trust the Certificate Authority used to sign the reverse proxy. See the
update-ca-trust(8)
manual page for more details.Show that Clevis is using a new keyslot in slot 1.
sudo cryptsetup luksDump /dev/sdb
Example Output:
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.
sudo blkid -s UUID /dev/sdb
Example Output:
/dev/sdb: UUID="74f0faf1-9cb9-45f9-a3d8-ef276263d729"
Store the UUID value in an environment variable.
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 the boot process handles encrypted devices.echo "encrypteddisk UUID=$SDB_ID - _netdev" | sudo tee -a /etc/crypttab > /dev/null
Mount the file system to ensure the disk is unlocked before the file system is mounted.
sudo sed -i '/\/encrypted/d' /etc/fstab echo '/dev/mapper/encrypteddisk /encrypted xfs _netdev 0 0'|sudo tee -a /etc/fstab > /dev/null
Restart the client instance to verify the file system mounts at boot.
sudo reboot
Wait until the instance has restarted, and you can reconnect before proceeding.
Confirm that the encrypted file system is mounted correctly.
df -h /encrypted/
Example Output:
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 using the clevis luks bind
command described above. To allow an early unlocking, you must install an RPM and rebuild the initramfs image as described in the following step.
Note: The Oracle Linux Cloud Infrastructure instances used in this tutorial do not have an encrypted root disk, so it is impossible to demonstrate this functionality.
Install the
clevis-dracut
package.sudo 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 the root filesystem is mounted. For more information, see the Network section of the dracut.cmdline(7)
manual page.
Next Steps
You should now be able to configure and use an Oracle Linux system with disk encryption on a network-based key service. Check out our other storage management content on the Oracle Linux Training Station.
Related Links
Other resources specific to this tutorial: