How I set up full disk encryption with automatic unlocking of data drives on OMV 7

  • First of all: This is an example, not a guide. I can not guarantee that what worked for me in my specific setup will work for anybody else. I might not be able to help in case any problems occur to anyone trying to copy what I did.


    However, this might be useful to people that look for ways to achieve the same thing I did. Still, if you don't understand every step of what I did: Don't do it.


    I like to have all my data stored in encrypted drives. I do that for my computer and for the drives I have been using to backup my computer. Naturally, I also encrypted my storage drives in OMV via the openmediavault-luksencryption plugin.

    Two things bothered me about that setup:

    1. After a reboot, services that are on or refer to an encrypted drive (for me: fail2ban, docker, mergerfs, ...) were not running and I had to manually put in the passphrase for each drive and then restart every service.

    Also after each reboot I received about 30 e-mails from omv telling me, that my filesystems were not existing, that mountpoints failed, etc. After unlocking the encrypted drives I received several e-mails, that mounting the filesystems was successful, etc.

    So, after each reboot or boot, I had to do a few adjustments before things worked and then delete a lot of useless e-mails.

    2. My root drive was not encrypted. While many might argue, that that is not necessary, I like the thought that, when I power down my computers, no one can access anything. Also, this way I don't have to care about what information might be stored by which program in which place. When my drive fails and I throw it away, I don't have to worry that there might be readable information on it I don't want in somebody else's hands, etc. Everything is encrypted. Zero trust. Nice.


    I came across this guide, it seems outdated though. My method is similar, but one doesn't have to copy or rsync the root drive and the final encryption can be done while the server is up and running.

    I ended up with a fully encrypted system, where I enter one passphrase once during the boot process and get a fully working system without getting 30 useless e-mails.

    It might be noteworthy, that my installation was on a 256 GB SSD with lots of free space.


    Here is what I did:


    0. Backup everything!!


    1. We need an encrypted swap. Encrypting everything but leaving swap unencrypted doesn't make sense in my opinion, since the encryption keys or anything else might be stored in swap temporarily. The cryptsetup readme has a good guide for this:

    a. Find out the current swap partition by using lsblk, or by looking in the fstab (cat /etc/fstab). If a swapfile is used there is no need to change anything since it won't be accessible without unlocking the root drive anyway.

    b. Deactivate our current swap: sudo swapoff -a

    c. Add an entry to etc/crypttab for our swap device:

    Code
    # <target name> <source device> <key file>      <options>    
    cswap1          <swapdevice, eg. PARTUUID=xxx> /dev/urandom    plain,cipher=aes-xts-plain64,size=256,swap

    <swapdevice> needs to be replaced by the correct device. Using something like /dev/sda5 is not safe, because this will change after rebooting. It is possible to use labels or UUIDs after following this guide, otherwise they also change after rebooting.

    I just use the PARTUUID I looked up via sudo blkid. (If the partition should be repurposed later on without repartitioning first, one has to remember to remove that line from crypttab, otherwise the partition will continue to be overwritten on each boot.)

    Other options include using /dev/disk/by-id/xxx-part-x. All persistent device names can be found via find -L /dev/disk -samefile /dev/<swapdevice>

    If the swap partition is stored on a SSD it's possible to add discard to the options in order to make trim work (although this makes the encryption weaker - probably more relevant for normal partitions though)

    Code
    # <target name> <source device> <key file>      <options>    
    cswap1          <swapdevice, eg. PARTUUID=xxx> /dev/urandom    plain,cipher=aes-xts-plain64,size=256,swap,discard

    d. Change the swap entry in /etc/fstab to point to the encrypted device:

    Code
    # <file system> <mount point>   <type>  <options>     <dump>  <pass>
    /dev/mapper/cswap1  none        swap    sw            0       0

    e. Create and start the encrypted swap device:

    Code
    sudo cryptdisks_start cswap1    
    sudo swapon -a

    f. Make sure resume/suspend to disk is disabled:

    Code
    sudo echo "RESUME=none" >/etc/initramfs-tools/conf.d/resume
    sudo update-initramfs -u

    g. Done. Swap is encrypted.


    2. Setup Dropbear to be able to connect via ssh during the boot process.

    a. Install dropbear-initramfs: sudo apt install dropbear-initramfs

    b. Edit /etc/dropbear/initramfs/dropbear.conf to contain the following:

    Code
    DROPBEAR_OPTIONS="-I 180 -j -k -p 33333 -s -c cryptroot-unlock"

    (this closes the connection after 180 seconds of no activity, disables port forwarding, sets dropbear's ssh port to 33333, disables password login and restricts the ssh connection to executing cryptroot-unlock.)

    c. Copy our ssh public key to /etc/dropbear/initramfs/authorized_keys . We can generate a new pair, and insert the public key there, or copy the key we might be using already from the ~/.ssh/authorized_keys file in our user's home folder on omv.

    I am using Ubuntu on my desktop computer, and the public key for openmediavault is already stored in my home folder so I just copied that one:

    Code
    user@Desktop:~$ scp ~/.ssh/id_ed25519.pub 192.xxx.xxx.xx:~/key.pub
    user@Desktop:~$ ssh 192.xxx.xxx.xx
    user@omv:~$ sudo -s
    root@omv:/home/user# cat key.pub >> /etc/dropbear/initramfs/authorized_keys

    d. My router is configured to always assign a specific IP address to my server via DHCP. If that is not the case we need to specify the IP in /etc/initramfs-tools/initramfs.conf by adding

    Code
    IP=<desired-omv-IP>::<gateway-ip>:<netmask>:<hostname>

    Even if this is not necessary because DHCP is set up, I recommend (additionally) setting the static IP in the omv GUI network interfaces settings page to avoid any trouble with DHCP after dropbear closes the connection.

    e. I have more than one network interface and dropbear always used the one that has no DHCP set up, so I specified which interface to use by defining it in /etc/initramfs-tools/initramfs.conf (by adding DEVICE=eno1).

    f. Update the initramfs image: sudo update-initramfs -u

    g. Done.


    3. See next post

  • 3. Set the system up for encryption by booting into a live environment. I used an Ubuntu 23.10 Live USB drive for this and connected display, mouse and keyboard to the server.


    3.1. First we need a separate /boot partition that remains unencrypted. (Newer versions of cryptsetup can work with encrypted /boot partitions but I haven't tried that yet.)

    a. We use Gparted to shrink our OMV system partition by a few GiB (I did 4, but 2 should be enough as well).

    b. Create a new ext4 partition in the freed space. Use boot as label and as name (LABEL and PARTNAME).

    c. Find out the device name of our system partition via sudo lsblk or sudo blkid. In my case /dev/nvme1n1p2

    d. Mount it: sudo mount /dev/nvme1n1p2 /mnt

    e. Now we backup our /boot folder and create an empty one:

    Code
    sudo mv /mnt/boot /mnt/boot.old
    sudo mkdir /mnt/boot

    f. We mount our new partition: sudo mount LABEL=boot /mnt/boot

    g. We copy the old /boot folder to the new partition: sudo cp -a /mnt/boot.old/* /mnt/boot/

    h. We add the following line to /mnt/etc/fstab:

    Code
    LABEL=boot /boot ext4 defaults 0 2

    i. We unmount both the system and the boot partition:

    Code
    sudo umount /mnt/boot
    sudo umount /mnt


    3.2. We stay in the live environment. Now we need to prepare our system partition to be able to be encrypted.

    The LUKS Header needs up to 32 MB of space at the beginning of the partition, that we need to create.

    a. Check the partition for errors. This needs to be done before changing it. sudo e2fsck -f /dev/nvme1n1p2

    b. Now we need to resize the filesystem inside the partition (not the partition itself!) to make room for our LUKS header. Here it is advisable to be generous with space, the change is only temporary. My partition was 32 GiB with only about 10 used, so I resized to 20 G: sudo resize2fs /dev/nvme1n1p2 20G

    c. Now we can create the LUKS header and initialize the encryption: sudo cryptsetup reencrypt --encrypt --init-only --reduce-device-size 32m /dev/nvme1n1p2 root_crypt After setting a passphrase the partition has a LUKS header and we are asked for its passphrase during boot. It is still unencrypted though. The actual encryption can be started at any time now, and also from within the running system.

    d. We check our new LUKS partition: sudo e2fsck -f /dev/mapper/root_crypt.

    e. And now we can resize the filesystem to use the whole partition again: sudo resize2fs /dev/mapper/root_crypt


    3.3 Now we need to chroot into our omv system to update the system to the new configuration.

    a. Find our EFI partition via sudo lsblk, sudo blkid, Gnome Disks or Gparted (for me it's /dev/nvme1n1p1).

    b. Mount our partitions:

    Code
    sudo mount /dev/mapper/root_crypt /mnt
    sudo mount LABEL=boot /mnt/boot
    sudo mount /dev/nvme1n1p1 /mnt/boot/efi

    c. chroot in our omv system:

    Code
    for d in dev sys proc tmp; do sudo mount --bind /${d} /mnt/${d}; done
    sudo chroot /mnt

    d. Now we can find out the UUID of /dev/mapper/root_crypt via sudo blkid /dev/mapper/root_crypt and change the root partition's /etc/fstab entry to the new UUID:

    Code
    # / was on /dev/nvme0n1p2 during installation
    UUID=xxxx    /    ext4    errors=remount-ro    0    1

    When editing the /etc/fstab be aware that the text between # >>> [openmediavault] and # <<< [openmediavault] should remain unchanged.

    e. Now we find out the UUID of the encrypted partition via sudo blkid /dev/nvme1n1p2 and add that to the /etc/crypttab:

    Code
    # <target name>    <source device>    <key file>       <options>
    cswap1            PARTUUID=xxx        /dev/urandom    swap,cipher=aes-xts-plain64,size=256,discard
    root_crypt        UUID=xxx            none            luks,discard

    f. Now we can also add our encrypted data disks to the /etc/crypttab with their respective UUIDs. If we want them to be automatically unlocked when unlocking the root partition, we need to use the same key for them as we used for the root partition.

    I use the same passphrase, I guess it would also work with keyfiles. If one uses different passphrases, the passphrase we used for the root partition can simply be added to the existing disks in another keyslot (either via command line or via the OMV plugin).

    If the same key is used we just need to add keyscript=decrypt_keyctl to the options and all drives get unlocked when unlocking the root partition during the boot process. The /etc/crypttab should look like this:

    Code
    # <target name>    <source device>    <key file>       <options>
    cswap1            PARTUUID=xyz        /dev/urandom    swap,cipher=aes-xts-plain64,size=256,discard
    root_crypt        UUID=xxx            none            luks,discard,keyscript=decrypt_keyctl
    data1_crypt       UUID=yyy            none            luks,discard,keyscript=decrypt_keyctl
    data2_crypt       UUID=zzz            none            luks,discard,keyscript=decrypt_keyctl

    g. Now we update our initramfs and reinstall the bootloader:

    Code
    sudo update-initramfs -c -k all
    sudo grub-install
    sudo update-grub

    h. We can now leave the chroot-environment: exit and unmount our devices:

    Code
    for d in dev sys proc tmp boot/efi boot ""; do sudo umount /mnt/${d}; done
    sudo cryptsetup close root_crypt

    i. Shut down the live environment. Display, mouse and keyboard shouldn't be needed anymore.


    4. Booting the system and finishing the encryption

    a. Power up the server.

    b. We can ping the IP we set up for the server to see when it is available:

    Code
    user@Desktop:~$ ping 192.xxx.xxx.xx

    c. When we see a response we can connect to dropbear using ssh and the port we configured in the beginning:

    Code
    user@Desktop:~$ ssh -p 33333 root@192.xxx.xxx.xx

    (Connecting as root is necessary. Dropbear doesn't know our OMV users.)

    d. We can now enter the password for our root partition. The output should be something like this:

    Code
    Please unlock disk root_crypt:
    cryptsetup: root_crypt set up successfully
    Connection to 192.xxx.xxx.xx closed.

    e. Now the system will start, unlock all drives from crypttab and we can use our regular ssh connection to connect to the server. Dropbear is only reachable during boot and closes the connection after unlocking the system partition.

    f. Now, whenever we want, we can finish the encryption with the command sudo cryptsetup reencrypt --active-name root_crypt. This can be interrupted with Ctrl+Cwhen necessary and resumed at any time. In my case it took only a few minutes though.

    g. If everything works, we could delete the /boot.old folder now.



    That's it. Full disk encryption with automatic unlock for data drives.



    Addditionally to what I already mentioned, here are some guides that helped me a lot when trying to figure this out (two in German, one behind paywall):

    LUKS-Festplatten-Vollverschlüsselung per SSH entsperren - codingblatt.de

    Linux-Installationen nachträglich verschlüsseln
    Mit unserer Anleitung verschlüsseln Sie Ihre Linux-Installation nachträglich und nach entsprechender Vorbereitung sogar im laufenden Betrieb.
    www.heise.de

    https://www.cyberciti.biz/security/how-to-unlock-luks-using-dropbear-ssh-keys-remotely-in-linux/

  • My server with its dozen disks is locked in a safe. That doesn't prevent it from being attacked over the network though. But neither do encrypted disks once unlocked and mounted.

    --
    Google is your friend and Bob's your uncle!


    OMV AMD64 7.x on headless Chenbro NR12000 1U 1x 8m Quad Core E3-1220 3.1GHz 32GB ECC RAM.

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!