This guide is written for Ubuntu 24.04. Other operating systems and distributions
may require different tools or steps — adapt accordingly.
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.
Boot from Ubuntu 24.04 installer
Download the Ubuntu 24.04 Server ISO and boot your machine from it.
Proceed through installer until storage configuration
At the Storage configuration screen, select Custom storage layout
and then choose Use entire disk option.
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.
Complete installation
Finish the installer normally. On every boot, you will be prompted to enter
the passphrase before the system starts.
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.
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: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 for details.
Prerequisites
- A spare disk or unpartitioned space available on the server.
cryptsetup and rsync installed:
sudo apt install -y cryptsetup rsync
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: Create and format the LUKS container
Replace /dev/sdb with your actual device. This will erase all data on it.sudo cryptsetup luksFormat /dev/sdb
You will be prompted to confirm (YES) and set a passphrase. Open the encrypted container
sudo cryptsetup open /dev/sdb zylon-data
This maps the container to /dev/mapper/zylon-data.Create a filesystem on the mapped device
sudo mkfs.ext4 /dev/mapper/zylon-data
Stop Zylon before migrating data
Mount the encrypted partition and migrate data
sudo mount /dev/mapper/zylon-data /mnt/zylon-data
sudo rsync -aAX /var/zylon/ /mnt/zylon-data/
Verify the copy completed successfully before continuing.Replace the original data directory with the encrypted mount
sudo mv /var/zylon /var/zylon.bak
sudo mkdir /var/zylon
sudo umount /mnt/zylon-data
sudo mount /dev/mapper/zylon-data /var/zylon
Configure automatic mounting at boot
Add the LUKS device to /etc/crypttab:# 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
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.
Start Zylon and verify
Confirm everything is working, then remove the backup:sudo rm -rf /var/zylon.bak
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.
Review the script before running it. It will erase the target disk and
stop Zylon during the migration.
Save it as encrypt-zylon.sh and run with sudo bash encrypt-zylon.sh.
#!/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"
The passphrase will be prompted at every boot. For headless servers, see
the Ubuntu documentation on remote LUKS unlocking.