Arch Linux: Nest system datasets for more flexibility; encryption warning messages
Arch Linux Root on ZFS: Encrypt boot pool with LUKS Typo fixes; tweaks Add Secure Boot Secure Boot key enrollment differs Secure Boot: rm HP laptop ref Strictly follow manu. instructions. I bricked my EliteBook 820 G2 with KeyTool.efi Example Secure Boot customization links Back up Secure Boot signing keys Secure Boot: Add link to bricked motherboard Replace Secure Boot with a link; out of scope Signed-off-by: Maurice Zhou <ja@apvc.uk>
This commit is contained in:
committed by
Richard Laager
parent
13271f2467
commit
c25037beb0
@@ -73,6 +73,9 @@ without the passphrase being entered at the console. Performance is
|
||||
good. As the encryption happens in ZFS, even if multiple disks (mirror
|
||||
or raidz topologies) are used, the data only has to be encrypted once.
|
||||
|
||||
Boot pool can be optionally encrypted with LUKS, see `here <#encrypt-boot-pool-with-luks>`__.
|
||||
Encrypted boot pool can protect initrd from tempering.
|
||||
|
||||
Preinstallation
|
||||
----------------
|
||||
Download Arch Linux live image
|
||||
@@ -291,6 +294,9 @@ Format and Partition the Target Disks
|
||||
sgdisk -n4:0:0 -t4:8308 $DISK
|
||||
|
||||
Adjust the swap partition size to your needs.
|
||||
If `hibernation <#hibernation>`__ is needed,
|
||||
swap size should be same or larger than RAM.
|
||||
Check RAM size with ``free -h``.
|
||||
|
||||
#. Repeat the above steps for other target disks, if any.
|
||||
|
||||
@@ -322,6 +328,7 @@ Create Root and Boot Pools
|
||||
|
||||
zpool create \
|
||||
-o ashift=12 \
|
||||
-o autotrim=on \
|
||||
-d -o feature@async_destroy=enabled \
|
||||
-o feature@bookmarks=enabled \
|
||||
-o feature@embedded_data=enabled \
|
||||
@@ -374,12 +381,12 @@ Create Root and Boot Pools
|
||||
“invalid dnode type” error. This feature does not matter for ``/boot``
|
||||
anyway.
|
||||
|
||||
#. Create root pool:
|
||||
|
||||
- Unencrypted::
|
||||
#. Create root pool::
|
||||
|
||||
zpool create \
|
||||
-o ashift=12 \
|
||||
-o autotrim=on \
|
||||
-R $INST_MNT \
|
||||
-O acltype=posixacl \
|
||||
-O canmount=off \
|
||||
-O compression=zstd \
|
||||
@@ -388,26 +395,6 @@ Create Root and Boot Pools
|
||||
-O relatime=on \
|
||||
-O xattr=sa \
|
||||
-O mountpoint=/ \
|
||||
-R $INST_MNT \
|
||||
rpool_$INST_UUID \
|
||||
${DISK}-part3
|
||||
|
||||
- Encrypted::
|
||||
|
||||
zpool create \
|
||||
-o ashift=12 \
|
||||
-O acltype=posixacl \
|
||||
-O canmount=off \
|
||||
-O compression=zstd \
|
||||
-O dnodesize=auto \
|
||||
-O normalization=formD \
|
||||
-O relatime=on \
|
||||
-O xattr=sa \
|
||||
-O mountpoint=/ \
|
||||
-R $INST_MNT \
|
||||
-O encryption=on \
|
||||
-O keylocation=prompt \
|
||||
-O keyformat=passphrase \
|
||||
rpool_$INST_UUID \
|
||||
${DISK}-part3
|
||||
|
||||
@@ -474,36 +461,81 @@ Create Root and Boot Pools
|
||||
|
||||
Create Datasets
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
#. Create system boot container::
|
||||
|
||||
zfs create \
|
||||
-o canmount=off \
|
||||
-o mountpoint=/boot \
|
||||
bpool_$INST_UUID/sys
|
||||
|
||||
#. Create system root container:
|
||||
|
||||
Dataset encryption is set at creation and can not be altered later,
|
||||
but encrypted dataset can be created inside an unencrypted parent dataset.
|
||||
|
||||
- Unencrypted::
|
||||
|
||||
zfs create \
|
||||
-o canmount=off \
|
||||
-o mountpoint=/ \
|
||||
rpool_$INST_UUID/sys
|
||||
|
||||
- Encrypted:
|
||||
|
||||
#. Choose a strong password.
|
||||
|
||||
Once the password is compromised,
|
||||
dataset and pool must be destroyed,
|
||||
disk wiped and system rebuilt from scratch to protect confidentiality.
|
||||
`Merely changing password is not enough <https://openzfs.github.io/openzfs-docs/man/8/zfs-change-key.8.html>`__.
|
||||
|
||||
Example: generate passphrase with `xkcdpass <https://github.com/redacted/XKCD-password-generator>`_::
|
||||
|
||||
pacman -S --noconfirm xkcdpass
|
||||
xkcdpass -Vn 10 -w /usr/lib/python*/site-packages/xkcdpass/static/eff-long
|
||||
|
||||
Password can be supplied with SSH at boot time,
|
||||
see `Supply password with SSH <#supply-password-with-ssh>`__.
|
||||
|
||||
#. Create dataset::
|
||||
|
||||
zfs create \
|
||||
-o canmount=off \
|
||||
-o mountpoint=/ \
|
||||
-o encryption=on \
|
||||
-o keylocation=prompt \
|
||||
-o keyformat=passphrase \
|
||||
rpool_$INST_UUID/sys
|
||||
|
||||
#. Create container datasets::
|
||||
|
||||
zfs create -o canmount=off -o mountpoint=none bpool_$INST_UUID/BOOT
|
||||
zfs create -o canmount=off -o mountpoint=none rpool_$INST_UUID/ROOT
|
||||
zfs create -o canmount=off -o mountpoint=none rpool_$INST_UUID/DATA
|
||||
zfs create -o canmount=off -o mountpoint=none bpool_$INST_UUID/sys/BOOT
|
||||
zfs create -o canmount=off -o mountpoint=none rpool_$INST_UUID/sys/ROOT
|
||||
zfs create -o canmount=off -o mountpoint=none rpool_$INST_UUID/sys/DATA
|
||||
|
||||
#. Create root and boot filesystem datasets::
|
||||
|
||||
zfs create -o mountpoint=legacy -o canmount=noauto bpool_$INST_UUID/BOOT/default
|
||||
zfs create -o mountpoint=/ -o canmount=noauto rpool_$INST_UUID/ROOT/default
|
||||
zfs create -o mountpoint=legacy -o canmount=noauto bpool_$INST_UUID/sys/BOOT/default
|
||||
zfs create -o mountpoint=/ -o canmount=noauto rpool_$INST_UUID/sys/ROOT/default
|
||||
|
||||
#. Mount root and boot filesystem datasets::
|
||||
|
||||
zfs mount rpool_$INST_UUID/ROOT/default
|
||||
zfs mount rpool_$INST_UUID/sys/ROOT/default
|
||||
mkdir $INST_MNT/boot
|
||||
mount -t zfs bpool_$INST_UUID/BOOT/default $INST_MNT/boot
|
||||
mount -t zfs bpool_$INST_UUID/sys/BOOT/default $INST_MNT/boot
|
||||
|
||||
#. Create datasets to separate user data from root filesystem::
|
||||
|
||||
zfs create -o mountpoint=/ -o canmount=off rpool_$INST_UUID/DATA/default
|
||||
zfs create -o mountpoint=/ -o canmount=off rpool_$INST_UUID/sys/DATA/default
|
||||
|
||||
for i in {usr,var,var/lib};
|
||||
do
|
||||
zfs create -o canmount=off rpool_$INST_UUID/DATA/default/$i
|
||||
zfs create -o canmount=off rpool_$INST_UUID/sys/DATA/default/$i
|
||||
done
|
||||
|
||||
for i in {home,root,srv,usr/local,var/log,var/spool,var/tmp};
|
||||
do
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/$i
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/$i
|
||||
done
|
||||
|
||||
chmod 750 $INST_MNT/root
|
||||
@@ -513,32 +545,32 @@ Create Datasets
|
||||
|
||||
If this system will have games installed::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/games
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/games
|
||||
|
||||
If you use /var/www on this system::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/www
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/www
|
||||
|
||||
If this system will use GNOME::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/lib/AccountsService
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/lib/AccountsService
|
||||
|
||||
If this system will use Docker (which manages its own datasets &
|
||||
snapshots)::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/lib/docker
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/lib/docker
|
||||
|
||||
If this system will use NFS (locking)::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/lib/nfs
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/lib/nfs
|
||||
|
||||
If this system will use Linux Containers::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/lib/lxc
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/lib/lxc
|
||||
|
||||
If this system will use libvirt::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/lib/libvirt
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/lib/libvirt
|
||||
|
||||
Format and Mount EFI System Partition
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -566,27 +598,27 @@ Package Installation
|
||||
| sed "s|.*${INST_LINVAR}=||" \
|
||||
| awk '{ print $1 }')
|
||||
|
||||
#. Install kernel::
|
||||
#. Install kernel. Download from archive if kernel is not available::
|
||||
|
||||
if [ ${INST_LINVER} == \
|
||||
$(pacman -Si ${INST_LINVAR} | grep Version | awk '{ print $3 }') ]; then
|
||||
pacstrap $INST_MNT ${INST_LINVAR}
|
||||
else
|
||||
pacstrap -U $INST_MNT \
|
||||
https://archive.archlinux.org/packages/l/${INST_LINVAR}/${INST_LINVAR}-${INST_LINVER}-x86_64.pkg.tar.zst
|
||||
fi
|
||||
|
||||
#. Install archzfs package::
|
||||
|
||||
pacstrap $INST_MNT zfs-$INST_LINVAR
|
||||
|
||||
#. If your computer has hardware that requires firmware to run::
|
||||
#. Install firmware::
|
||||
|
||||
pacstrap $INST_MNT linux-firmware
|
||||
pacstrap $INST_MNT linux-firmware intel-ucode amd-ucode
|
||||
|
||||
#. If you boot your computer with EFI::
|
||||
|
||||
pacstrap $INST_MNT dosfstools efibootmgr
|
||||
|
||||
#. Microcode:
|
||||
|
||||
- ``pacstrap $INST_MNT amd-ucode``
|
||||
- ``pacstrap $INST_MNT intel-ucode``
|
||||
pacstrap $INST_MNT efibootmgr
|
||||
|
||||
#. For other optional packages,
|
||||
see `ArchWiki <https://wiki.archlinux.org/index.php/Installation_guide#Installation>`__.
|
||||
@@ -614,13 +646,13 @@ System Configuration
|
||||
|
||||
#. Generate fstab::
|
||||
|
||||
echo bpool_$INST_UUID/BOOT/default /boot zfs rw,xattr,posixacl 0 0 >> $INST_MNT/etc/fstab
|
||||
echo bpool_$INST_UUID/sys/BOOT/default /boot zfs rw,xattr,posixacl 0 0 >> $INST_MNT/etc/fstab
|
||||
echo UUID=$(blkid -s UUID -o value ${DISK}-part1) /boot/efi vfat \
|
||||
x-systemd.idle-timeout=1min,x-systemd.automount,noauto,umask=0022,fmask=0022,dmask=0022 0 1 >> $INST_MNT/etc/fstab
|
||||
|
||||
If a swap partition has been created::
|
||||
|
||||
echo crypt-swap ${DISK}-part4 /dev/urandom swap,cipher=aes-cbc-essiv:sha256,size=256 >> $INST_MNT/etc/crypttab
|
||||
echo crypt-swap ${DISK}-part4 /dev/urandom swap,cipher=aes-cbc-essiv:sha256,size=256,discard >> $INST_MNT/etc/crypttab
|
||||
echo /dev/mapper/crypt-swap none swap defaults 0 0 >> $INST_MNT/etc/fstab
|
||||
|
||||
#. Configure mkinitcpio::
|
||||
@@ -790,6 +822,50 @@ Generate GRUB Boot Menu
|
||||
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
|
||||
Optional Configuration
|
||||
----------------------
|
||||
|
||||
Supply password with SSH
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Optional:
|
||||
|
||||
#. Install mkinitcpio tools::
|
||||
|
||||
pacman -S mkinitcpio-netconf mkinitcpio-dropbear openssh
|
||||
|
||||
#. Store public keys in ``/etc/dropbear/root_key``::
|
||||
|
||||
vi /etc/dropbear/root_key
|
||||
|
||||
Note that dropbear only supports RSA keys.
|
||||
|
||||
#. Edit mkinitcpio::
|
||||
|
||||
tee /etc/mkinitcpio.conf <<- 'EOF'
|
||||
HOOKS=(base udev autodetect modconf block keyboard netconf dropbear zfsencryptssh zfs filesystems)
|
||||
EOF
|
||||
|
||||
#. Add ``ip=`` to kernel command line::
|
||||
|
||||
# example DHCP
|
||||
echo 'GRUB_CMDLINE_LINUX="ip=::::::dhcp"' >> /etc/default/grub
|
||||
|
||||
Details for ``ip=`` can be found at
|
||||
`here <https://www.kernel.org/doc/html/latest/admin-guide/nfs/nfsroot.html#kernel-command-line>`__.
|
||||
|
||||
#. Generate host keys::
|
||||
|
||||
ssh-keygen -Am pem
|
||||
|
||||
#. Regenerate initramfs::
|
||||
|
||||
mkinitcpio -P
|
||||
|
||||
#. Update GRUB menu::
|
||||
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
|
||||
Finish Installation
|
||||
-------------------
|
||||
|
||||
@@ -799,8 +875,8 @@ Finish Installation
|
||||
|
||||
#. Take a snapshot of the clean installation for future use::
|
||||
|
||||
zfs snapshot -r rpool_$INST_UUID/ROOT/default@install
|
||||
zfs snapshot -r bpool_$INST_UUID/BOOT/default@install
|
||||
zfs snapshot -r rpool_$INST_UUID/sys/ROOT/default@install
|
||||
zfs snapshot -r bpool_$INST_UUID/sys/BOOT/default@install
|
||||
|
||||
#. Unmount EFI system partition::
|
||||
|
||||
@@ -838,18 +914,18 @@ Mirror EFI System Partition
|
||||
|
||||
#. Create a service to monitor and sync EFI partitions::
|
||||
|
||||
tee /usr/lib/systemd/system/boot/efis-sync.path << EOF
|
||||
tee /etc/systemd/system/efis-sync.path << EOF
|
||||
[Unit]
|
||||
Description=Monitor changes in EFI system partition
|
||||
|
||||
[Path]
|
||||
PathModified=/boot/efi/EFI/arch/
|
||||
|
||||
PathChanged=/boot/efi/EFI/arch/
|
||||
#PathChanged=/boot/efi/EFI/BOOT/
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
tee /usr/lib/systemd/system/boot/efis-sync.service << EOF
|
||||
tee /etc/systemd/system/efis-sync.service << EOF
|
||||
[Unit]
|
||||
Description=Sync EFI system partition contents to backups
|
||||
|
||||
@@ -878,72 +954,6 @@ This need to be manually applied when GRUB is updated.
|
||||
grub-install /dev/disk/by-id/$i
|
||||
done
|
||||
|
||||
Change encryption method
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By default the root pool is encrypted with a key file,
|
||||
created at installation.
|
||||
|
||||
Password
|
||||
^^^^^^^^
|
||||
|
||||
After installation, encryption by password can be enabled with::
|
||||
|
||||
zfs change-key -l -o keylocation=prompt -o keyformat=passphrase rpool_$INST_UUID
|
||||
|
||||
See ``man 8 zfs-change-key``.
|
||||
If password is enabled, the system will require this password to boot.
|
||||
Password can be entered locally with keyboard or remotely with SSH.
|
||||
|
||||
Supply password with SSH
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#. Install mkinitcpio tools::
|
||||
|
||||
pacman -S mkinitcpio-netconf mkinitcpio-dropbear
|
||||
|
||||
#. Store authorized keys in ``/etc/dropbear/root_key``::
|
||||
|
||||
vi /etc/dropbear/root_key
|
||||
|
||||
Note that dropbear only supports RSA keys.
|
||||
|
||||
#. Edit mkinitcpio::
|
||||
|
||||
tee /etc/mkinitcpio.conf <<- 'EOF'
|
||||
HOOKS=(base udev autodetect modconf block keyboard netconf dropbear zfsencryptssh zfs filesystems)
|
||||
EOF
|
||||
|
||||
#. Add ``ip=`` to kernel command line::
|
||||
|
||||
# example DHCP
|
||||
echo 'GRUB_CMDLINE_LINUX="ip=::::::dhcp"' >> /etc/default/grub
|
||||
|
||||
Details for ``ip=`` can be found at
|
||||
`here <https://www.kernel.org/doc/html/latest/admin-guide/nfs/nfsroot.html#kernel-command-line>`__.
|
||||
|
||||
#. If using OpenSSH as SSH server, convert host keys to PEM format::
|
||||
|
||||
for i in {rsa,dsa,ecdsa,ed25519}; do
|
||||
ssh-keygen -p -m PEM -f /etc/ssh/ssh_host_${i}_key -qN ""
|
||||
done
|
||||
|
||||
#. Regenerate initramfs::
|
||||
|
||||
mkinitcpio -P
|
||||
|
||||
#. Update GRUB menu::
|
||||
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
|
||||
Key file
|
||||
^^^^^^^^
|
||||
|
||||
You can also set a new key file for root pool and
|
||||
store the key file on an external drive::
|
||||
|
||||
zfs change-key -l -o keylocation=file:///path/to/keyfile -o keyformat=raw rpool_$INST_UUID
|
||||
|
||||
Boot Environment Manager
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -963,68 +973,371 @@ see `ArchWiki <https://wiki.archlinux.org/index.php/Installation_guide#Post-inst
|
||||
|
||||
Remember to create separate datasets for individual users.
|
||||
|
||||
Encrypt boot pool with LUKS
|
||||
---------------------------
|
||||
|
||||
If encryption is enabled earlier, boot pool can be optionally encrypted.
|
||||
|
||||
This step will rebuild boot pool
|
||||
on a LUKS 1 container. Password must
|
||||
be entered interactively at GRUB and thus incompatible with
|
||||
`Supply password with SSH <#supply-password-with-ssh>`__.
|
||||
|
||||
Encrypted boot pool protects initramfs from
|
||||
malicious modification and supports hibernation
|
||||
to encrypted swap.
|
||||
|
||||
#. Create encryption keys::
|
||||
|
||||
mkdir /etc/cryptkey.d/
|
||||
chmod 700 /etc/cryptkey.d/
|
||||
dd bs=32 count=1 if=/dev/urandom of=/etc/cryptkey.d/lukskey-bpool_$INST_UUID
|
||||
dd bs=32 count=1 if=/dev/urandom of=/etc/cryptkey.d/zfskey-rpool_$INST_UUID
|
||||
|
||||
#. Backup boot pool::
|
||||
|
||||
zfs snapshot -r bpool_$INST_UUID/sys@pre-luks
|
||||
zfs send -R bpool_$INST_UUID/sys@pre-luks > /root/bpool_$INST_UUID-pre-luks
|
||||
|
||||
#. Check boot pool creation command::
|
||||
|
||||
zpool history bpool_$INST_UUID | head -n2 \
|
||||
| grep 'zpool create' > /root/bpool_$INST_UUID-cmd
|
||||
|
||||
Note the vdev disks at the end of the command.
|
||||
|
||||
#. Unmount EFI partition::
|
||||
|
||||
umount /boot/efi
|
||||
umount /boot/efis/* # if backups exist
|
||||
|
||||
#. Destroy boot pool::
|
||||
|
||||
zpool destroy bpool_$INST_UUID
|
||||
|
||||
#. Enter LUKS password::
|
||||
|
||||
LUKS_PWD=rootpool
|
||||
|
||||
#. Create LUKS containers::
|
||||
|
||||
for i in {disk1,disk2}; do
|
||||
cryptsetup luksFormat -q --type luks1 /dev/disk/by-id/$i-part2 --key-file /etc/cryptkey.d/lukskey-bpool_$INST_UUID
|
||||
echo $LUKS_PWD | cryptsetup luksAddKey /dev/disk/by-id/$i-part2 --key-file /etc/cryptkey.d/lukskey-bpool_$INST_UUID
|
||||
cryptsetup open /dev/disk/by-id/$i-part2 luks-bpool_$INST_UUID-$i-part2 --key-file /etc/cryptkey.d/lukskey-bpool_$INST_UUID
|
||||
echo luks-bpool_$INST_UUID-$i-part2 /dev/disk/by-id/$i-part2 /etc/cryptkey.d/lukskey-bpool_$INST_UUID discard >> /etc/crypttab
|
||||
done
|
||||
|
||||
#. Embed key file in initramfs::
|
||||
|
||||
tee -a /etc/mkinitcpio.conf <<EOF
|
||||
FILES=(/etc/cryptkey.d/lukskey-bpool_$INST_UUID /etc/cryptkey.d/zfskey-rpool_$INST_UUID)
|
||||
EOF
|
||||
|
||||
#. Recreate boot pool.
|
||||
|
||||
Reuse command from ``/root/bpool_$INST_UUID-cmd``.
|
||||
Remove ``-R $INST_MNT``
|
||||
and replace devices with ``/dev/mapper/luks-bpool_$INST_UUID-$DISK-part2``.
|
||||
|
||||
Example::
|
||||
|
||||
zpool create \
|
||||
-o ashift=12 \
|
||||
-o autotrim=on \
|
||||
-d -o feature@async_destroy=enabled \
|
||||
-o feature@bookmarks=enabled \
|
||||
-o feature@embedded_data=enabled \
|
||||
-o feature@empty_bpobj=enabled \
|
||||
-o feature@enabled_txg=enabled \
|
||||
-o feature@extensible_dataset=enabled \
|
||||
-o feature@filesystem_limits=enabled \
|
||||
-o feature@hole_birth=enabled \
|
||||
-o feature@large_blocks=enabled \
|
||||
-o feature@lz4_compress=enabled \
|
||||
-o feature@spacemap_histogram=enabled \
|
||||
-O acltype=posixacl \
|
||||
-O canmount=off \
|
||||
-O compression=lz4 \
|
||||
-O devices=off \
|
||||
-O normalization=formD \
|
||||
-O relatime=on \
|
||||
-O xattr=sa \
|
||||
-O mountpoint=/boot \
|
||||
# remove -R $INST_MNT
|
||||
bpool_$INST_UUID \
|
||||
/dev/mapper/luks-bpool_$INST_UUID-$disk1-part2
|
||||
|
||||
#. Restore boot pool backup::
|
||||
|
||||
cat /root/bpool_$INST_UUID-pre-luks | zfs recv bpool_$INST_UUID/sys
|
||||
|
||||
#. Mount boot dataset and EFI partitions::
|
||||
|
||||
mount /boot
|
||||
mount /boot/efi
|
||||
mount /boot/efis/*
|
||||
|
||||
#. Change root pool password to key file::
|
||||
|
||||
zfs change-key -l \
|
||||
-o keylocation=file:///etc/cryptkey.d/zfskey-rpool_$INST_UUID \
|
||||
-o keyformat=raw \
|
||||
rpool_$INST_UUID/sys
|
||||
|
||||
#. Remove ``zfsencryptssh`` hook.
|
||||
Encrypted boot pool is incompatible with
|
||||
password by SSH::
|
||||
|
||||
sed -i 's|zfsencryptssh||g' /etc/mkinitcpio.conf
|
||||
|
||||
If ``zfsencryptssh`` is not removed, initramfs will
|
||||
stuck at ``fail to load key material`` and fail to boot.
|
||||
|
||||
#. Generate initramfs::
|
||||
|
||||
mkinitcpio -P
|
||||
|
||||
#. Import boot pool after starting systemd::
|
||||
|
||||
tee /etc/systemd/system/zfs-bpool-import-cache.service <<EOF
|
||||
[Unit]
|
||||
Description=Import boot pool by cache file
|
||||
Documentation=man:zpool(8)
|
||||
DefaultDependencies=no
|
||||
Requires=systemd-udev-settle.service
|
||||
After=zfs-import-cache.service
|
||||
After=zfs-import.target
|
||||
Before=boot.mount
|
||||
ConditionFileNotEmpty=/etc/zfs/zpool.cache
|
||||
ConditionPathIsDirectory=/sys/module/zfs
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/zpool import -c /etc/zfs/zpool.cache -aN
|
||||
|
||||
[Install]
|
||||
WantedBy=zfs-import.target
|
||||
EOF
|
||||
|
||||
systemctl enable zfs-bpool-import-cache.service
|
||||
|
||||
Initramfs will still try to import boot pool
|
||||
before mapping LUKS containers. This will fail
|
||||
and delay boot for a few seconds.
|
||||
|
||||
|
||||
#. Enable GRUB cryptodisk::
|
||||
|
||||
echo "GRUB_ENABLE_CRYPTODISK=y" >> /etc/default/grub
|
||||
|
||||
#. Install GRUB. See `GRUB Installation <#grub-installation>`__.
|
||||
|
||||
#. Generate GRUB menu::
|
||||
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
|
||||
#. **Important**: Back up root dataset key ``/etc/cryptkey.d/zfskey-rpool_$INST_UUID``
|
||||
to a secure location.
|
||||
|
||||
In the possible event of LUKS container corruption,
|
||||
data on root set will only be available
|
||||
with this key.
|
||||
|
||||
Secure Boot
|
||||
~~~~~~~~~~~
|
||||
Recommended: With Secure Boot + encrypted boot pool + encrypted root dataset,
|
||||
a chain-of-trust can be established.
|
||||
|
||||
#. Sign boot loader
|
||||
|
||||
- Use boot loader signed by Microsoft
|
||||
|
||||
Using a boot loader signed with Microsoft's key is the
|
||||
simplest and most direct approach to booting with Secure Boot active;
|
||||
however, it's also the most limiting approach.
|
||||
|
||||
Use `shim-signed <https://aur.archlinux.org/packages/shim-signed/>`__\ :sup:`AUR`
|
||||
and sign ``grubx64.efi`` with machine owner key.
|
||||
See `here <https://www.rodsbooks.com/efi-bootloaders/secureboot.html#shim>`__.
|
||||
|
||||
- Customized Secure Boot
|
||||
|
||||
It's possible to replace Microsoft's keys with your own,
|
||||
which enables you to gain the benefits of Secure Boot
|
||||
without using either Shim. This can be a
|
||||
useful approach if you want the benefits of Secure Boot
|
||||
but don't want to trust Microsoft or any of the others
|
||||
who distribute binaries signed with Microsoft's keys.
|
||||
|
||||
See `here <https://www.rodsbooks.com/efi-bootloaders/controlling-sb.html>`__.
|
||||
|
||||
#. Set up a service to monitor and sign ``grubx64.efi``,
|
||||
as in `mirrored ESP <#mirror-efi-system-partition>`__.
|
||||
|
||||
Hibernation
|
||||
~~~~~~~~~~~
|
||||
|
||||
If a separate swap partition and
|
||||
`encrypted boot pool <#encrypt-boot-pool-with-LUKS>`__
|
||||
have been configured, hibernation,
|
||||
also known as suspend-to-disk, can be enabled.
|
||||
|
||||
#. Unload swap::
|
||||
|
||||
swapoff /dev/mapper/crypt-swap
|
||||
cryptsetup close crypt-swap
|
||||
|
||||
#. Check partition name and remove crypttab entry::
|
||||
|
||||
grep crypt-swap /etc/crypttab | awk '{ print $2 }'
|
||||
# ${DISK}-part4
|
||||
DISK=/dev/disk/by-id/nvme-foo # NO -part4
|
||||
sed -i 's|crypt-swap.*||' /etc/crypttab
|
||||
|
||||
Swap will be handled by ``encrypt`` initramfs hook.
|
||||
|
||||
#. Create LUKS container::
|
||||
|
||||
dd bs=32 count=1 if=/dev/urandom of=/etc/cryptkey.d/lukskey-crypt-swap
|
||||
cryptsetup luksFormat -q --type luks2 ${DISK}-part4 --key-file /etc/cryptkey.d/lukskey-crypt-swap
|
||||
cryptsetup luksOpen ${DISK}-part4 crypt-swap --key-file /etc/cryptkey.d/lukskey-crypt-swap --allow-discards
|
||||
mkswap /dev/mapper/crypt-swap
|
||||
swapon /dev/mapper/crypt-swap
|
||||
|
||||
#. Configure mkinitcpio::
|
||||
|
||||
sed -i 's|FILES=(|FILES=(/etc/cryptkey.d/lukskey-crypt-swap |' /etc/mkinitcpio.conf
|
||||
sed -i 's| zfs | encrypt resume zfs |' /etc/mkinitcpio.conf
|
||||
|
||||
#. Add kernel command line::
|
||||
|
||||
echo "GRUB_CMDLINE_LINUX=\"cryptdevice=PARTUUID=$(blkid -s PARTUUID -o value ${DISK}-part4):crypt-swap:allow-discards \
|
||||
cryptkey=rootfs:/etc/cryptkey.d/lukskey-crypt-swap \
|
||||
resume=/dev/mapper/crypt-swap\"" >> /etc/default/grub
|
||||
|
||||
#. Regenerate initramfs and GRUB menu::
|
||||
|
||||
mkinitcpio -P
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
|
||||
#. Test hibernation::
|
||||
|
||||
systemctl hibernate
|
||||
|
||||
Close all program before testing, just in case.
|
||||
|
||||
If hibernation works, your computer will shut down.
|
||||
Power it on. Computer should return to the previous state
|
||||
seamlessly.
|
||||
|
||||
Enter LUKS password in GRUB rescue
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Using LUKS encryption for boot pool,
|
||||
if the password entered is wrong, GRUB
|
||||
will drop to ``grub-rescue``::
|
||||
|
||||
Attempting to decrypt master key...
|
||||
Enter passphrase for hd0,gpt2 (c0987ea1a51049e9b3056622804de62a):
|
||||
error: access denied.
|
||||
error: no such cryptodisk found.
|
||||
Entering rescue mode...
|
||||
grub rescue>
|
||||
|
||||
Try entering the password again with::
|
||||
|
||||
grub rescue> cryptomount hd0,gpt2
|
||||
Attempting to decrypt master key...
|
||||
Enter passphrase for hd0,gpt2 (c0987ea1a51049e9b3056622804de62a):
|
||||
Slot 1 opened
|
||||
grub rescue> insmod normal
|
||||
grub rescue> normal
|
||||
|
||||
GRUB should then boot normally.
|
||||
|
||||
Change GRUB prefix when disk fails
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Using encryption, when
|
||||
disk failed, GRUB might fail to boot.
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Welcome to GRUB!
|
||||
|
||||
error: no such cryptodisk found.
|
||||
Attempting to decrypt master key...
|
||||
Enter passphrase for hd0,gpt2 (c0987ea1a51049e9b3056622804de62a):
|
||||
Slot 1 opened
|
||||
error: disk `cryptouuid/47ed1b7eb0014bc9a70aede3d8714faf' not found.
|
||||
Entering rescue mode...
|
||||
grub rescue>
|
||||
|
||||
Ensure ``Slot 1 opened`` message
|
||||
is shown. If ``error: access denied.`` is shown,
|
||||
the password entered is wrong.
|
||||
|
||||
#. Check prefix::
|
||||
|
||||
grub rescue > set
|
||||
# prefix=(cryptouuid/47ed1b7eb0014bc9a70aede3d8714faf)/sys/BOOT/default@/grub
|
||||
# root=cryptouuid/47ed1b7eb0014bc9a70aede3d8714faf
|
||||
|
||||
#. Replace ``cryptouuid/UUID`` with ``crypto0``::
|
||||
|
||||
grub rescue> prefix=(crypto0)/sys/BOOT/default@/grub
|
||||
grub rescue> root=crypto0
|
||||
|
||||
#. Boot GRUB::
|
||||
|
||||
grub rescue> insmod normal
|
||||
grub rescue> normal
|
||||
|
||||
GRUB should then boot normally. After entering system,
|
||||
promote one backup to ``/boot/efi`` and reinstall GRUB with
|
||||
``grub-install``.
|
||||
|
||||
Recovery
|
||||
--------
|
||||
|
||||
Load grub.cfg in GRUB command line
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Boot environment menu is stored in ``/boot/grub.cfg``.
|
||||
But the absolute path of ``grub.cfg`` will
|
||||
change when you enter another boot environment,
|
||||
from ``bpool/BOOT/default/@/boot/grub.cfg`` to
|
||||
``bpool/BOOT/bootenv1/@/boot/grub.cfg``.
|
||||
#. Press ``c`` at GRUB menu.
|
||||
|
||||
This absolute path is stored in the bootloader file:
|
||||
``grubx64.efi`` for EFI booting, or inside the first sector of the
|
||||
disk for BIOS booting.
|
||||
#. Check prefix::
|
||||
|
||||
GRUB will load the wrong ``grub.cfg`` if the bootloader
|
||||
file has not been updated upon entering another boot environment.
|
||||
Following are the steps to load the correct ``grub.cfg``,
|
||||
|
||||
#. Enter GRUB command line
|
||||
|
||||
No additional steps if you are already in GRUB rescue.
|
||||
Otherwise, press ``c`` at the GRUB menu.
|
||||
|
||||
#. List available partitions::
|
||||
|
||||
grub > ls
|
||||
(hd0) (hd0,gpt4) (hd0,gpt3) (hd0,gpt2) (hd0,gpt1) (hd1) (hd1,gpt5) ...
|
||||
|
||||
Boot pool is always ``(hdx,gpt2)``::
|
||||
|
||||
grub > ls (hd0, # press tab after comma
|
||||
Possible partitions are:
|
||||
|
||||
Partition hd0,gpt1: Filesystem type fat - Label 'EFI', UUID ...
|
||||
Partition hd0,gpt2: Filesystem type zfs - Label 'bpool' - Last modification time ...
|
||||
Partition hd0,gpt3: No known filesystem detected ...
|
||||
grub > set
|
||||
# ...
|
||||
# unencrypted bpool
|
||||
# prefix=(hd0,gpt2)/sys/BOOT/default@/grub
|
||||
# encrypted bpool
|
||||
# prefix=(cryptouuid/UUID)/sys/BOOT/default@/grub
|
||||
|
||||
#. List available boot environments::
|
||||
|
||||
grub > ls (hd0,gpt2) # press tab after bracket
|
||||
Possible files are:
|
||||
|
||||
@/ BOOT/
|
||||
|
||||
grub > ls (hd0,gpt2)/BOOT # press tab after 'T'
|
||||
# unencrypted bpool
|
||||
grub > ls (hd0,gpt2)/sys/BOOT # press tab after 'T'
|
||||
# encrypted bpool
|
||||
grub > ls (crypto0)/sys/BOOT # press tab after 'T'
|
||||
Possible files are:
|
||||
|
||||
@/ default/ pac-multm2/
|
||||
|
||||
#. Load grub.cfg
|
||||
#. Set new prefix::
|
||||
|
||||
To load from ``default`` boot environment, append
|
||||
``default/@/grub/grub.cfg`` to the last ``ls`` command.
|
||||
# unencrypted bpool
|
||||
grub > prefix=(hd0,gpt2)/sys/BOOT/pac-multm2@/grub
|
||||
# encrypted bpool
|
||||
grub > prefix=(crypto0)/sys/BOOT/pac-multm2@/grub
|
||||
|
||||
Then press ``home`` on the keyboard to move
|
||||
cursor to the start of the line.
|
||||
#. Load config from new prefix::
|
||||
|
||||
Change ``ls`` to ``configfile`` and press return::
|
||||
grub > normal
|
||||
|
||||
grub > configfile (hd0,gpt2)/BOOT/default/@/grub/grub.cfg
|
||||
New entries are shown below the old ones.
|
||||
|
||||
Rescue in Live Environment
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -1040,10 +1353,6 @@ Rescue in Live Environment
|
||||
INST_MNT=$(mktemp -d)
|
||||
INST_UUID=abc123
|
||||
|
||||
#. If using other keyfile::
|
||||
|
||||
KEYFILE=/path/to/keyfile
|
||||
|
||||
#. Import and unlock root and boot pool::
|
||||
|
||||
zpool import -N -R $INST_MNT rpool_$INST_UUID
|
||||
@@ -1051,20 +1360,20 @@ Rescue in Live Environment
|
||||
|
||||
If using password::
|
||||
|
||||
zfs load-key rpool_$INST_UUID
|
||||
zfs load-key rpool_$INST_UUID/sys
|
||||
|
||||
If using keyfile::
|
||||
|
||||
zfs load-key -L file://$KEYFILE rpool_$INST_UUID
|
||||
zfs load-key -L file:///path/to/keyfile rpool_$INST_UUID/sys
|
||||
|
||||
#. Find the current boot environment::
|
||||
|
||||
zfs list
|
||||
BE=default
|
||||
|
||||
#. Mount boot and root filesystem::
|
||||
#. Mount root filesystem::
|
||||
|
||||
zfs mount rpool_$INST_UUID/ROOT/$BE
|
||||
zfs mount rpool_$INST_UUID/sys/ROOT/$BE
|
||||
|
||||
#. chroot into the system::
|
||||
|
||||
|
||||
@@ -320,6 +320,7 @@ Create Root and Boot Pools
|
||||
|
||||
zpool create \
|
||||
-o ashift=12 \
|
||||
-o autotrim=on \
|
||||
-d -o feature@async_destroy=enabled \
|
||||
-o feature@bookmarks=enabled \
|
||||
-o feature@embedded_data=enabled \
|
||||
@@ -372,12 +373,12 @@ Create Root and Boot Pools
|
||||
“invalid dnode type” error. This feature does not matter for ``/boot``
|
||||
anyway.
|
||||
|
||||
#. Create root pool:
|
||||
|
||||
- Unencrypted::
|
||||
#. Create root pool::
|
||||
|
||||
zpool create \
|
||||
-o ashift=12 \
|
||||
-o autotrim=on \
|
||||
-R $INST_MNT \
|
||||
-O acltype=posixacl \
|
||||
-O canmount=off \
|
||||
-O compression=zstd \
|
||||
@@ -386,26 +387,6 @@ Create Root and Boot Pools
|
||||
-O relatime=on \
|
||||
-O xattr=sa \
|
||||
-O mountpoint=/ \
|
||||
-R $INST_MNT \
|
||||
rpool_$INST_UUID \
|
||||
${DISK}-part3
|
||||
|
||||
- Encrypted::
|
||||
|
||||
zpool create \
|
||||
-o ashift=12 \
|
||||
-O acltype=posixacl \
|
||||
-O canmount=off \
|
||||
-O compression=zstd \
|
||||
-O dnodesize=auto \
|
||||
-O normalization=formD \
|
||||
-O relatime=on \
|
||||
-O xattr=sa \
|
||||
-O mountpoint=/ \
|
||||
-R $INST_MNT \
|
||||
-O encryption=on \
|
||||
-O keylocation=prompt \
|
||||
-O keyformat=passphrase \
|
||||
rpool_$INST_UUID \
|
||||
${DISK}-part3
|
||||
|
||||
@@ -472,36 +453,81 @@ Create Root and Boot Pools
|
||||
|
||||
Create Datasets
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
#. Create system boot container::
|
||||
|
||||
zfs create \
|
||||
-o canmount=off \
|
||||
-o mountpoint=/boot \
|
||||
bpool_$INST_UUID/sys
|
||||
|
||||
#. Create system root container:
|
||||
|
||||
Dataset encryption is set at creation and can not be altered later,
|
||||
but encrypted dataset can be created inside an unencrypted parent dataset.
|
||||
|
||||
- Unencrypted::
|
||||
|
||||
zfs create \
|
||||
-o canmount=off \
|
||||
-o mountpoint=/ \
|
||||
rpool_$INST_UUID/sys
|
||||
|
||||
- Encrypted:
|
||||
|
||||
#. Choose a strong password.
|
||||
|
||||
Once the password is compromised,
|
||||
dataset and pool must be destroyed,
|
||||
disk wiped and system rebuilt from scratch to protect confidentiality.
|
||||
`Merely changing password is not enough <https://openzfs.github.io/openzfs-docs/man/8/zfs-change-key.8.html>`__.
|
||||
|
||||
Example: generate passphrase with `xkcdpass <https://github.com/redacted/XKCD-password-generator>`_::
|
||||
|
||||
pacman -S --noconfirm xkcdpass
|
||||
xkcdpass -Vn 10 -w /usr/lib/python*/site-packages/xkcdpass/static/eff-long
|
||||
|
||||
Password can be supplied with SSH at boot time,
|
||||
see `Supply password with SSH <#supply-password-with-ssh>`__.
|
||||
|
||||
#. Create dataset::
|
||||
|
||||
zfs create \
|
||||
-o canmount=off \
|
||||
-o mountpoint=/ \
|
||||
-o encryption=on \
|
||||
-o keylocation=prompt \
|
||||
-o keyformat=passphrase \
|
||||
rpool_$INST_UUID/sys
|
||||
|
||||
#. Create container datasets::
|
||||
|
||||
zfs create -o canmount=off -o mountpoint=none bpool_$INST_UUID/BOOT
|
||||
zfs create -o canmount=off -o mountpoint=none rpool_$INST_UUID/ROOT
|
||||
zfs create -o canmount=off -o mountpoint=none rpool_$INST_UUID/DATA
|
||||
zfs create -o canmount=off -o mountpoint=none bpool_$INST_UUID/sys/BOOT
|
||||
zfs create -o canmount=off -o mountpoint=none rpool_$INST_UUID/sys/ROOT
|
||||
zfs create -o canmount=off -o mountpoint=none rpool_$INST_UUID/sys/DATA
|
||||
|
||||
#. Create root and boot filesystem datasets::
|
||||
|
||||
zfs create -o mountpoint=legacy -o canmount=noauto bpool_$INST_UUID/BOOT/default
|
||||
zfs create -o mountpoint=/ -o canmount=noauto rpool_$INST_UUID/ROOT/default
|
||||
zfs create -o mountpoint=legacy -o canmount=noauto bpool_$INST_UUID/sys/BOOT/default
|
||||
zfs create -o mountpoint=/ -o canmount=noauto rpool_$INST_UUID/sys/ROOT/default
|
||||
|
||||
#. Mount root and boot filesystem datasets::
|
||||
|
||||
zfs mount rpool_$INST_UUID/ROOT/default
|
||||
zfs mount rpool_$INST_UUID/sys/ROOT/default
|
||||
mkdir $INST_MNT/boot
|
||||
mount -t zfs bpool_$INST_UUID/BOOT/default $INST_MNT/boot
|
||||
mount -t zfs bpool_$INST_UUID/sys/BOOT/default $INST_MNT/boot
|
||||
|
||||
#. Create datasets to separate user data from root filesystem::
|
||||
|
||||
zfs create -o mountpoint=/ -o canmount=off rpool_$INST_UUID/DATA/default
|
||||
zfs create -o mountpoint=/ -o canmount=off rpool_$INST_UUID/sys/DATA/default
|
||||
|
||||
for i in {usr,var,var/lib};
|
||||
do
|
||||
zfs create -o canmount=off rpool_$INST_UUID/DATA/default/$i
|
||||
zfs create -o canmount=off rpool_$INST_UUID/sys/DATA/default/$i
|
||||
done
|
||||
|
||||
for i in {home,root,srv,usr/local,var/log,var/spool,var/tmp};
|
||||
do
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/$i
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/$i
|
||||
done
|
||||
|
||||
chmod 750 $INST_MNT/root
|
||||
@@ -511,32 +537,32 @@ Create Datasets
|
||||
|
||||
If this system will have games installed::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/games
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/games
|
||||
|
||||
If you use /var/www on this system::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/www
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/www
|
||||
|
||||
If this system will use GNOME::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/lib/AccountsService
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/lib/AccountsService
|
||||
|
||||
If this system will use Docker (which manages its own datasets &
|
||||
snapshots)::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/lib/docker
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/lib/docker
|
||||
|
||||
If this system will use NFS (locking)::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/lib/nfs
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/lib/nfs
|
||||
|
||||
If this system will use Linux Containers::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/lib/lxc
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/lib/lxc
|
||||
|
||||
If this system will use libvirt::
|
||||
|
||||
zfs create -o canmount=on rpool_$INST_UUID/DATA/default/var/lib/libvirt
|
||||
zfs create -o canmount=on rpool_$INST_UUID/sys/DATA/default/var/lib/libvirt
|
||||
|
||||
Format and Mount EFI System Partition
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -550,7 +576,6 @@ Format and Mount EFI System Partition
|
||||
If you are using a multi-disk setup, this step will only install
|
||||
bootloader to the first disk. Other disks will be handled later.
|
||||
|
||||
|
||||
Package Installation
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -621,24 +646,19 @@ Package Installation
|
||||
|
||||
Kernel must be manually updated, see kernel update section in Getting Started.
|
||||
|
||||
#. If your computer has hardware that requires firmware to run::
|
||||
#. Install firmware::
|
||||
|
||||
basestrap $INST_MNT linux-firmware
|
||||
pacstrap $INST_MNT linux-firmware intel-ucode amd-ucode
|
||||
|
||||
#. If you boot your computer with EFI::
|
||||
|
||||
basestrap $INST_MNT dosfstools efibootmgr
|
||||
basestrap $INST_MNT efibootmgr
|
||||
|
||||
#. If a swap partition has been created::
|
||||
|
||||
basestrap $INST_MNT cryptsetup
|
||||
basestrap $INST_MNT cryptsetup-openrc
|
||||
|
||||
#. Microcode:
|
||||
|
||||
- ``pacstrap $INST_MNT amd-ucode``
|
||||
- ``pacstrap $INST_MNT intel-ucode``
|
||||
|
||||
#. For other optional packages,
|
||||
see `ArchWiki <https://wiki.archlinux.org/index.php/Installation_guide#Installation>`__.
|
||||
|
||||
@@ -647,7 +667,7 @@ System Configuration
|
||||
|
||||
#. Generate fstab::
|
||||
|
||||
echo bpool_$INST_UUID/BOOT/default /boot zfs rw,xattr,posixacl 0 0 >> $INST_MNT/etc/fstab
|
||||
echo bpool_$INST_UUID/sys/BOOT/default /boot zfs rw,xattr,posixacl 0 0 >> $INST_MNT/etc/fstab
|
||||
echo UUID=$(blkid -s UUID -o value ${DISK}-part1) /boot/efi vfat umask=0022,fmask=0022,dmask=0022 0 1 >> $INST_MNT/etc/fstab
|
||||
|
||||
``tmpfs`` for ``/tmp`` is recommended::
|
||||
@@ -822,6 +842,50 @@ Generate GRUB Boot Menu
|
||||
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
|
||||
Optional Configuration
|
||||
----------------------
|
||||
|
||||
Supply password with SSH
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Optional:
|
||||
|
||||
#. Install mkinitcpio tools::
|
||||
|
||||
pacman -S mkinitcpio-netconf mkinitcpio-dropbear openssh
|
||||
|
||||
#. Store authorized keys in ``/etc/dropbear/root_key``::
|
||||
|
||||
vi /etc/dropbear/root_key
|
||||
|
||||
Note that dropbear only supports RSA keys.
|
||||
|
||||
#. Edit mkinitcpio::
|
||||
|
||||
tee /etc/mkinitcpio.conf <<- 'EOF'
|
||||
HOOKS=(base udev autodetect modconf block keyboard netconf dropbear zfsencryptssh zfs filesystems)
|
||||
EOF
|
||||
|
||||
#. Add ``ip=`` to kernel command line::
|
||||
|
||||
# example DHCP
|
||||
echo 'GRUB_CMDLINE_LINUX="ip=::::::dhcp"' >> /etc/default/grub
|
||||
|
||||
Details for ``ip=`` can be found at
|
||||
`here <https://www.kernel.org/doc/html/latest/admin-guide/nfs/nfsroot.html#kernel-command-line>`__.
|
||||
|
||||
#. Generate host keys::
|
||||
|
||||
ssh-keygen -Am pem
|
||||
|
||||
#. Regenerate initramfs::
|
||||
|
||||
mkinitcpio -P
|
||||
|
||||
#. Update GRUB menu::
|
||||
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
|
||||
Finish Installation
|
||||
-------------------
|
||||
|
||||
@@ -831,8 +895,8 @@ Finish Installation
|
||||
|
||||
#. Take a snapshot of the clean installation for future use::
|
||||
|
||||
zfs snapshot -r rpool_$INST_UUID/ROOT/default@install
|
||||
zfs snapshot -r bpool_$INST_UUID/BOOT/default@install
|
||||
zfs snapshot -r rpool_$INST_UUID/sys/ROOT/default@install
|
||||
zfs snapshot -r bpool_$INST_UUID/sys/BOOT/default@install
|
||||
|
||||
#. Unmount EFI system partition::
|
||||
|
||||
@@ -893,72 +957,6 @@ This need to be manually applied when GRUB is updated.
|
||||
grub-install /dev/disk/by-id/$i
|
||||
done
|
||||
|
||||
Change encryption method
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
By default the root pool is encrypted with a key file,
|
||||
created at installation.
|
||||
|
||||
Password
|
||||
^^^^^^^^
|
||||
|
||||
After installation, encryption by password can be enabled with::
|
||||
|
||||
zfs change-key -l -o keylocation=prompt -o keyformat=passphrase rpool_$INST_UUID
|
||||
|
||||
See ``man 8 zfs-change-key``.
|
||||
If password is enabled, the system will require this password to boot.
|
||||
Password can be entered locally with keyboard or remotely with SSH.
|
||||
|
||||
Supply password with SSH
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#. Install mkinitcpio tools::
|
||||
|
||||
pacman -S mkinitcpio-netconf mkinitcpio-dropbear
|
||||
|
||||
#. Store authorized keys in ``/etc/dropbear/root_key``::
|
||||
|
||||
vi /etc/dropbear/root_key
|
||||
|
||||
Note that dropbear only supports RSA keys.
|
||||
|
||||
#. Edit mkinitcpio::
|
||||
|
||||
tee /etc/mkinitcpio.conf <<- 'EOF'
|
||||
HOOKS=(base udev autodetect modconf block keyboard netconf dropbear zfsencryptssh zfs filesystems)
|
||||
EOF
|
||||
|
||||
#. Add ``ip=`` to kernel command line::
|
||||
|
||||
# example DHCP
|
||||
echo 'GRUB_CMDLINE_LINUX="ip=::::::dhcp"' >> /etc/default/grub
|
||||
|
||||
Details for ``ip=`` can be found at
|
||||
`here <https://www.kernel.org/doc/html/latest/admin-guide/nfs/nfsroot.html#kernel-command-line>`__.
|
||||
|
||||
#. If using OpenSSH as SSH server, convert host keys to PEM format::
|
||||
|
||||
for i in {rsa,dsa,ecdsa,ed25519}; do
|
||||
ssh-keygen -p -m PEM -f /etc/ssh/ssh_host_${i}_key -qN ""
|
||||
done
|
||||
|
||||
#. Regenerate initramfs::
|
||||
|
||||
mkinitcpio -P
|
||||
|
||||
#. Update GRUB menu::
|
||||
|
||||
grub-mkconfig -o /boot/grub/grub.cfg
|
||||
|
||||
Key file
|
||||
^^^^^^^^
|
||||
|
||||
You can also set a new key file for root pool and
|
||||
store the key file on an external drive::
|
||||
|
||||
zfs change-key -l -o keylocation=file:///path/to/keyfile -o keyformat=raw rpool_$INST_UUID
|
||||
|
||||
Boot Environment Manager
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -984,62 +982,25 @@ Recovery
|
||||
Load grub.cfg in GRUB command line
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Boot environment menu is stored in ``/boot/grub.cfg``.
|
||||
But the absolute path of ``grub.cfg`` will
|
||||
change when you enter another boot environment,
|
||||
from ``bpool/BOOT/default/@/boot/grub.cfg`` to
|
||||
``bpool/BOOT/bootenv1/@/boot/grub.cfg``.
|
||||
#. Press ``c`` at GRUB menu.
|
||||
|
||||
This absolute path is stored in the bootloader file:
|
||||
``grubx64.efi`` for EFI booting, or inside the first sector of the
|
||||
disk for BIOS booting.
|
||||
#. List available disks::
|
||||
|
||||
GRUB will load the wrong ``grub.cfg`` if the bootloader
|
||||
file has not been updated upon entering another boot environment.
|
||||
Following are the steps to load the correct ``grub.cfg``,
|
||||
grub > ls (hd # press tab after 'd'
|
||||
Possible devices are:
|
||||
|
||||
#. Enter GRUB command line
|
||||
|
||||
No additional steps if you are already in GRUB rescue.
|
||||
Otherwise, press ``c`` at the GRUB menu.
|
||||
|
||||
#. List available partitions::
|
||||
|
||||
grub > ls
|
||||
(hd0) (hd0,gpt4) (hd0,gpt3) (hd0,gpt2) (hd0,gpt1) (hd1) (hd1,gpt5) ...
|
||||
|
||||
Boot pool is always ``(hdx,gpt2)``::
|
||||
|
||||
grub > ls (hd0, # press tab after comma
|
||||
Possible partitions are:
|
||||
|
||||
Partition hd0,gpt1: Filesystem type fat - Label 'EFI', UUID ...
|
||||
Partition hd0,gpt2: Filesystem type zfs - Label 'bpool' - Last modification time ...
|
||||
Partition hd0,gpt3: No known filesystem detected ...
|
||||
hd0 hd1
|
||||
|
||||
#. List available boot environments::
|
||||
|
||||
grub > ls (hd0,gpt2) # press tab after bracket
|
||||
Possible files are:
|
||||
|
||||
@/ BOOT/
|
||||
|
||||
grub > ls (hd0,gpt2)/BOOT # press tab after 'T'
|
||||
grub > ls (hd0,gpt2)/sys/BOOT # press tab after 'T'
|
||||
Possible files are:
|
||||
|
||||
@/ default/ pac-multm2/
|
||||
|
||||
#. Load grub.cfg
|
||||
#. Load grub.cfg::
|
||||
|
||||
To load from ``default`` boot environment, append
|
||||
``default/@/grub/grub.cfg`` to the last ``ls`` command.
|
||||
|
||||
Then press ``home`` on the keyboard to move
|
||||
cursor to the start of the line.
|
||||
|
||||
Change ``ls`` to ``configfile`` and press return::
|
||||
|
||||
grub > configfile (hd0,gpt2)/BOOT/default/@/grub/grub.cfg
|
||||
grub > configfile (hd0,gpt2)/sys/BOOT/default@/grub/grub.cfg
|
||||
|
||||
Rescue in Live Environment
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -1055,10 +1016,6 @@ Rescue in Live Environment
|
||||
INST_MNT=$(mktemp -d)
|
||||
INST_UUID=abc123
|
||||
|
||||
#. If using other keyfile::
|
||||
|
||||
KEYFILE=/path/to/keyfile
|
||||
|
||||
#. Import and unlock root and boot pool::
|
||||
|
||||
zpool import -N -R $INST_MNT rpool_$INST_UUID
|
||||
@@ -1068,18 +1025,14 @@ Rescue in Live Environment
|
||||
|
||||
zfs load-key rpool_$INST_UUID
|
||||
|
||||
If using keyfile::
|
||||
|
||||
zfs load-key -L file://$KEYFILE rpool_$INST_UUID
|
||||
|
||||
#. Find the current boot environment::
|
||||
|
||||
zfs list
|
||||
BE=default
|
||||
|
||||
#. Mount boot and root filesystem::
|
||||
#. Mount root filesystem::
|
||||
|
||||
zfs mount rpool_$INST_UUID/ROOT/$BE
|
||||
zfs mount rpool_$INST_UUID/sys/ROOT/$BE
|
||||
|
||||
#. chroot into the system::
|
||||
|
||||
|
||||
@@ -78,10 +78,15 @@ Check compatible kernel version::
|
||||
|
||||
INST_LINVER=$(pacman -Si zfs-${INST_LINVAR} | grep 'Depends On' | sed "s|.*${INST_LINVAR}=||" | awk '{ print $1 }')
|
||||
|
||||
Install compatible kernel::
|
||||
Install kernel. Download from archive if kernel is not available::
|
||||
|
||||
pacman -U \
|
||||
https://archive.archlinux.org/packages/l/${INST_LINVAR}/${INST_LINVAR}-${INST_LINVER}-x86_64.pkg.tar.zst
|
||||
if [ ${INST_LINVER} == \
|
||||
$(pacman -Si ${INST_LINVAR} | grep Version | awk '{ print $3 }') ]; then
|
||||
pacstrap $INST_MNT ${INST_LINVAR}
|
||||
else
|
||||
pacstrap -U $INST_MNT \
|
||||
https://archive.archlinux.org/packages/l/${INST_LINVAR}/${INST_LINVAR}-${INST_LINVER}-x86_64.pkg.tar.zst
|
||||
fi
|
||||
|
||||
Install archzfs::
|
||||
|
||||
|
||||
Reference in New Issue
Block a user