351 lines
12 KiB
ReStructuredText
351 lines
12 KiB
ReStructuredText
Debian Bullseye UEFI Installation
|
|
=================================
|
|
|
|
.. contents:: Contents
|
|
:depth: 2
|
|
:local:
|
|
:backlinks: none
|
|
|
|
Preparation
|
|
-----------
|
|
|
|
Download the `Debian Bullseye (11) Live image <https://www.debian.org/CD/live/>`_ and write it to a USB drive. Grab the
|
|
most recent image.
|
|
|
|
Disable Secure Boot on your system. Because ZFS modules are built using the ``zfs-dkms`` package, the modules will not
|
|
be signed and will be unusable in a Secure Boot setup. The modules may be signed for use with Secure Boot, but that is
|
|
beyond the scope of this document.
|
|
|
|
Blindly copying and pasting this commands most likely will not work. take some time to understand ZFS and boot proccess.
|
|
First read the whole guide at least once and then start the installation.
|
|
|
|
Early Setup
|
|
-----------
|
|
|
|
Boot the USB/CD/DVD/... drive containing the live image.
|
|
|
|
Log in as root. most of the following commands need root access::
|
|
|
|
sudo su --login
|
|
|
|
Configure APT and update the package database::
|
|
|
|
cat <<EOF > /etc/apt/sources.list
|
|
deb http://deb.debian.org/debian bullseye main contrib
|
|
deb-src http://deb.debian.org/debian bullseye main contrib
|
|
EOF
|
|
apt update
|
|
|
|
You may see faster downloads replacing ``deb.debian.org`` with a local mirror. If you want to use HTTPS transport, make
|
|
sure that the ``ca-certificates`` and ``apt-transport-https`` packages are installed and your mirror has a valid
|
|
certificate; otherwise, apt will refuse to use the mirror.
|
|
|
|
Install fundamental packages in live system::
|
|
|
|
apt install debootstrap gdisk parted dkms linux-headers-$(uname -r)
|
|
apt install zfsutils-linux
|
|
|
|
Disk Preparation
|
|
----------------
|
|
|
|
For disk operations, it is assumed that the environment variable ``TARGET_DISK`` points to a single disk on which you
|
|
wish to create a ZFS pool.
|
|
|
|
Create partition table
|
|
~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
.. caution::
|
|
|
|
This action will delete all data on your drive.
|
|
|
|
This example creates two partitions: one EFI system partition and another on which the ZFS pool will be stored. Adjust
|
|
this to suit your needs. You may find it easier to use ``cgdisk`` insteade of ``sgdisk`` to partition your drive.
|
|
|
|
.. code-block::
|
|
|
|
sgdisk --zap-all $TARGET_DISK
|
|
sgdisk -n1:1m:+512m -t1:ef00 $TARGET_DISK
|
|
sgdisk -n2:0:0 -t2:bf00 $TARGET_DISK
|
|
|
|
Running ``lsblk`` will confirm that the kernel has recognized the new partitions. If the output does not contain created
|
|
partitions, run ``partprobe`` to inform the kernel of partition table changes. If that didnt work, reboot.
|
|
|
|
Format EFI system partition (ESP)
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
For this step, it is assumed that the environment variable ``TARGET_ESP`` points to the first partition created in the
|
|
preceding step.
|
|
|
|
.. code-block::
|
|
|
|
mkfs -t vfat -F 32 -s 1 -n EFI $TARGET_ESP
|
|
|
|
The ``-s 1`` flag is only necessary for drives which present 4 KiB logical sectors ("4Kn" drives) to meet the minimum
|
|
cluster size (given the partition size of 512 MiB) for FAT32. It also works fine on drives which present 512 B sectors.
|
|
|
|
Create a ZFS pool
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
If you want encryption, store a pool passphrase in a key file::
|
|
|
|
echo '<your-passphrase-here>' > /etc/zfs/zroot.key
|
|
chmod 000 /etc/zfs/zroot.key
|
|
|
|
Create the pool. When specifying devices for ZFS vdevs, it is generally advisable to use persistent disk names created
|
|
by ``udev`` in one of the ``/dev/disk`` subdirectories. Both ``by-id`` and (on GPT disks) ``by-partuuid`` subdirectories
|
|
are good choices as ZFS vdev targets. Using ordinary block device nodes may cause import problems if your disk
|
|
configuration eventually changes. For this example, it is assumed that the environment variable ``TARGET_VDEV`` contains
|
|
the path to the second partition created above.
|
|
|
|
.. code-block::
|
|
|
|
zpool create -f \
|
|
-o ashift=12 \
|
|
-o autotrim=on \
|
|
-O encryption=aes-256-gcm \
|
|
-O keylocation=file:///etc/zfs/zroot.key \
|
|
-O keyformat=passphrase \
|
|
-O acltype=posixacl \
|
|
-O compression=lz4 \
|
|
-O normalization=formD \
|
|
-O relatime=on \
|
|
-O xattr=sa \
|
|
-O mountpoint=none \
|
|
-R /mnt \
|
|
zroot $TARGET_VDEV
|
|
|
|
If you are not using encryption, omit the following options:
|
|
|
|
.. code-block::
|
|
|
|
-O encryption=aes-256-gcm
|
|
-O keylocation=file:///etc/zfs/zroot.key
|
|
-O keyformat=passphrase
|
|
|
|
Create filesystems to hold the Debian boot environment and home directories::
|
|
|
|
zfs create zroot/ROOT
|
|
zfs create -o canmount=noauto -o mountpoint=/ zroot/ROOT/debian
|
|
zfs mount zroot/ROOT/debian
|
|
zfs create -o mountpoint=/home zroot/home
|
|
|
|
.. note::
|
|
|
|
It is important to set ``canmount=noauto`` on any filesystem with ``mountpoint=/`` to prevent the ZFS automount
|
|
process from attempting to mount more than one boot environment at the root of the filesystem. It is also possible to
|
|
set ``mountpoint=legacy`` on boot environments, but filesystems with ``mountpoint=legacy`` will not be examined by
|
|
ZFSBootMenu unless the property ``org.zfsbootmenu:active=on`` is also set.
|
|
|
|
Set the default boot environment to tell ZFSBootMenu what it should prefer to boot::
|
|
|
|
zpool set bootfs=zroot/ROOT/debian zroot
|
|
|
|
Re-import the pool with a temporary root to populate the filesystems::
|
|
|
|
zpool export zroot
|
|
zpool import -N -R /mnt zroot
|
|
zfs load-key zroot # only if encrypted
|
|
zfs mount zroot/ROOT/debian
|
|
zfs mount -a
|
|
|
|
Mount EFI system partition where it will reside in the target system::
|
|
|
|
mkdir -p /mnt/boot/efi
|
|
mount $TARGET_ESP /mnt/boot/efi
|
|
|
|
Install the Debian base::
|
|
|
|
debootstrap bullseye /mnt
|
|
|
|
If you want, you can specify a mirror by appending its URL to the above command.
|
|
|
|
Copy the pool key (for an encrypted pool) and resolv.conf into the new installation::
|
|
|
|
cp /etc/resolv.conf /mnt/etc/
|
|
mkdir -p /mnt/etc/zfs
|
|
cp /etc/zfs/zroot.key /mnt/etc/zfs/
|
|
|
|
Set a hostname and add it to the hosts file::
|
|
|
|
echo 'YOURHOSTNAME' > /mnt/etc/hostname
|
|
echo -e '127.0.1.1\tYOURHOSTNAME' >> /mnt/etc/hosts
|
|
|
|
Bind virtual filesystems from the live environment into the target hierarchy, then chroot into the target system::
|
|
|
|
for i in dev sys proc run; do
|
|
mount --rbind /$i /mnt/$i
|
|
mount --make-rslave /mnt/$i
|
|
done
|
|
chroot /mnt env TARGET_ESP="$TARGET_ESP" TARGET_VDEV="$TARGET_VDEV" bash --login
|
|
|
|
Customize the installation
|
|
--------------------------
|
|
|
|
At this point, the installation process looks like any other Linux setup procedure. Major steps are highlighted for
|
|
convenience, but the process may be adapted as you see fit.
|
|
|
|
Basic configuration
|
|
~~~~~~~~~~~~~~~~~~~
|
|
|
|
Set a root password for installed system. you can disable login as root later, when you have created another user with
|
|
``sudo`` privilege.
|
|
|
|
.. code-block::
|
|
|
|
passwd
|
|
|
|
Configure ``apt``. Use other mirrors if you prefer.
|
|
|
|
.. code-block::
|
|
|
|
cat <<EOF > /etc/apt/sources.list
|
|
deb http://deb.debian.org/debian bullseye main contrib
|
|
deb-src http://deb.debian.org/debian bullseye main contrib
|
|
|
|
deb http://deb.debian.org/debian-security/ bullseye-security main contrib
|
|
deb-src http://deb.debian.org/debian-security/ bullseye-security main contrib
|
|
|
|
deb http://deb.debian.org/debian bullseye-updates main contrib
|
|
deb-src http://deb.debian.org/debian bullseye-updates main contrib
|
|
|
|
deb http://deb.debian.org/debian bullseye-backports main contrib
|
|
deb-src http://deb.debian.org/debian bullseye-backports main contrib
|
|
EOF
|
|
|
|
Do not use HTTPS as a transport protocol yet. The packages ``ca-certificates`` and ``apt-transport-https`` are not
|
|
installed. After installing and configuring the ``locales`` package, it will be possible to install ``ca-certificates``
|
|
and ``apt-transport-https`` and switch to HTTPS transports.
|
|
|
|
Update the repository cache and install upgrades if any are available::
|
|
|
|
apt update
|
|
apt full-upgrade
|
|
|
|
Install essential packages and ``bash-completion`` to make typing commands easier::
|
|
|
|
apt install locales console-setup bash-completion
|
|
. /usr/share/bash-completion/bash_completion
|
|
|
|
Configure packages to customize local and console properties::
|
|
|
|
dpkg-reconfigure locales tzdata keyboard-configuration console-setup
|
|
|
|
.. note::
|
|
|
|
You should always enable the `en_US.UTF-8` locale because some programs require it.
|
|
|
|
Install packages necessary to support ZFS::
|
|
|
|
apt install linux-headers-amd64 linux-image-amd64 refind git zfs-initramfs
|
|
echo "REMAKE_INITRD=yes" > /etc/dkms/zfs.conf
|
|
|
|
When rEFInd offers to make edits to your ESP partition, check to make sure that it mounted the correct partition::
|
|
|
|
mount | grep /boot
|
|
|
|
On systems with multiple bootable drives, rEFInd may mount more than one ESP partition when it makes changes. You may
|
|
have to manually copy the ``/boot/efi/EFI/refind`` directory to a temporary directory, unmount the unwanted ESP
|
|
partitions so only the ``$TARGET_ESP`` partition is mounted, and then move the directory back.
|
|
|
|
Verify that your ZFS pool passphrase is stored in ``/etc/zfs/zroot.key`` and that permissions are 000::
|
|
|
|
echo -n ZFS passphrase: && cat /etc/zfs/zroot.key
|
|
echo -n Permissions: && ls -aFl /etc/zfs/zroot.key
|
|
|
|
Set the ``cachefile`` property for your pool::
|
|
|
|
zpool set cachefile=/etc/zfs/zpool.cache zroot
|
|
|
|
Enable systemd zfs services::
|
|
|
|
systemctl enable zfs.target
|
|
systemctl enable zfs-import-cache
|
|
systemctl enable zfs-mount
|
|
systemctl enable zfs-import.target
|
|
|
|
Create ``/etc/fstab`` to make sure your EFI system partition will be mounted::
|
|
|
|
cat > /etc/fstab <<EOF
|
|
$(blkid -s PARTUUID -o export $TARGET_ESP | grep '^PARTUUID=') /boot/efi vfat defaults 0 1
|
|
EOF
|
|
|
|
Configure ``initramfs-tools``
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Because the encryption key is stored in ``/etc/zfs`` directory, it will automatically be copied into the system
|
|
initramfs.
|
|
|
|
.. note::
|
|
|
|
The pool key will be stored in kernel initramfs in plain text. Never move this initramfs image off of the encrypted
|
|
pool! In addition, it is strongly recommended that the initramfs be created with permissions that prevent users from
|
|
inspecting its contents::
|
|
|
|
echo "UMASK=0077" > /etc/initramfs-tools/conf.d/umask.conf
|
|
|
|
Set up ZFSBootMenu
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
Set a desired kernel command line for the boot environment, *e.g.*::
|
|
|
|
zfs set org.zfsbootmenu:commandline="quiet" zroot/ROOT
|
|
|
|
Install ZFSBootMenu. There is no pre-built package for Debian, so we need to install from source.
|
|
|
|
mkdir -p /usr/local/src
|
|
cd /usr/local/src
|
|
git clone 'https://github.com/zbm-dev/zfsbootmenu.git'
|
|
cd zfsbootmenu
|
|
make core dracut
|
|
|
|
Configure ZFSBootMenu to build images. (It may be easier to modify the configuration in an editor).
|
|
|
|
.. code-block::
|
|
|
|
sed -i -e "s|void|debian|" -e "s|ManageImages: false|ManageImages: true|" /etc/zfsbootmenu/config.yaml
|
|
|
|
Install required dependencies::
|
|
|
|
apt install libconfig-inifiles-perl libsort-versions-perl libboolean-perl libyaml-pp-perl fzf mbuffer kexec-tools dracut-core
|
|
|
|
Choose 'No' when asked if kexec-tools should handle reboots.
|
|
|
|
.. note::
|
|
|
|
Do not install ``dracut`` instead of ``dracut-core`` because the former conflicts with ``initramfs-tools``, requires
|
|
advanced configuration to boot your system. The ``dracut-core`` package coexists with ``initramfs-tools``, does not
|
|
alter standard system behavior, and provides everything needed by ZFSBootMenu.
|
|
|
|
Generate the system initramfs::
|
|
|
|
update-initramfs -c -k all
|
|
|
|
Generate a ZFSBootMenu image::
|
|
|
|
generate-zbm
|
|
|
|
Configure rEFInd to boot the ZFSBootMenu image::
|
|
|
|
cat > /boot/efi/EFI/debian/refind_linux.conf <<EOF
|
|
"Boot default" "spl.spl_hostid=0x$( hostid ) zbm.prefer=zroot zbm.skip loglevel=4"
|
|
"Boot to menu" "spl.spl_hostid=0x$( hostid ) zbm.prefer=zroot zbm.show loglevel=4"
|
|
EOF
|
|
|
|
(Optional) You may need to add rEFInd to your EFI boot order manually::
|
|
|
|
apt install efibootmgr
|
|
|
|
# List existing boot items
|
|
efibootmgr
|
|
|
|
# Add refind as a boot item
|
|
efibootmgr -c -d $TARGET_ESP -l "\\EFI\\refind\\refind_x64.efi" -L rEFInd
|
|
|
|
Exit the chroot and reboot::
|
|
|
|
exit
|
|
cd /
|
|
umount -R /mnt
|
|
zpool export -a
|
|
reboot
|