======================================================= Install Gentoo with full-disk encryption and SecureBoot ======================================================= :CreationDate: 2019-07-13 14:09:07 :Id: SW/gentoo-luks-secureboot :tags: - software - configs .. 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 ----------------------------- .. |portage-scan| replace:: ``portage-scan`` .. _`portage-scan`: https://www.thenautilus.net/cgit/misc-scripts/tree/bin/portage-scan * 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 ``_ and unpack it (we download it on the main hdd because the live USB stick is small):: cd /mnt/gentoo wget http://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 ---------- .. |make-efi-keys| replace:: ``make-efi-keys`` .. _`make-efi-keys`: https://www.thenautilus.net/cgit/misc-scripts/tree/bin/make-efi-keys 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/ http://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 ---------- * move the private keys out of the disk * get genkernel to sign the kernel (using keys from removable medium) put a script in ``/etc/kernels/postbuild.d/`` and ``/etc/kernels/postinstall.d/`` and see what it gets passed not much, we have ``KERNEL_ARCH`` and that's it, I'm not sure how to figure out where the kernel to sign is * store a disk encryption key in the TPM https://github.com/shpedoikal/tpm-luks/blob/master/tpm-luks/tpm-luks-chain-hashes https://github.com/morbitzer/linux-luks-tpm-boot/