## Alpine UEFI ZFSBootMenu Install source /etc/os-release export ID # VARIABLES export USERNAME="alpine" export ZPOOLNAME="tank" # HDD/SDD export BOOT_DISK="/dev/sda" export BOOT_PART="1" export BOOT_DEVICE="${BOOT_DISK}${BOOT_PART}" export POOL_DISK="/dev/sda" export POOL_PART="2" export POOL_DEVICE="${POOL_DISK}${POOL_PART}" # NVME export BOOT_DISK="/dev/nvme0n1" export BOOT_PART="1" export BOOT_DEVICE="${BOOT_DISK}p${BOOT_PART}" export POOL_DISK="/dev/nvme0n1" export POOL_PART="2" export POOL_DEVICE="${POOL_DISK}p${POOL_PART}" # Setup networking setup-interfaces # Refresh apk repositories cat < /etc/apk/repositories https://dl-cdn.alpinelinux.org/alpine/latest-stable/main/ https://dl-cdn.alpinelinux.org/alpine/latest-stable/community/ EOF # Update apk and add zfs tools apk update apk add coreutils efibootmgr hdparm sgdisk zfs zfs-scripts zzz modprobe zfs # Generate a random hostid head /dev/urandom | tr -dc a-f0-9 | head -c 13 > /etc/hostid # Wipe disks: ## HDD shred -n 7 -v "$BOOT_DISK" ## SSD zzz hdparm -I "$BOOT_DISK" | grep frozen hdparm --user-master u --security-set-pass PasSWorD "$BOOT_DISK" hdparm --user-master u --security-erase-enhanced PasSWorD "$BOOT_DISK" ## NVME https://wiki.archlinux.org/title/Solid_state_drive/Memory_cell_clearing#NVMe_drive # Create partitions sgdisk --zap-all "$BOOT_DISK" sgdisk -n "${BOOT_PART}:1m:+512m" -t "${BOOT_PART}:ef00" "$BOOT_DISK" sgdisk -n "${POOL_PART}:0:-10m" -t "${POOL_PART}:bf00" "$POOL_DISK" # Reload mdev mdev -s # Create an encryption phrase vi /etc/zfs/zroot.key chmod 000 /etc/zfs/zroot.key # Create a zpool zpool create -f -o ashift=12 \ -O compression=lz4 \ -O acltype=posixacl \ -O xattr=sa \ -O relatime=on \ -O encryption=aes-256-gcm \ -O keylocation=file:///etc/zfs/zroot.key \ -O keyformat=passphrase \ -o autotrim=on \ -R /mnt "$ZPOOLNAME" "$POOL_DEVICE" # Create zfs datasets zfs create -o mountpoint=none "$ZPOOLNAME"/ROOT zfs create -o mountpoint=/ -o canmount=noauto "$ZPOOLNAME"/ROOT/${ID} zfs create -o mountpoint=/root "$ZPOOLNAME"/ROOT/${ID}/root zfs create -o mountpoint=/opt "$ZPOOLNAME"/ROOT/${ID}/opt zfs create -o mountpoint=/var "$ZPOOLNAME"/ROOT/${ID}/var zfs create -o mountpoint=/var/log "$ZPOOLNAME"/ROOT/${ID}/var/log zfs create -o mountpoint=/home "$ZPOOLNAME"/HOME zfs create -o mountpoint=/home/"$USERNAME" "$ZPOOLNAME"/HOME/"$USERNAME" # Set zpool to boot from zpool set bootfs="$ZPOOLNAME"/ROOT/${ID} "$ZPOOLNAME" # Re-import zpool zpool export "$ZPOOLNAME" zpool import -N -R /mnt "$ZPOOLNAME" zfs load-key -L prompt "$ZPOOLNAME" # Remount zfs datasets zfs mount "$ZPOOLNAME"/ROOT/${ID} zfs mount "$ZPOOLNAME"/ROOT/${ID}/root zfs mount "$ZPOOLNAME"/ROOT/${ID}/opt zfs mount "$ZPOOLNAME"/ROOT/${ID}/var zfs mount "$ZPOOLNAME"/ROOT/${ID}/var/log zfs mount "$ZPOOLNAME"/HOME zfs mount "$ZPOOLNAME"/HOME/"$USERNAME" # Check everything is mounted correctly mount | grep mnt # Bootstrap alpine apk --arch x86_64 -X http://dl-cdn.alpinelinux.org/alpine/latest-stable/main \ -U --allow-untrusted --root /mnt --initdb add alpine-base # Copy relevant files to chroot cp /etc/hostid /mnt/etc cp /etc/resolv.conf /mnt/etc cp /etc/apk/repositories /mnt/etc/apk cp /etc/network/interfaces /mnt/etc/network mkdir /mnt/etc/zfs cp /etc/zfs/zroot.key /mnt/etc/zfs # Mount and chroot mount --rbind /dev /mnt/dev mount --rbind /sys /mnt/sys mount --rbind /proc /mnt/proc chroot /mnt # Setup alpine, disk/cache/configs as none! setup-alpine rc-update add hostname # Chown home dir chown "$USERNAME":"$USERNAME" /home/"$USERNAME" # Add necessary things, set services apk add curl efibootmgr zfs zfs-lts #rc-update add zfs-import sysinit rc-update add zfs-mount sysinit # Zfs config for initramfs echo "/etc/hostid" >> /etc/mkinitfs/features.d/zfshost.files echo "/etc/zfs/zroot.key" >> /etc/mkinitfs/features.d/zfshost.files echo 'features="ata base keymap kms mmc scsi usb virtio nvme zfs zfshost"' > /etc/mkinitfs/mkinitfs.conf # Make initramfs mkinitfs -c /etc/mkinitfs/mkinitfs.conf "$(ls /lib/modules)" # Set zfs properties zfs set org.zfsbootmenu:commandline="quiet" "$ZPOOLNAME"/ROOT zfs set org.zfsbootmenu:keysource="${ZPOOLNAME}/ROOT/${ID}" "$ZPOOLNAME" # Format EFI partition mkfs.vfat -F32 "$BOOT_DEVICE" # Cat an /etc/fstab for mounts cat << EOF >> /etc/fstab $BOOT_DEVICE /boot/efi vfat defaults 0 0 tmpfs /tmp tmpfs rw,noatime,nodev,nosuid,mode=1777 0 0 /tmp /var/tmp none rw,noatime,nodev,nosuid,mode=1777,bind 0 0 EOF # Mkdir and mount EFI partition mkdir -p /boot/efi && mount /boot/efi # Grab zfsbootmenu mkdir -p /boot/efi/EFI/ZBM curl -o /boot/efi/EFI/ZBM/VMLINUZ.EFI -L https://get.zfsbootmenu.org/efi # Add zfsbootmenu to bios with efibootmgr efibootmgr -c -d "$BOOT_DISK" -p "$BOOT_PART" -L "ZFSBootMenu" -l '\EFI\ZBM\VMLINUZ.EFI' # Exit, unmount, reboot exit cut -f2 -d" " /proc/mounts | grep ^/mnt | tac | while read i; do umount -l $i; done zpool export "$ZPOOLNAME" reboot