Oracle by Example brandingOracle Linux Disk Encryption Using Network Based Key Services

section 0Before You Begin

This 20-minute tutorial shows you how to configure an Oracle Linux system with disk encryption that's dependent on a network based key service.

Background

In this lab we will create an encrypted XFS filesystem that's automatically unlocked at boot when on the same network as our key server. This lab uses Oracle Linux 8 but the same tools are available on Oracle Linux 7.

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?

Environment

This lab involves multiple VMs and you will need to perform different steps on different VMs. The easiest way to do this is through the vagrant command

vagrant ssh <hostname>

Once connected you can return to your desktop with a standard logout or exit command.

For example

    [user@demo lab]$ vagrant ssh keyserver
    Last login: Tue Aug 20 23:56:58 2019 from 10.0.2.2
    [vagrant@keyserver ~]$ hostname
    keyserver.vagrant.vm
    [vagrant@keyserver ~]$ exit
    logout
    Connection to 127.0.0.1 closed.
    [user@demo lab]$ vagrant ssh appserver
    Last login: Tue Aug 20 05:25:49 2019 from 10.0.2.2
    [vagrant@appserver ~]$ hostname
    appserver.vagrant.vm
    [vagrant@appserver ~]$ logout
    Connection to 127.0.0.1 closed.

The Oracle Linux VirtualBox template includes an unused second virtual disk (/dev/sdb) which we will use to store our encrypted data.


section 1Start the lab environment

You will first download and start the VMs we will be using in this lab environment. This is simplified through the use of Vagrant.

  1. Download the lab configuration
    [user@demo lab]$ git clone https://github.com/oracle/linux-labs.git
  2. Change to the lab directory
    [user@demo lab]$ cd linux-labs/NBDE/
  3. Install the Vagrant plugin

    To automatically configure the /etc/hosts file of our VMs we use the vagrant-hosts plugin

    [user@demo NBDE]$ vagrant plugin install vagrant-hosts
  4. Start the lab virtual machines
    [user@demo NBDE]$ vagrant up

Vagrant will download an Oracle Linux 8 image and create two virtual machines.

Remember you can access them using the vagrant ssh hostname command mentioned above and you do not need to connect via address.

section 2Configure the key server

Install Tang, allow it to receive requests on port 80 and start the service.

We perform this step on the VM keyserver, connecting with the vagrant ssh keyserver command.

  1. Install the RPMs
    [vagrant@keyserver ~]$ sudo dnf install -y tang
  2. Allow the required port through the firewall
    [vagrant@keyserver ~]$ sudo firewall-cmd --add-service=http --permanent
    [vagrant@keyserver ~]$ sudo firewall-cmd --reload
  3. Enable the service
    [vagrant@keyserver ~]$ sudo systemctl enable --now tangd.socket
  4. Refresh the Tang cache
    [vagrant@keyserver ~]$ sudo systemctl restart tangd-update

section 3Create an encrypted filesystem on appserver

Create a passphrase based encrypted disk device, a filesystem on top of that device and mount it as /encrypted.

