> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zylon.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Disk Encryption

> Encrypt your Zylon server's disk to protect data at rest on Ubuntu 24.04

<Note>
  This guide is written for Ubuntu 24.04. Other operating systems and distributions
  may require different tools or steps — adapt accordingly.
</Note>

Disk encryption ensures that data stored on your server is unreadable without the
correct passphrase, protecting it against physical theft or unauthorized hardware access.

Choose the approach that matches your situation:

* **Clean machine** — no OS installed yet. Full-disk encryption is set up during Ubuntu installation.
* **Zylon already installed** — encrypt a separate data partition without reinstalling.

***

## Option 1: Clean Machine — Full-Disk Encryption During Installation

This is the recommended approach. Ubuntu's installer can encrypt the entire disk
using LUKS (Linux Unified Key Setup) with a single passphrase.

<Steps>
  <Step title="Boot from Ubuntu 24.04 installer">
    Download the Ubuntu 24.04 Server ISO and boot your machine from it.
  </Step>

  <Step title="Proceed through installer until storage configuration">
    At the **Storage configuration** screen, select **Custom storage layout**
    and then choose **Use entire disk** option.
  </Step>

  <Step title="Enable encryption">
    Check **Encrypt the LVM group with LUKS**. You will be prompted to set a passphrase.

    Choose a strong passphrase and store it securely — **losing it means losing access to all data**.
  </Step>

  <Step title="Complete installation">
    Finish the installer normally. On every boot, you will be prompted to enter
    the passphrase before the system starts.
  </Step>

  <Step title="Install Zylon">
    Once Ubuntu is running, follow the standard [Zylon installation guide](/en/operator-manual/installation/index).
  </Step>
</Steps>

***

## Option 2: Zylon Already Installed — Encrypt a Data Partition

If Zylon is already running, a full reinstall is disruptive. Instead, you can
create an encrypted partition for Zylon's data directory (`/var/zylon`)
using LUKS and move the data into it.

<Warning>
  **This is a complex, high-risk operation. Data loss is possible if anything goes wrong.**

  Before proceeding, back up all Zylon data and move it off the server:

  ```bash theme={null}
  sudo zylon-cli backup
  ```

  Copy the resulting backup file to a safe external location (S3, another machine, etc.)
  and verify you can access it before continuing. Do not proceed without a verified backup.

  See the [Backup guide](/en/operator-manual/operations/backup) for details.
</Warning>

### Prerequisites

* A spare disk or unpartitioned space available on the server.
* `cryptsetup` and `rsync` installed:

```bash theme={null}
sudo apt install -y cryptsetup rsync
```

<Steps>
  <Step title="Identify the target disk or partition">
    List available block devices to find your spare disk (e.g. `/dev/sdb`).
    The `-e 7` flag excludes loop devices (snap packages) to reduce noise:

    ```bash theme={null}
    lsblk -d -e 7
    ```
  </Step>

  <Step title="Create and format the LUKS container">
    Replace `/dev/sdb` with your actual device. This will **erase all data on it**.

    ```bash theme={null}
    sudo cryptsetup luksFormat /dev/sdb
    ```

    You will be prompted to confirm (`YES`) and set a passphrase.
  </Step>

  <Step title="Open the encrypted container">
    ```bash theme={null}
    sudo cryptsetup open /dev/sdb zylon-data
    ```

    This maps the container to `/dev/mapper/zylon-data`.
  </Step>

  <Step title="Create a filesystem on the mapped device">
    ```bash theme={null}
    sudo mkfs.ext4 /dev/mapper/zylon-data
    ```
  </Step>

  <Step title="Stop Zylon before migrating data">
    ```bash theme={null}
    sudo k0s stop
    ```
  </Step>

  <Step title="Mount the encrypted partition and migrate data">
    ```bash theme={null}
    sudo mount /dev/mapper/zylon-data /mnt/zylon-data
    sudo rsync -aAX /var/zylon/ /mnt/zylon-data/
    ```

    Verify the copy completed successfully before continuing.
  </Step>

  <Step title="Replace the original data directory with the encrypted mount">
    ```bash theme={null}
    sudo mv /var/zylon /var/zylon.bak
    sudo mkdir /var/zylon
    sudo umount /mnt/zylon-data
    sudo mount /dev/mapper/zylon-data /var/zylon
    ```
  </Step>

  <Step title="Configure automatic mounting at boot">
    Add the LUKS device to `/etc/crypttab`:

    ```bash theme={null}
    # Get the UUID of the LUKS device
    sudo cryptsetup luksDump /dev/sdb | grep UUID
    ```

    Append a line to `/etc/crypttab` (replace `YOUR_UUID` with the value above):

    ```
    zylon-data UUID=YOUR_UUID none luks
    ```

    Then add the mount to `/etc/fstab`:

    ```
    /dev/mapper/zylon-data /var/zylon ext4 defaults 0 2
    ```

    <Note>
      Using `none` as the key file means the passphrase will be prompted at every boot.
      For headless servers, see the Ubuntu documentation on remote LUKS unlocking.
    </Note>
  </Step>

  <Step title="Start Zylon and verify">
    ```bash theme={null}
    sudo k0s start
    ```

    Confirm everything is working, then remove the backup:

    ```bash theme={null}
    sudo rm -rf /var/zylon.bak
    ```
  </Step>
