LXD security luks

From UVOO Tech Wiki
Jump to navigation Jump to search

Setting up an encrypted storage pool for LXD is the closest you can get to the "AWS EBS Encryption" model on your own hardware. By using LUKS (Linux Unified Key Setup) underneath ZFS, even if someone pulls the physical drive from your server, the data is just random noise without the decryption passphrase.

Here is how to build that secure foundation on Ubuntu 24.04.


Phase 1: Prepare the Encrypted Partition

We will use a raw partition or a secondary drive (e.g., /dev/sdb).

  1. Install the necessary tools: bash sudo apt update && sudo apt install cryptsetup zfsutils-linux -y
  2. Format the partition with LUKS: Choose a strong passphrase; you will need this every time the server boots. bash sudo cryptsetup luksFormat /dev/sdb
  3. Open the encrypted "container": This maps the encrypted physical drive to a virtual device at /dev/mapper/lxd_encrypted. bash sudo cryptsetup open /dev/sdb lxd_encrypted

Phase 2: Create the LXD Storage Pool

Now that we have an open, decrypted block device, we tell LXD to use it for a ZFS pool.

  1. Create the Pool: bash sudo lxc storage create secure-pool zfs source=/dev/mapper/lxd_encrypted
  2. Verify the Pool: bash lxc storage list You should see secure-pool listed with the driver zfs.

Phase 3: Launch a Secure Container/VM

To ensure your workloads actually live on this encrypted disk, you must specify the pool during launch.

  • For a Container: bash lxc launch ubuntu:24.04 my-secure-app --storage secure-pool
  • For a VM (Even More Secure): bash lxc launch ubuntu:24.04 my-vault --vm --storage secure-pool

Phase 4: Handling Reboots (The "Unlock" Process)

Unlike a public cloud where the provider handles the hardware keys, you own the keys now. This means when your physical server reboots, the LXD pool will stay "offline" because the LUKS partition is locked.

To restore access after a reboot: 1. Unlock the drive:

   bash
   sudo cryptsetup open /dev/sdb lxd_encrypted

2. Restart LXD (if it didn't auto-detect):

   bash
   sudo systemctl restart snap.lxd.daemon

[!TIP] If you want the server to unlock automatically at boot (less secure, but common for remote servers), you can use a Keyfile stored on a specialized USB drive or an initramfs configuration, though this technically means anyone with physical access to that USB drive can bypass the encryption.


How this mimics "Cloud Security"

  • The "Admin" Problem: If an admin tries to cat a file from the host's /var/lib/lxd/storage-pools/, they can only do so while the LUKS partition is "Open."
  • Cold Boot Attacks: If the server is powered off, the data is mathematically inaccessible.
  • Snapshot Safety: Since the ZFS snapshots live inside the LUKS container, your backups are also encrypted by default if you replicate the ZFS stream.

Automount

Automating the unlock process is a balance between convenience and security. If you store the key on the same hard drive, you defeat the purpose of encryption (it’s like leaving the key in the lock).

The "Pro" way to do this on-premise is to store the keyfile on a separate USB drive or a dedicated microSD card that stays plugged into the server.


1. Create the Keyfile

First, we generate a file full of random data to act as your "digital key."

# Create a 4KB keyfile
sudo dd if=/dev/urandom of=/root/lxd_keyfile bs=1024 count=4
# Set strict permissions (Only root can read it)
sudo chmod 400 /root/lxd_keyfile

(Note: For higher security, move this file to a USB drive mounted at /mnt/usb/keyfile instead of /root/.)


2. Add the Keyfile to LUKS

LUKS has "slots" for multiple keys. We will keep your manual passphrase in Slot 0 and add this file to Slot 1.

sudo cryptsetup luksAddKey /dev/sdb /root/lxd_keyfile

You will be prompted for your original passphrase to authorize adding the new key.


3. Configure /etc/crypttab

This file tells Ubuntu to unlock the drive automatically during the boot sequence using the keyfile.

  1. Get the UUID of your physical drive:
    blkid /dev/sdb
    
    Copy the UUID (e.g., UUID="1234-abcd-...").
  2. Edit the crypttab file:
    sudo nano /etc/crypttab
    
  3. Add this line: text lxd_encrypted UUID=your-uuid-here /root/lxd_keyfile luks

4. Update Initramfs

Since storage is a core system component, you need to update the boot RAM disk so the kernel knows how to handle this mapping at startup.

sudo update-initramfs -u

5. Final Step: The ZFS Mount

LXD is usually smart enough to see the /dev/mapper/lxd_encrypted device appear and then mount the ZFS pool. However, if the pool doesn't import automatically, you can add a simple systemd override or just run lxc storage import if needed.

The "Cloud-Level" Security Result

  • Rebooting: The server boots, finds the keyfile, unlocks the drive, and LXD starts your containers.
  • Theft Scenario: If someone steals the server but unplugs the USB key (or if you keep the keyfile on a network share that you disconnect), the data remains encrypted and unreadable.
  • Rogue Admin: An admin with access to the running OS can still see the data (since it's unlocked), but an admin with physical access to the "cold" hardware cannot.

[!WARNING] If you lose both your manual passphrase and this keyfile, the data on that LXD pool is gone forever. There is no "Password Reset" in LUKS encryption.