Skip to content
Snippets Groups Projects

mirrored zfs with luks

  • Clone with SSH
  • Clone with HTTPS
  • Embed
  • Share
    The snippet can be accessed without any authentication.
    Authored by Kevin Cotrone
    Edited
    partition.sh 3.42 KiB
    # https://openzfs.github.io/openzfs-docs/Getting%20Started/NixOS/Root%20on%20ZFS.html#
    # scp partition.sh root@$IP:/root
    #! /usr/bin/env bash
    set -e
    
    ZFS_OPTIONS="-o ashift=12 -o autotrim=on -O acltype=posixacl -O canmount=off -O compression=zstd -O devices=on -O atime=off -O relatime=off -O xattr=sa -O checksum=sha256 -O dnodesize=auto -O mountpoint=/ -O normalization=formD"
    DISK='/dev/disk/by-id/nvme-WD_BLACK_SN850X_2000GB_250128801492 /dev/disk/by-id/nvme-WD_BLACK_SN850X_2000GB_250205804965'
    BOOT_SiZE='4GiB'
    
    MNT=$(mktemp -d)
    
    echo "Warning! This will erase the contents of ${DISK}."
    read -p "Press enter to continue"
    
    partition_disk () {
     local disk="${1}"
     blkdiscard -f "${disk}" || true
    
     # Setup an EFI partition with a size of BOOT_SIZE and the rest of the disk for the rpool
     parted --script --align=optimal "${disk}" -- \
       mklabel gpt \
       mkpart EFI 1MiB $BOOT_SiZE \
       set 1 esp on \
       align-check optimal 1 \
       mkpart rpool $BOOT_SiZE 100% \
       align-check optimal 2 \
       print
    
     partprobe "${disk}"
    }
    
    for i in ${DISK}; do
       partition_disk "${i}"
    done
    
    # Read luks password and make sure they match
    read -sp "Please enter passphrase: " PASS
    echo -e "\n"
    read -sp "Please re-enter passphrase: " REPASS
    echo -e "\n"
    if [[ "$PASS" != "$REPASS" ]];
    then
    echo "Passphrases did not match!"
    exit 1
    else
    echo -n $PASS > /tmp/mykeyfile
    fi
    
    # Create luks partitions and open them
    for i in ${DISK}; do
       # see PASSPHRASE PROCESSING section in cryptsetup(8)
       cryptsetup luksFormat --type luks2 "${i}"-part2 /tmp/mykeyfile
       cryptsetup open "${i}"-part2 luks-rpool-"${i##*/}"-part2 /tmp/mykeyfile
       cryptsetup --allow-discards --persistent refresh luks-rpool-"${i##*/}"-part2
    done
    
    # Create the zpool
    zpool create $ZFS_OPTIONS -R "${MNT}" rpool mirror \
      $(for i in ${DISK}; do
          printf '/dev/mapper/luks-rpool-%s ' "${i##*/}-part2";
        done)
    
    # Create the datasets in the zpool
    zfs create -o mountpoint=none rpool/local
    zfs create -o mountpoint=/mounted-for-the-purpose-of-auto-snapshot rpool/safe
    zfs create -o refreservation=10G -o mountpoint=none rpool/local/reserved
    zfs create -o canmount=off -o mountpoint=/ rpool/safe/root
    zfs create -o canmount=on -o mountpoint=/nix rpool/local/nix
    zfs create -o canmount=on -o mountpoint=/etc rpool/safe/etc
    zfs create -o canmount=on -o mountpoint=/home rpool/safe/home
    zfs create -o canmount=on -o mountpoint=/var rpool/safe/var
    zfs create -o canmount=on -o mountpoint=/var/lib rpool/safe/var/lib
    zfs create -o canmount=on -o mountpoint=/var/log rpool/safe/var/log
    zfs create -o canmount=on -o mountpoint=/var/spool rpool/safe/var/spool
    
    for i in ${DISK}; do
     mkfs.vfat -n EFI "${i}"-part1
    done
    
    for i in ${DISK}; do
     mount -t vfat -o fmask=0077,dmask=0077,iocharset=iso8859-1,X-mount.mkdir "${i}"-part1 "${MNT}"/boot
     break
    done
    
    # Generate the initial configuration
    nixos-generate-config --root "${MNT}"
    HOSTID=$(head -c4 /dev/urandom | od -A none -t x4 | tr -d ' ')
    
    # Set the hostname and network configuration
    echo "networking.hostId = \"${HOSTID}\";"
    
    # Write out the configuration for initrd in order to boot
    tee <<EOF
      boot.initrd.luks.devices = {
    EOF
    
    for i in ${DISK}; do echo \"luks-rpool-"${i##*/}-part2"\".device = \"${i}-part2\"\; ; done
    
    tee <<EOF
    };
    EOF
    
    read -p "Copy the generated nix config and add it into the mounted config. Press enter to continue"
    nano "${MNT}"/etc/nixos/configuration.nix
    
    echo "Installing NixOS"
    chmod o+rx "${MNT}"
    nixos-install --root "${MNT}" --no-root-passwd
    cd /
    umount -Rl "${MNT}"
    • I recommend doing passwords via:

      `` echo

      read -p "Please enter node number: " NODE echo -e "\n"

      read -sp "Please enter passphrase: " PASS echo -e "\n" read -sp "Please re-enter passphrase: " REPASS echo -e "\n"

      if [ "PASS" != "REPASS" ]; then echo "Passphrases did not match!" exit 1 else echo -n $PASS > /tmp/mykeyfile fi ``

      to avoid mismatch issues.

      -O devices=off

      You're going to need devices somewhere.

      relatime=off

      You may also want that.

      zfs create -o mountpoint=none rpool/safe

      If this isn't mounted, you won't get atomic snapshots of that tree given the current system in nixos.

    • Used the password suggestion, set devices=on explicitly (it's the default), set relatime=off, mounted rpool/safe to /mounted-for-the-purpose-of-auto-snapshot

    • Set end for zfs partition to 100%

    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment