Notes for encryption; direct link for Live ISO; striped vdev topology;
Signed-off-by: Maurice Zhou <ja@apvc.uk>
This commit is contained in:
committed by
Richard Laager
parent
ff20f0b5d7
commit
99b06be59a
@@ -1,4 +1,4 @@
|
|||||||
Root on ZFS
|
Arch Linux Root on ZFS
|
||||||
======================
|
======================
|
||||||
`Start here <Root%20on%20ZFS/0-overview.html>`__.
|
`Start here <Root%20on%20ZFS/0-overview.html>`__.
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
Overview
|
Overview
|
||||||
======================
|
======================
|
||||||
Before following this guide, you might want to read `index page <../index.html>`__.
|
|
||||||
|
|
||||||
This document describes how to install Arch Linux with ZFS as root
|
This document describes how to install Arch Linux with ZFS as root
|
||||||
file system.
|
file system.
|
||||||
|
|
||||||
@@ -76,17 +74,49 @@ Dataset layout
|
|||||||
|
|
||||||
Encryption
|
Encryption
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
User should be aware that, ZFS native encryption, used on root pool,
|
|
||||||
does not encrypt some metadata of the datasets.
|
|
||||||
|
|
||||||
ZFS native encryption also does not change master key when ``zfs change-key`` is invoked,
|
- Swap
|
||||||
it means that you must wipe the disk when password is compromised to protect confidentiality.
|
|
||||||
|
|
||||||
See `zfs-load-key.8 <https://openzfs.github.io/openzfs-docs/man/8/zfs-load-key.8.html>`__
|
Swap is always encrypted. By default, swap is encrypted
|
||||||
and `zfs-change-key.8 <https://openzfs.github.io/openzfs-docs/man/8/zfs-change-key.8.html>`__ for more information.
|
with plain dm-crypt with key generated from ``/dev/urandom``
|
||||||
|
at every boot. Swap content does not persist between reboots.
|
||||||
|
|
||||||
Root dataset encryption is enabled at creation and can not be disabled later. If root dataset is protected
|
LUKS2-encrypted persistent swap can be
|
||||||
with a passphrase and boot pool is not encrypted, then password can be supplied via SSH.
|
enabled after encrypting both boot pool and root pool, see below.
|
||||||
|
|
||||||
Boot pool can be encrypted with LUKS 1, this requires the password to be interactively entered at boot
|
With persistent swap, hibernation (suspend-to-disk) can be enabled.
|
||||||
in GRUB.
|
|
||||||
|
- Root pool
|
||||||
|
|
||||||
|
ZFS native encryption can be optionally enabled for ``rpool/sys``
|
||||||
|
and child datasets.
|
||||||
|
|
||||||
|
User should be aware that, ZFS native encryption does not
|
||||||
|
encrypt some metadata of the datasets.
|
||||||
|
ZFS native encryption also does not change master key when ``zfs change-key`` is invoked.
|
||||||
|
Therefore, you should wipe the disk when password is compromised to protect confidentiality.
|
||||||
|
See `zfs-load-key.8 <https://openzfs.github.io/openzfs-docs/man/8/zfs-load-key.8.html>`__
|
||||||
|
and `zfs-change-key.8 <https://openzfs.github.io/openzfs-docs/man/8/zfs-change-key.8.html>`__
|
||||||
|
for more information regarding ZFS native encryption.
|
||||||
|
|
||||||
|
Encryption is enabled at dataset creation and can not be disabled later.
|
||||||
|
Password can be supplied via SSH.
|
||||||
|
|
||||||
|
- Boot pool
|
||||||
|
|
||||||
|
After encrypting root pool, boot pool can also be encrypted with LUKS1.
|
||||||
|
This protects initrd from attacks and also protects key material in initrd.
|
||||||
|
|
||||||
|
Password must be interactively entered at boot in GRUB. This disables
|
||||||
|
password with SSH.
|
||||||
|
|
||||||
|
- Bootloader
|
||||||
|
|
||||||
|
Bootloader can not be encrypted.
|
||||||
|
|
||||||
|
However, with Secure Boot, bootloader
|
||||||
|
can be verified by motherboard firmware to be untempered,
|
||||||
|
which should be sufficient for most purposes.
|
||||||
|
|
||||||
|
As enabling Secure Boot is device specific, this is not
|
||||||
|
covered in detail.
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ Preparation
|
|||||||
.. contents:: Table of Contents
|
.. contents:: Table of Contents
|
||||||
:local:
|
:local:
|
||||||
|
|
||||||
#. Download 2021.05.01 build and signature.
|
#. Download
|
||||||
|
`2021.05.01 <https://mirrors.ocf.berkeley.edu/archlinux/iso/2021.05.01/archlinux-2021.05.01-x86_64.iso>`__
|
||||||
|
Live ISO and `signature <https://archlinux.org/iso/2021.05.01/archlinux-2021.05.01-x86_64.iso.sig>`__.
|
||||||
|
|
||||||
#. Follow `installation guide on Arch wiki <https://wiki.archlinux.org/title/Installation_guide>`__
|
#. Follow `installation guide on Arch wiki <https://wiki.archlinux.org/title/Installation_guide>`__
|
||||||
up to **Update the system clock**.
|
up to **Update the system clock**.
|
||||||
@@ -29,10 +31,10 @@ Preparation
|
|||||||
LIVE_ZFS_PKG="zfs-linux-2.0.4_5.11.16.arch1.1-1-x86_64.pkg.tar.zst"
|
LIVE_ZFS_PKG="zfs-linux-2.0.4_5.11.16.arch1.1-1-x86_64.pkg.tar.zst"
|
||||||
LIVE_ZFS_UTILS="zfs-utils-2.0.4-1-x86_64.pkg.tar.zst"
|
LIVE_ZFS_UTILS="zfs-utils-2.0.4-1-x86_64.pkg.tar.zst"
|
||||||
LIVE_ZFS_MIRROR="https://mirror.sum7.eu/archlinux/archzfs"
|
LIVE_ZFS_MIRROR="https://mirror.sum7.eu/archlinux/archzfs"
|
||||||
pacman -U --noconfirm ${LIVE_ZFS_MIRROR}/archzfs/x86_64/${LIVE_ZFS_UTILS} \
|
pacman -U --noconfirm ${LIVE_ZFS_MIRROR}/archzfs/x86_64/${LIVE_ZFS_UTILS} || \
|
||||||
|| pacman -U --noconfirm ${LIVE_ZFS_MIRROR}/archive_archzfs/${LIVE_ZFS_UTILS}
|
pacman -U --noconfirm ${LIVE_ZFS_MIRROR}/archive_archzfs/${LIVE_ZFS_UTILS}
|
||||||
pacman -U --noconfirm ${LIVE_ZFS_MIRROR}/archzfs/x86_64/${LIVE_ZFS_PKG} \
|
pacman -U --noconfirm ${LIVE_ZFS_MIRROR}/archzfs/x86_64/${LIVE_ZFS_PKG} || \
|
||||||
|| pacman -U --noconfirm ${LIVE_ZFS_MIRROR}/archive_archzfs/${LIVE_ZFS_PKG}
|
pacman -U --noconfirm ${LIVE_ZFS_MIRROR}/archive_archzfs/${LIVE_ZFS_PKG}
|
||||||
modprobe zfs
|
modprobe zfs
|
||||||
|
|
||||||
#. Timezone
|
#. Timezone
|
||||||
@@ -105,9 +107,9 @@ Preparation
|
|||||||
hook treats ``:`` as argument separator without a means to
|
hook treats ``:`` as argument separator without a means to
|
||||||
escape this character.
|
escape this character.
|
||||||
|
|
||||||
#. Set vdev specification, possible values are:
|
#. Set vdev topology, possible values are:
|
||||||
|
|
||||||
- (not set, single disk)
|
- (not set, single disk or striped; no redundancy)
|
||||||
- mirror
|
- mirror
|
||||||
- raidz1
|
- raidz1
|
||||||
- raidz2
|
- raidz2
|
||||||
|
|||||||
@@ -143,6 +143,8 @@ System Installation
|
|||||||
|
|
||||||
#. This section implements dataset layout as described in `overview <0-overview.html>`__.
|
#. This section implements dataset layout as described in `overview <0-overview.html>`__.
|
||||||
|
|
||||||
|
Create root system container:
|
||||||
|
|
||||||
- Unencrypted::
|
- Unencrypted::
|
||||||
|
|
||||||
zfs create -o canmount=off -o mountpoint=none rpool_$INST_UUID/$INST_ID
|
zfs create -o canmount=off -o mountpoint=none rpool_$INST_UUID/$INST_ID
|
||||||
@@ -154,7 +156,7 @@ System Installation
|
|||||||
|
|
||||||
zfs create -o canmount=off -o mountpoint=none -o encryption=on -o keylocation=prompt -o keyformat=passphrase rpool_$INST_UUID/$INST_ID
|
zfs create -o canmount=off -o mountpoint=none -o encryption=on -o keylocation=prompt -o keyformat=passphrase rpool_$INST_UUID/$INST_ID
|
||||||
|
|
||||||
::
|
Create other system datasets::
|
||||||
|
|
||||||
zfs create -o canmount=off -o mountpoint=none bpool_$INST_UUID/$INST_ID
|
zfs create -o canmount=off -o mountpoint=none bpool_$INST_UUID/$INST_ID
|
||||||
zfs create -o canmount=off -o mountpoint=none bpool_$INST_UUID/$INST_ID/BOOT
|
zfs create -o canmount=off -o mountpoint=none bpool_$INST_UUID/$INST_ID/BOOT
|
||||||
|
|||||||
@@ -32,14 +32,6 @@ System Configuration
|
|||||||
done
|
done
|
||||||
echo UUID=$(blkid -s UUID -o value ${INST_PRIMARY_DISK}-part1) /boot/efi vfat \
|
echo UUID=$(blkid -s UUID -o value ${INST_PRIMARY_DISK}-part1) /boot/efi vfat \
|
||||||
x-systemd.idle-timeout=1min,x-systemd.automount,noauto,umask=0022,fmask=0022,dmask=0022 0 1 >> /mnt/etc/fstab
|
x-systemd.idle-timeout=1min,x-systemd.automount,noauto,umask=0022,fmask=0022,dmask=0022 0 1 >> /mnt/etc/fstab
|
||||||
|
|
||||||
By default systemd will halt boot process if EFI system partition
|
|
||||||
fails to mount at boot. The above mount options
|
|
||||||
tells systemd to only mount partitions on demand.
|
|
||||||
Thus if a disk fails, system will still boot normally.
|
|
||||||
|
|
||||||
Add encrypted swap. Skip if swap was not created::
|
|
||||||
|
|
||||||
if [ "${INST_PARTSIZE_SWAP}" != "" ]; then
|
if [ "${INST_PARTSIZE_SWAP}" != "" ]; then
|
||||||
for i in ${DISK[@]}; do
|
for i in ${DISK[@]}; do
|
||||||
echo ${i##*/}-part4-swap ${i}-part4 /dev/urandom swap,cipher=aes-cbc-essiv:sha256,size=256,discard >> /mnt/etc/crypttab
|
echo ${i##*/}-part4-swap ${i}-part4 /dev/urandom swap,cipher=aes-cbc-essiv:sha256,size=256,discard >> /mnt/etc/crypttab
|
||||||
@@ -47,10 +39,14 @@ System Configuration
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
By default, systemd will halt boot process if any entry in ``/etc/fstab`` fails
|
||||||
|
to mount. This is unnecessary for mirrored EFI boot partitions.
|
||||||
|
With the above mount options, systemd will skip mounting them at boot,
|
||||||
|
only mount them on demand when accessed.
|
||||||
|
|
||||||
#. Configure mkinitcpio::
|
#. Configure mkinitcpio::
|
||||||
|
|
||||||
mv /mnt/etc/mkinitcpio.conf /mnt/etc/mkinitcpio.conf.original
|
mv /mnt/etc/mkinitcpio.conf /mnt/etc/mkinitcpio.conf.original
|
||||||
|
|
||||||
tee /mnt/etc/mkinitcpio.conf <<EOF
|
tee /mnt/etc/mkinitcpio.conf <<EOF
|
||||||
HOOKS=(base udev autodetect modconf block keyboard zfs filesystems)
|
HOOKS=(base udev autodetect modconf block keyboard zfs filesystems)
|
||||||
EOF
|
EOF
|
||||||
@@ -102,7 +98,6 @@ System Configuration
|
|||||||
|
|
||||||
systemctl enable zfs-import-scan.service zfs-import.target zfs-mount zfs-zed zfs.target --root=/mnt
|
systemctl enable zfs-import-scan.service zfs-import.target zfs-mount zfs-zed zfs.target --root=/mnt
|
||||||
|
|
||||||
|
|
||||||
#. Chroot::
|
#. Chroot::
|
||||||
|
|
||||||
echo "INST_PRIMARY_DISK=$INST_PRIMARY_DISK
|
echo "INST_PRIMARY_DISK=$INST_PRIMARY_DISK
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ Supply password with SSH
|
|||||||
|
|
||||||
Encrypt boot pool
|
Encrypt boot pool
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
Note: This will disable password with SSH.
|
||||||
|
|
||||||
#. LUKS password::
|
#. LUKS password::
|
||||||
|
|
||||||
@@ -71,8 +72,8 @@ Encrypt boot pool
|
|||||||
protected by this password, the previous warning
|
protected by this password, the previous warning
|
||||||
about password strength still apply.
|
about password strength still apply.
|
||||||
|
|
||||||
Double-check password here. You will need a complete reinstallation if
|
Double-check password here. Complete reinstallation is
|
||||||
it is wrong.
|
needed if entered wrong.
|
||||||
|
|
||||||
#. Create encryption keys::
|
#. Create encryption keys::
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ Install GRUB
|
|||||||
|
|
||||||
mkinitcpio -P
|
mkinitcpio -P
|
||||||
|
|
||||||
#. When not sure, install both legacy boot
|
#. When in doubt, install both legacy boot
|
||||||
and EFI.
|
and EFI.
|
||||||
|
|
||||||
#. If using legacy booting, install GRUB to every disk::
|
#. If using legacy booting, install GRUB to every disk::
|
||||||
@@ -114,6 +114,13 @@ This is optional.
|
|||||||
mv PreLoader.efi /boot/efi/EFI/BOOT/BOOTX64.EFI
|
mv PreLoader.efi /boot/efi/EFI/BOOT/BOOTX64.EFI
|
||||||
mv HashTool.efi /boot/efi/EFI/BOOT/
|
mv HashTool.efi /boot/efi/EFI/BOOT/
|
||||||
|
|
||||||
|
# mirror ESP content
|
||||||
|
ESP_MIRROR=$(mktemp -d)
|
||||||
|
cp -r /boot/efi/EFI $ESP_MIRROR
|
||||||
|
for i in /boot/efis/*; do
|
||||||
|
cp -r $ESP_MIRROR/EFI $i
|
||||||
|
done
|
||||||
|
|
||||||
for i in ${DISK[@]}; do
|
for i in ${DISK[@]}; do
|
||||||
efibootmgr -cgp 1 -l "\EFI\BOOT\BOOTX64.EFI" \
|
efibootmgr -cgp 1 -l "\EFI\BOOT\BOOTX64.EFI" \
|
||||||
-L "arch-PreLoader-${i##*/}" -d ${i}
|
-L "arch-PreLoader-${i##*/}" -d ${i}
|
||||||
|
|||||||
@@ -159,10 +159,10 @@ GRUB with the following method:
|
|||||||
#. Make the change to ``prefix`` and ``root``
|
#. Make the change to ``prefix`` and ``root``
|
||||||
permanent by `reinstalling GRUB <#grub-installation>`__.
|
permanent by `reinstalling GRUB <#grub-installation>`__.
|
||||||
|
|
||||||
Recovery
|
Access system in chroot
|
||||||
--------
|
-----------------------
|
||||||
|
|
||||||
#. Go through `preparations <#preparations>`__.
|
#. Go through `preparation <1-preparation.html>`__.
|
||||||
|
|
||||||
#. Import and unlock root and boot pool::
|
#. Import and unlock root and boot pool::
|
||||||
|
|
||||||
@@ -193,3 +193,34 @@ Recovery
|
|||||||
mount -a
|
mount -a
|
||||||
|
|
||||||
#. Finish rescue. See `finish installation <#finish-installation>`__.
|
#. Finish rescue. See `finish installation <#finish-installation>`__.
|
||||||
|
|
||||||
|
Backup and migrate existing installation
|
||||||
|
----------------------------------------
|
||||||
|
With the help of `zfs send
|
||||||
|
<https://openzfs.github.io/openzfs-docs/man/8/zfs-send.8.html>`__
|
||||||
|
it is relatively easy to perform a system backup and migration.
|
||||||
|
|
||||||
|
#. Create a snapshot of root file system::
|
||||||
|
|
||||||
|
zfs snapshot -r rpool/arch@backup
|
||||||
|
zfs snapshot -r bpool/arch@backup
|
||||||
|
|
||||||
|
#. Save snapshot to a file or pipe to SSH::
|
||||||
|
|
||||||
|
zfs send --options rpool/arch@backup > /backup/arch-rpool
|
||||||
|
zfs send --options bpool/arch@backup > /backup/arch-bpool
|
||||||
|
|
||||||
|
#. Re-create partitions and root/boot
|
||||||
|
pool on target system.
|
||||||
|
|
||||||
|
#. Restore backup::
|
||||||
|
|
||||||
|
zfs recv rpool_new/arch < /backup/arch-rpool
|
||||||
|
zfs recv bpool_new/arch < /backup/arch-bpool
|
||||||
|
|
||||||
|
#. Chroot and reinstall bootloader.
|
||||||
|
|
||||||
|
#. Update pool name in ``/etc/fstab``, ``/boot/grub/grub.cfg``
|
||||||
|
and ``/etc/zfs/zfs-list.cache/*``.
|
||||||
|
|
||||||
|
#. Update device name, etc, in ``/etc/fstab`` and ``/etc/crypttab``.
|
||||||
|
|||||||
Reference in New Issue
Block a user