Skip to content

Instantly share code, notes, and snippets.

@kmullin
Last active August 3, 2026 00:05
Show Gist options
  • Select an option

  • Save kmullin/7a0c8a0e10fd188570e8c8f5722b7a38 to your computer and use it in GitHub Desktop.

Select an option

Save kmullin/7a0c8a0e10fd188570e8c8f5722b7a38 to your computer and use it in GitHub Desktop.
zfs_ubuntu.sh
#!/bin/bash
# cobbled together from a few sources:
# * https://medo64.com/posts/manually-installing-encrypted-zfs-on-ubuntu-24-04/
# * https://blog.wrouesnel.com/posts/ubuntu-2404-dracut-and-native-zfs-encryption/
# * https://blog.jjgaming.net/blog/zfs-root-ubuntu
set -exu
. /etc/os-release
UUID=$(LC_ALL=C tr -dc a-z0-9 < /dev/urandom | head -c 6)
UUIDUSER=$(LC_ALL=C tr -dc a-z0-9 < /dev/urandom | head -c 6)
# create the encryption key
KEYFILE=$(mktemp)
dd if=/dev/urandom of="$KEYFILE" bs=32 count=1
# found here:https://code.launchpad.net/~dbungert/curtin/+git/curtin/+merge/486154
LUKS_HEADER_SIZE=$((16 << 20))
USABLE_VOLUME_SIZE=$((4 << 20))
read -p "device for rpool: " RPOOL_DEV
read -p "device for bpool: " BPOOL_DEV
# create the rpool
zpool create \
-o ashift=12 \
-o autotrim=on \
-O canmount=off \
-O normalization=formD \
-O acltype=posixacl \
-O compression=lz4 \
-O devices=off \
-O dnodesize=auto \
-O relatime=on \
-O sync=standard \
-O xattr=sa \
-O encryption=on \
-O keylocation=file://"$KEYFILE" \
-O keyformat=raw \
-O mountpoint=/ \
-R /target \
rpool \
"$RPOOL_DEV"
zpool set cachefile=/etc/zfs/zpool.cache rpool
# create the zvol to hold the key
zfs create \
-o encryption=off \
-V $((LUKS_HEADER_SIZE + USABLE_VOLUME_SIZE)) \
rpool/keystore
cryptsetup --batch-mode luksFormat --offset $((LUKS_HEADER_SIZE / 512)) /dev/zvol/rpool/keystore
cryptsetup open /dev/zvol/rpool/keystore keystore-rpool
mkfs.ext4 /dev/mapper/keystore-rpool
mount /dev/mapper/keystore-rpool /mnt
cp -v "$KEYFILE" /mnt/system.key
zfs set keylocation=file:///run/keystore/rpool/system.key rpool
zfs create -o canmount=off -o mountpoint=none rpool/ROOT
zfs create -o canmount=on -o mountpoint=/ rpool/ROOT/"$ID"_"$UUID"
zfs create -o canmount=off rpool/ROOT/"$ID"_"$UUID"/var
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/var/lib
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/var/lib/AccountsService
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/var/lib/apt
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/var/lib/dpkg
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/var/lib/NetworkManager
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/srv
zfs create -o canmount=off rpool/ROOT/"$ID"_"$UUID"/usr
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/usr/local
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/var/games
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/var/log
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/var/mail
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/var/snap
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/var/spool
zfs create -o canmount=on rpool/ROOT/"$ID"_"$UUID"/var/www
zfs create -o canmount=off -o mountpoint=none rpool/USERDATA
zfs create -o canmount=on -o mountpoint=/root rpool/USERDATA/root_"$UUIDUSER"
zfs create -o canmount=on -o mountpoint=/home rpool/USERDATA/home_"$UUIDUSER"
# do bpool things
zpool create \
-o ashift=12 \
-o autotrim=on \
-o feature@async_destroy=enabled \
-o feature@bookmarks=enabled \
-o feature@embedded_data=enabled \
-o feature@empty_bpobj=enabled \
-o feature@enabled_txg=enabled \
-o feature@extensible_dataset=enabled \
-o feature@filesystem_limits=enabled \
-o feature@hole_birth=enabled \
-o feature@large_blocks=enabled \
-o feature@lz4_compress=enabled \
-o feature@spacemap_histogram=enabled \
-O canmount=off \
-O normalization=formD \
-O acltype=posixacl \
-O compression=lz4 \
-O devices=off \
-O relatime=on \
-O sync=standard \
-O xattr=sa \
-O mountpoint=/boot \
-R /target \
-d bpool \
"$BPOOL_DEV"
zpool set cachefile=/etc/zfs/zpool.cache bpool
zfs create -o canmount=off -o mountpoint=none bpool/BOOT
zfs create -o canmount=on -o mountpoint=/boot bpool/BOOT/"$ID"_"$UUID"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment