Install Gentoo with full-disk encryption and SecureBoot

Note

These are personal notes. They may be incomplete, incorrect, and misleading. Or they may actually work! Use at your own risk (but improvements / corrections are always welcome)

Capture data from old machine

  • run portage-scan, trim stuff we don't care about, save to $machine_name.txt
  • maybe set PermitRootLogin yes on old machine /etc/ssh/sshd_config, and set root password
  • on the helper machine:
    mkdir $machine_name
    rsync -vaHSxr --files-from $machine_name.txt \
          root@$machine_hostname: $machine_name/
    
  • also record which services are running:
    rc-update --all
    
  • maybe which fonts are enabled:
    eselect fontconfig list
    

Install new machine

  • disable secureboot
  • boot on system rescue cd usb stick
  • startx
  • connect to WiFi
  • terminal
  • gparted
    • empty partition table
    • create new GPT
    • one 200MB partition at start, fat32, label boot name boot
    • one partition for the rest, ext4, label root name root
  • set root password
  • disable the firewall:
    iptables -F
    iptables -P INPUT ACCEPT
    
  • ssh in from a better machine
  • cryptsetup benchmark to check crypto speed
  • create encrypted volume:

    cryptsetup --cipher aes-xts-plain64 --key-size 256 \
      --hash whirlpool --type luks2 luksFormat \
      $(readlink -f /dev/disk/by-partlabel/root)
    

    (apparently cryptsetup doesn't like symlinks)

  • make filesystem, mount it:
    cryptsetup open /dev/disk/by-partlabel/root root
    mkfs.ext4 -L root /dev/mapper/root
    mkdir /mnt/gentoo
    mount /dev/disk/by-label/root /mnt/gentoo
    
  • get stage3 from https://www.gentoo.org/downloads/#other-arches and unpack it (we download it on the main hdd because the live USB stick is small):
    cd /mnt/gentoo
    wget https://distfiles.gentoo.org/releases/amd64/autobuilds/20190707T214502Z/stage3-amd64-20190707T214502Z.tar.xz
    tar xvpf /mnt/gentoo/stage3*.tar.xz --xattrs-include='*.*' --numeric-owner
    
  • copy some configuration over, while you're at it
    • skip /var/lib/portage/world, avoid layman stuff
    • include most portage config, though
  • prepare and chroot:
    cp /etc/resolv.conf /mnt/gentoo/etc/
    
    cd /mnt/gentoo
    mount --types proc /proc /mnt/gentoo/proc
    mount --rbind /sys /mnt/gentoo/sys
    mount --make-rslave /mnt/gentoo/sys
    mount --rbind /dev /mnt/gentoo/dev
    mount --make-rslave /mnt/gentoo/dev
    chroot /mnt/gentoo /bin/bash
    source /etc/profile
    
    mount /dev/disk/by-partlabel/boot boot/
    
  • bring portage up:
    emerge --sync
    eselect news read
    
  • do whatever tweaks are necessary (e.g. switch to profile 17.1)
  • kernel time! copy the /proc/config.gz from old machine into /mnt/gentoo/root/config.gz, install genkernel:

    USE='-doc -emacs -perl -python -subversion -tk -webdav -abi_x86_32 cryptsetup' \
    emerge -av1 genkernel-next gentoo-sources
    genkernel --kernel-config=/root/config.gz --no-firmware all
    

    (this assumes we're using my genkernel.conf!)

    edit config, make sure you have crypto options:

    • XTS
    • key wrapping
    • all hash modes
    • all SHAs
    • Whirlpool
    • all AESs
    • all compressions
    • prng
    • all user-space interfaces

    also device mapper ("Multiple devices driver support") and "crypt target support"

    built-in kernel command line:

    crypt_root=UUID=??? rootfstype=ext4
    

    for crypt_root: take UUID (not PARTUUID) from blkid -t PARTLABEL=root -o export

    will probably fail, no pre-existing initramfs during kernel compilation (use correct version for initramfs filename):

    touch /var/tmp/genkernel/initramfs-4.19.37-gentoo.cpio
    genkernel --kernel-config=/usr/src/linux/.config \
              --no-firmware --no-clean all
    

    (maybe genkernel --no-firmware --no-install initramfs first would solve this?)

    Add the firmware to the initramfs (make sure you have sys-kernel/linux-firmware savedconfig in package.use):

    mkdir -p /etc/portage/savedconfig/sys-kernel
    
    find /lib/modules/*-gentoo/ -type f -name '*.ko' \
      -exec modinfo -F firmware '{}' ';' \
      > /etc/portage/savedconfig/sys-kernel/linux-firmware
    
    emerge -av1 linux-firmware
    genkernel --kernel-config=/usr/src/linux/.config --no-clean all
    
  • install wpa_supplicant for wireless network after reboot (my stage3 came with ~arch openssl/openssh?):

    USE='-doc -emacs -qt5 -gpm -X' emerge -avuN1 \
      openssl openssh wpa_supplicant dhcpcd
    

    symlink the init scripts:

    ln -s net.lo net.net0
    ln -s net.lo net.wifi0
    

    and enable:

    rc-update add net.wifi0 default
    

    (make sure /etc/udev/rules.d/70-network-interfaces.rules maps the adapters by MAC:

    SUBSYSTEM=="net", DRIVERS=="?*", ATTR{address}=="20:47:47:ea:f2:58", NAME="net0"
    SUBSYSTEM=="net", DRIVERS=="?*", ATTR{address}=="dc:53:60:38:25:84", NAME="wifi0"
    

    )

  • tools:
    USE='-doc -emacs -qt5 -gpm -X' emerge -avuN1 \
      vixie-cron syslog-ng mlocate
    rc-update add vixie-cron default
    rc-update add syslog-ng default
    rc-update add sshd default
    
  • final checks: /etc/fstab:

    LABEL=BOOT  /boot             vfat   noauto,noatime,utf8=1  0 2
    LABEL=root  /                 ext4   relatime               0 1
    none        /var/tmp/portage  tmpfs  size=75%,defaults      0 0
    

    /etc/hostname, /etc/conf.d/net, /etc/wpa_supplicant/*

  • create a user that can sudo, give it a password:
    useradd -m -U -u 1000 \
       -G wheel,portage,audio,video,usb,disk,cron \
       dakkar
    passwd dakkar
    emerge -av1 sudo
    
  • set EFI booting options:
    # remove existing boot options, one at a time
    efibootmgr -b 0 -B
    
    # create new options
    efibootmgr -c -d /dev/nvme0n1 -p 1 -L gentoo -l EFI\\gentoo.efi
    efibootmgr -c -d /dev/nvme0n1 -p 1 -L gentoo-old -l EFI\\gentoo-old.efi
    
    # set boot order
    efibootmgr -o 0,1
    
  • unmount (from outside the chroot):
    umount -R /mnt/gentoo
    
  • reboot, tell UEFI to use our kernel (if you didn't use efibootmgr), go
  • log in as dakkar via ssh, copy world from old machine, install everything:

    sudo emerge -av1 app-misc/screen
    screen -S emerge
    sudo emerge -pv $(< world)
    

    might require some USE='-foo' to break cycles, or emerging some packages by hand first

  • in the meantime, restore /home/dakkar with something like:

    rsync -vaHSx admin@192.168.1.142::NetBackup/exelion/home/dakkar/ \
                 /home/dakkar/
    

    (we don't have avahi yet, can't use the mDNS name)

  • restore fontconfig, special services (net, user-specific emacs, openvpn, &c)

SecureBoot

Install efitools, sbsigntools. Run the make-efi-keys program:

make-efi-keys $hostname
cp keys-for-$hostname/*.{cer,crt,auth} /boot/
sbsign --key DB.key --cert DB.crt /boot/kernel-genkernel-*-gentoo

reboot, then from the UEFI setup:

  • clear all secureboot keys (the Dell laptops I've tried this on can always restore their factory set of keys)
  • replace the DB from file (Dell wants the DB.auth)
  • then the KEK
  • then the PK
  • enable secure boot
  • make sure that the signed kernel is going to be booted
  • reboot

Info from:

http://www.kroah.com/log/blog/2013/09/02/booting-a-self-signed-linux-kernel/ https://www.rodsbooks.com/efi-bootloaders/controlling-sb.html

Signed modules

Using the same key we use to sign the kernel, packaged as PEM:

openssl x509 -in DB.crt -out DB.pem
cat DB.key DB.pem > kernel-signing-key.pem

the config option for that file is under "Cryptographic API"

keep the DB.crt and DB.key around, they're needed to sign out-of-tree modules (virtualbox, for example):

/usr/src/linux/scripts/sign-file sha256 DB.key DB.crt vboxdrv.ko

Next steps

DatesCreated: 2019-07-13 14:09:07 Last modification: 2023-02-10 12:45:24