We perform this step on the VM appserver, connecting with the vagrant ssh appserver command.

  1. Install the RPMs
    [vagrant@appserver ~]$ sudo dnf install -y cryptsetup
  2. Create an encrypted disk
    [vagrant@appserver ~]$ sudo cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 --key-size 512 --hash sha256 --use-random /dev/sdb
    
    WARNING!
    ========
    This will overwrite data on /dev/sdb irrevocably.
    
    Are you sure? (Type uppercase yes): YES
    Enter passphrase for /dev/sdb: examplepassphrase
    Verify passphrase: examplepassphrase
    Key slot 0 created.
    Command successful.                  

    These options are given as an example and you may need to alter the cipher, hash and key size to fit your environment.

  3. Unlock the block device for use
    [vagrant@appserver ~]$ sudo cryptsetup --verbose luksOpen /dev/sdb demodisk 
    Enter passphrase for /dev/sdb: examplepassphrase
    Key slot 0 unlocked.
    Command successful.
    

    This has created a device of demodisk under /dev/mapper

    [vagrant@appserver ~]$ ls -la /dev/mapper/demodisk
    lrwxrwxrwx. 1 root root 7 Feb  3 04:05 /dev/mapper/demodisk -> ../dm-2
  4. Create a filesystem on the encrypted disk
    [vagrant@appserver ~]$ sudo mkfs.xfs /dev/mapper/demodisk
    meta-data=/dev/mapper/demodisk   isize=512    agcount=4, agsize=1023488 blks
             =                       sectsz=512   attr=2, projid32bit=1
             =                       crc=1        finobt=1, sparse=1, rmapbt=0
             =                       reflink=1
    data     =                       bsize=4096   blocks=4093952, imaxpct=25
             =                       sunit=0      swidth=0 blks
    naming   =version 2              bsize=4096   ascii-ci=0, ftype=1
    log      =internal log           bsize=4096   blocks=2560, version=2
             =                       sectsz=512   sunit=0 blks, lazy-count=1
    realtime =none                   extsz=4096   blocks=0, rtextents=0
  5. Identify the UUID of the new filesytem
    [vagrant@appserver ~]$ sudo blkid -s UUID  /dev/mapper/demodisk
    /dev/mapper/demodisk: UUID="4057664e-122f-421d-bcb6-2cb5a068a4d8"
    
  6. Create a fstab entry for the filesystem
    [vagrant@appserver ~]$ echo "UUID=4057664e-122f-421d-bcb6-2cb5a068a4d8 /encrypted xfs defaults 0 0" | sudo tee -a /etc/fstab
  7. Mount the filesystem
    [vagrant@appserver ~]$ sudo mkdir /encrypted
    [vagrant@appserver ~]$ sudo mount /encrypted                

section 4Add a remote key to the encrypted device

Use Clevis to add an additional passphrase to open the encrypted device.

  1. Install the RPMs
    [vagrant@appserver ~]$ sudo dnf install -y clevis-systemd clevis-luks
  2. View the keys

    Note there is one keyslot in use, keyslot 0. In the next step we will use an additional keyslot.

    [vagrant@appserver ~]$ sudo cryptsetup luksDump /dev/sdb
    LUKS header information
    Version:        2
    Epoch:          3
    Metadata area:  16384 [bytes]
    Keyslots area:  16744448 [bytes]
    UUID:           74f0faf1-9cb9-45f9-a3d8-ef276263d729
    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:     652621
            Threads:    2
            Salt:       89 f8 d9 3f 82 d3 e7 a9 5c c3 0e 97 4a b2 17 96
                        d2 8d 35 f6 ee 10 e8 df ed 23 cb 5a 1e d0 72 76
            AF stripes: 4000
            AF hash:    sha256
            Area offset:32768 [bytes]
            Area length:258048 [bytes]
            Digest ID:  0
    Tokens:
    Digests:
      0: pbkdf2
            Hash:       sha256
            Iterations: 60235
            Salt:       16 45 a8 71 ea d3 03 c2 b1 09 ca d9 a3 10 fa 7f
                        ab 3f a0 22 1a f3 8b 11 38 14 d3 b7 dd da 15 26
            Digest:     66 b1 2f f5 ee ba 82 47 a9 f6 82 97 da 69 56 5d
                        48 e8 4f 8c 8b 81 b0 96 5e dd 5b 35 7e eb ee 28
  3. Add remote key
    [vagrant@appserver ~]$ sudo clevis luks bind -d /dev/sdb tang '{"url":"http://keyserver"}'
    The advertisement contains the following signing keys:
    
    9PZH7moczWcBukwc8esiW-dMAJs
    
    Do you wish to trust these keys? [ynYN] y
    Enter existing LUKS password: examplepassphrase

    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)

  4. Show there is a new keyslot in use by Clevis in slot 1
    [vagrant@appserver ~]$ sudo cryptsetup luksDump /dev/sdb
    LUKS header information
    Version:        2
    Epoch:          5
    Metadata area:  16384 [bytes]
    Keyslots area:  16744448 [bytes]
    UUID:           74f0faf1-9cb9-45f9-a3d8-ef276263d729
    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:     652621
            Threads:    2
            Salt:       89 f8 d9 3f 82 d3 e7 a9 5c c3 0e 97 4a b2 17 96
                        d2 8d 35 f6 ee 10 e8 df ed 23 cb 5a 1e d0 72 76
            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:     715513
            Threads:    2
            Salt:       09 ae 5e 47 e6 15 f2 1b 99 ad c9 a6 8f 56 db fc
                        6a 4f ac 33 37 0c 4c 27 48 02 99 1e 45 5b 9d 1c
            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: 60235
            Salt:       16 45 a8 71 ea d3 03 c2 b1 09 ca d9 a3 10 fa 7f
                        ab 3f a0 22 1a f3 8b 11 38 14 d3 b7 dd da 15 26
            Digest:     66 b1 2f f5 ee ba 82 47 a9 f6 82 97 da 69 56 5d
                        48 e8 4f 8c 8b 81 b0 96 5e dd 5b 35 7e eb ee 28

section 5Mount the encrypted filesystem on boot

Configure the system to unlock the encrypted device and mount the filesystem on boot.

  1. Enable the service
    [vagrant@appserver ~]$ sudo systemctl enable clevis-luks-askpass.path
  2. Identify the block device UUID for later use
    [vagrant@appserver ~]$ sudo blkid -s UUID  /dev/sdb
    /dev/sdb: UUID="74f0faf1-9cb9-45f9-a3d8-ef276263d729"
  3. Have the block device unlocked during boot

    The file /etc/crypttab defines how encrypted devices are handled during boot

    [vagrant@appserver ~]$ echo "encrypteddisk UUID=74f0faf1-9cb9-45f9-a3d8-ef276263d729 - _netdev" | sudo tee -a /etc/crypttab
  4. Mount the filesystem later in the boot

    To ensure the disk is unlocked before the filesystem is mounted, update the /etc/fstab

    [vagrant@appserver ~]$ sudo vi /etc/fstab
    and change the line
    UUID=4057664e-122f-421d-bcb6-2cb5a068a4d8 /encrypted xfs defaults 0 0
    to
    /dev/mapper/encrypteddisk /encrypted xfs _netdev 0 0

    We use the /dev/mapper path for readability and ensure systemd dependencies are generated and _netdev to indicate it's dependent on network devices being available.

  5. Restart the appserver to verify the filesystem is mounted at boot
    [vagrant@appserver ~]$ sudo shutdown -h now
    Connection to 127.0.0.1 closed by remote host.
    Connection to 127.0.0.1 closed.
    
    [user@demo NBDE]$ vagrant up appserver
    [user@demo NBDE]$ vagrant ssh appserver
    [vagrant@appserver]$ df -h /encrypted/
    Filesystem               Size  Used Avail Use% Mounted on
    /dev/mapper/exampledisk   16G  144M   16G   1% /encrypted

section 6Optional: Remove known passphrase

You can remove the known passphrase from slot 0 and mandate use of the tang server. If the tang server is unreachable the disk cannot be unlocked and filesystem inaccessible.

  1. Remove the passphrase
    [vagrant@appserver ~]$ cryptsetup --verbose luksRemoveKey /dev/sdb
    Enter passphrase to be deleted: examplepassphrase
    Key slot 0 unlocked.
    Keyslot 0 is selected for deletion.
    Key slot 0 removed.
    Command successful.
  2. Show that there are now only Clevis keyslots
    [vagrant@appserver ~]$ sudo cryptsetup luksDump /dev/sdb
    LUKS header information
    Version:        2
    Epoch:          5
    Metadata area:  16384 [bytes]
    Keyslots area:  16744448 [bytes]
    UUID:           74f0faf1-9cb9-45f9-a3d8-ef276263d729
    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:
      1: luks2
            Key:        512 bits
            Priority:   normal
            Cipher:     aes-xts-plain64
            Cipher key: 512 bits
            PBKDF:      argon2i
            Time cost:  4
            Memory:     715513
            Threads:    2
            Salt:       09 ae 5e 47 e6 15 f2 1b 99 ad c9 a6 8f 56 db fc
                        6a 4f ac 33 37 0c 4c 27 48 02 99 1e 45 5b 9d 1c
            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: 60235
            Salt:       16 45 a8 71 ea d3 03 c2 b1 09 ca d9 a3 10 fa 7f
                        ab 3f a0 22 1a f3 8b 11 38 14 d3 b7 dd da 15 26
            Digest:     66 b1 2f f5 ee ba 82 47 a9 f6 82 97 da 69 56 5d
                        48 e8 4f 8c 8b 81 b0 96 5e dd 5b 35 7e eb ee 28

    Note that keyslot zero has been removed.


section 7Appendix: 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 VirtualBox image used does not have an encrypted root disk so cannot be demonstrated in this lab.

  1. Install the RPMs
    [vagrant@appserver ~]$ sudo dnf install -y clevis-dracut
  2. Rebuild boot files
    [vagrant@appserver ~]$ 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)



more informationWant to Learn More?