=======================================================
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
<http://www.system-rescue-cd.org/Installing-SystemRescueCd-on-a-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 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/