</Steps>

### Automated script (alternative)

The script below performs all the steps above interactively. It will ask for
the target disk and the LUKS passphrase, then handle the rest.

<Warning>
  Review the script before running it. It will **erase the target disk** and
  stop Zylon during the migration.
</Warning>

Save it as `encrypt-zylon.sh` and run with `sudo bash encrypt-zylon.sh`.

```bash theme={null}
#!/usr/bin/env bash
set -eu

log()   { echo "[INFO]  $*"; }
warn()  { echo "[WARN]  $*"; }
abort() { echo "[ERROR] $*" >&2; exit 1; }

[ "$(id -u)" -eq 0 ] || abort "Run this script with sudo: sudo bash $0"
command -v cryptsetup >/dev/null || abort "cryptsetup not found. Run: apt install cryptsetup"
command -v rsync      >/dev/null || abort "rsync not found. Run: apt install rsync"

lsblk -d -e 7
echo

ROOT_DISK=$(lsblk -rno PKNAME,MOUNTPOINT 2>/dev/null | awk '$2=="/" {print $1}')
if [ -n "$ROOT_DISK" ]; then
    warn "Root disk (do NOT use this): /dev/$ROOT_DISK"
fi

log "Unpartitioned disks (candidates for encryption):"
lsblk -d -e 7 -rno NAME | while read -r name; do
    part_count=$(lsblk "/dev/$name" -rno NAME | grep -c ".")
    if [ "$part_count" -eq 1 ] && [ "$name" != "$ROOT_DISK" ]; then
        size=$(lsblk -d "/dev/$name" -rno SIZE)
        echo "    /dev/$name  $size"
    fi
done
echo

read -rp "Enter the target disk device (e.g. /dev/sdb): " DEVICE

[ -b "$DEVICE" ] || abort "$DEVICE is not a valid block device."

warn "ALL DATA ON $DEVICE WILL BE ERASED. This cannot be undone."
read -rp "Type YES to confirm: " CONFIRM
[ "$CONFIRM" = "YES" ] || abort "Aborted."

MAPPER_NAME="zylon-data"
MOUNT_TMP="/mnt/zylon-data"
DATA_DIR="/var/zylon"
BACKUP_DIR="/var/zylon.bak"

log "Stopping Zylon... (if the script is interrupted from this point on, start it again manually with: sudo k0s start)"
k0s stop || true

log "Formatting $DEVICE with LUKS..."
cryptsetup luksFormat "$DEVICE"

log "Verifying LUKS formatting..."
cryptsetup isLuks "$DEVICE" || abort "LUKS formatting failed — $DEVICE is not a valid LUKS container. Aborting before any data is moved."

log "Opening encrypted container..."
cryptsetup open "$DEVICE" "$MAPPER_NAME"

[ -b "/dev/mapper/$MAPPER_NAME" ] || abort "Failed to open LUKS container — mapper device not found."

log "Creating ext4 filesystem..."
mkfs.ext4 "/dev/mapper/$MAPPER_NAME"

mkdir -p "$MOUNT_TMP"
mount "/dev/mapper/$MAPPER_NAME" "$MOUNT_TMP"

log "Copying data from $DATA_DIR to encrypted partition (this may take a while)..."
rsync -aAX "$DATA_DIR/" "$MOUNT_TMP/"

log "Swapping data directory..."
mv "$DATA_DIR" "$BACKUP_DIR"
mkdir "$DATA_DIR"
umount "$MOUNT_TMP"
mount "/dev/mapper/$MAPPER_NAME" "$DATA_DIR"

UUID=$(cryptsetup luksDump "$DEVICE" | awk '/^UUID:/ { print $2 }')

log "Updating /etc/crypttab..."
CRYPTTAB_LINE="$MAPPER_NAME UUID=$UUID none luks"
if ! grep -Fqx "$CRYPTTAB_LINE" /etc/crypttab; then
  echo "$CRYPTTAB_LINE" >> /etc/crypttab
else
  log "/etc/crypttab already contains the required entry; skipping."
fi

log "Updating /etc/fstab..."
FSTAB_LINE="/dev/mapper/$MAPPER_NAME $DATA_DIR ext4 defaults 0 2"
if ! grep -Fqx "$FSTAB_LINE" /etc/fstab; then
  echo "$FSTAB_LINE" >> /etc/fstab
else
  log "/etc/fstab already contains the required entry; skipping."
fi

log "Starting Zylon..."
k0s start

echo
log "Done. Zylon data is now on an encrypted partition."
log "Verifying..."
lsblk -o NAME,FSTYPE,MOUNTPOINT | grep -E "crypto|zylon"
echo
log "Backup at $BACKUP_DIR — remove it once everything looks good:"
echo "  sudo rm -rf $BACKUP_DIR"
```

<Note>
  The passphrase will be prompted at every boot. For headless servers, see
  the Ubuntu documentation on remote LUKS unlocking.
</Note>
