Root on ZFS with native encryption: Difference between revisions

From Alpine Linux
(update to reflects steps for latest version v3.12)
m (added additional categories)
 
(125 intermediate revisions by 9 users not shown)
Line 1: Line 1:
= Setting up  Alpine Linux using ZFS with a pool that uses ZFS' native encryption capabilities =
This is a guide for installing Alpine Linux with its root partition on an encrypted [[ZFS]] volume, using ZFS's own encryption capabilities. The system will be encrypted when powered off and will need to be unlocked by typing a passphrase at boot. To be able to boot the system, the `/boot` partition remains unencrypted.


== Download ==
== Initial Setup ==


Download the '''extended'' release from https://www.alpinelinux.org/downloads/ as only it contains the zfs kernel mods at the time of this writing (2020.07.10)
Download the '''extended''' release from https://www.alpinelinux.org/downloads/ as only it contains the zfs kernel modules the time of writing.as on (2022-02-12). Write it to a USB device and boot from it.


Write it to a USB and boot from it.
Run the following to start the installation procedure: {{cmd|setup-alpine}}


== Initial setup ==
Answer all the questions, and hit {{Key|Ctrl}}+{{Key|C}} when prompted for which disk you'd like to use.


Run the following
=== Optional: SSH access ===


    setup-alpine
This section is optional and it assumes internet connectivity. You may enable sshd so you can ssh into the box and copy and paste the rest of the commands from these instructions into a terminal window.


Answer all the questions, and hit ctrl-c when promted for what disk you'd like to use.
Edit {{path|/etc/ssh/sshd_config}} and search for `Permit`. Change the value after `PermitRootLogin` to read `yes`


== OPTIONAL ==
save and exit to shell. Run {{codeline|service sshd restart}}


This section is optional and it assumes internet connectivity. You may enable sshd so you can ssh into the box and copy and paste the rest of the commands into my terminal window from these instructions.
Now you can ssh in as root. Do not forget to go back and comment this line out when you're done since it will be enabled on the resulting machine. You will be reminded again at the end of this doc.


Edit `/etc/ssh/sshd_config` and search for `Permit`. Change the value after `PermitRootLogin` to read `yes`
=== Add required packages  ===


save and exit to shell. Run `service sshd restart`
{{cmd|apk add {{pkg|zfs}} {{pkg|sfdisk}} {{pkg|e2fsprogs}} {{pkg|syslinux}}}}


Now you can ssh in as root. Do not forget to go back and comment this line out when you're done since it will be enabled on your resulting machine. You will be reminded again at the end of this doc.
== Partition setup ==


== Add needed packages  ==
We're assuming that {{path|/dev/sda}} is the target storage device here and in the rest of the document, but the name of the storage device you wish to install to may be different. To see a list of storage devices and determine the correct one, type {{codeline|sfdisk -l}}.


    apk add zfs sfdisk e2fsprogs syslinux
{{cmd|echo -e "/dev/sda1: start{{=}}1M,size{{=}}100M,bootable\n/dev/sda2: start{{=}}101M" | sfdisk --quiet --label dos /dev/sda}}


== Create our partitions ==
=== Create device nodes ===


We're assuming `/dev/sda` here and in the rest of the document but you can use whatever you need to. To see a list, type: `sfdisk -l`
{{cmd|mdev -s}}


    echo -e "/dev/sda1: start=1M,size=100M,bootable\n/dev/sda2: start=101M" | sfdisk --quiet --label dos /dev/sda
=== Create the {{path|/boot}} filesystem ===


== Create device nodes ==
{{cmd|mkfs.ext4 /dev/sda1}}


    mdev -s
== ZFS setup ==


== Create the /boot filesystem ==
=== Create the root zpool ===


    mkfs.ext4 /dev/sda1
{{cmd|modprobe zfs
 
zpool create -f -o ashift{{=}}12 \
== Create the root filesystem using zfs ==
-O acltype{{=}}posixacl -O canmount{{=}}off -O compression{{=}}lz4 \
 
-O dnodesize{{=}}auto -O normalization{{=}}formD -O relatime{{=}}on -O xattr{{=}}sa \
    modprobe zfs
-O encryption{{=}}aes-256-gcm -O keylocation{{=}}prompt -O keyformat{{=}}passphrase \
    zpool create -f -o ashift=12 \
-O mountpoint{{=}}/ -R /mnt \
        -O acltype=posixacl -O canmount=off -O compression=lz4 \
rpool /dev/sda2}}
        -O dnodesize=auto -O normalization=formD -O relatime=on -O xattr=sa \
        -O encryption=aes-256-gcm -O keylocation=prompt -O keyformat=passphrase \
        -O mountpoint=/ -R /mnt \
        rpool /dev/sda2


You will have to enter your passphrase at this point. Choose wisely, as your passphrase is most likely [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#5-security-aspects the weakest link in this setup].
You will have to enter your passphrase at this point. Choose wisely, as your passphrase is most likely [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#5-security-aspects the weakest link in this setup].


A few notes on the options supplied to zpool:
A few notes on the options supplied to zpool:
 
<ul>
- `ashift=12` is recommended here because many drives today have 4KiB (or larger) physical sectors, even though they present 512B logical sectors
<li>{{codeline|ashift{{=}}12}} is recommended here because many drives today have 4KiB (or larger) physical sectors, even though they present 512B logical sectors</li>
 
<li>{{codeline|acltype{{=}}posixacl}} enables POSIX ACLs globally</li>
- `acltype=posixacl` enables POSIX ACLs globally
<li>{{codeline|normalization{{=}}formD}} eliminates some corner cases relating to UTF-8 filename normalization. It also enables `utf8only=on`, meaning that only files with valid UTF-8 filenames will be accepted.</li>
 
<li>{{codeline|xattr{{=}}sa}} vastly improves the performance of extended attributes, but is Linux-only. If you care about using this pool on other OpenZFS implementation don't specify this option.</li></ul>
- `normalization=formD` eliminates some corner cases relating to UTF-8 filename normalization. It also enables `utf8only=on`, meaning that only files with valid UTF-8 filenames will be accepted.
 
- `xattr=sa` vastly improves the performance of extended attributes, but is Linux-only. If you care about using this pool on other OpenZFS implementation don't specify this option.


After completing this, confirm that the pool has been created:
After completing this, confirm that the pool has been created:


    # zpool status
{{cmd|# zpool status}}


Should return something like:
Should return something like:
Line 75: Line 68:
       scan: none requested
       scan: none requested
     config:
     config:
 
   
         NAME        STATE    READ WRITE CKSUM
         NAME        STATE    READ WRITE CKSUM
         rpool      ONLINE      0    0    0
         rpool      ONLINE      0    0    0
           sda2      ONLINE      0    0    0
           sda2      ONLINE      0    0    0
 
   
     errors: No known data errors
     errors: No known data errors


== Create the required datasets and mount root ==
=== Create the required datasets and mount root ===


    zfs create -o mountpoint=none -o canmount=off rpool/ROOT
{{cmd|zfs create -o mountpoint{{=}}none -o canmount{{=}}off rpool/ROOT
    zfs create -o mountpoint=legacy rpool/ROOT/alpine
zfs create -o mountpoint{{=}}legacy rpool/ROOT/alpine
    mount -t zfs rpool/ROOT/alpine /mnt/
mount -t zfs rpool/ROOT/alpine /mnt/}}


== Mount the `/boot` filesystem ==
=== Mount the {{path|/boot}} filesystem ===


    mkdir /mnt/boot/
{{cmd|mkdir /mnt/boot/
    mount -t ext4 /dev/sda1 /mnt/boot/
mount -t ext4 /dev/sda1 /mnt/boot/}}


=== Enable ZFS' services ===
=== Enable ZFS' services ===


    rc-update add zfs-import sysinit
{{cmd|rc-update add zfs-import sysinit
    rc-update add zfs-mount sysinit
rc-update add zfs-mount sysinit}}


== Install Alpine Linux ==
== Install Alpine Linux ==


    setup-disk /mnt
{{cmd|setup-disk /mnt
    dd if=/usr/share/syslinux/mbr.bin of=/dev/sda # write mbr so we can boot
dd if{{=}}/usr/share/syslinux/mbr.bin of{{=}}/dev/sda # write mbr so we can boot}}


Reboot and enjoy!


== Reboot and enjoy! ==
'''NOTE:''' If you went with the optional step, be sure to disable root login after you reboot.


😉
== See also ==
* [[ZFS]]
* [https://openzfs.github.io/openzfs-docs/Getting%20Started/Alpine%20Linux/Root%20on%20ZFS.html OpenZFS Guide for Alpine Linux]


'''NOTE:'''
[[Category:Storage]]
If you went with the optional step, be sure to disable root login after you reboot.
[[Category:Installation]]
[[Category:Security]]

Latest revision as of 10:12, 2 April 2025

This is a guide for installing Alpine Linux with its root partition on an encrypted ZFS volume, using ZFS's own encryption capabilities. The system will be encrypted when powered off and will need to be unlocked by typing a passphrase at boot. To be able to boot the system, the `/boot` partition remains unencrypted.

Initial Setup

Download the extended release from https://www.alpinelinux.org/downloads/ as only it contains the zfs kernel modules the time of writing.as on (2022-02-12). Write it to a USB device and boot from it.

Run the following to start the installation procedure:

setup-alpine

Answer all the questions, and hit Ctrl+C when prompted for which disk you'd like to use.

Optional: SSH access

This section is optional and it assumes internet connectivity. You may enable sshd so you can ssh into the box and copy and paste the rest of the commands from these instructions into a terminal window.

Edit /etc/ssh/sshd_config and search for `Permit`. Change the value after `PermitRootLogin` to read `yes`

save and exit to shell. Run service sshd restart

Now you can ssh in as root. Do not forget to go back and comment this line out when you're done since it will be enabled on the resulting machine. You will be reminded again at the end of this doc.

Add required packages

apk add zfs sfdisk e2fsprogs syslinux

Partition setup

We're assuming that /dev/sda is the target storage device here and in the rest of the document, but the name of the storage device you wish to install to may be different. To see a list of storage devices and determine the correct one, type sfdisk -l.

echo -e "/dev/sda1: start=1M,size=100M,bootable\n/dev/sda2: start=101M" | sfdisk --quiet --label dos /dev/sda

Create device nodes

mdev -s

Create the /boot filesystem

mkfs.ext4 /dev/sda1

ZFS setup

Create the root zpool

modprobe zfs zpool create -f -o ashift=12 \ -O acltype=posixacl -O canmount=off -O compression=lz4 \ -O dnodesize=auto -O normalization=formD -O relatime=on -O xattr=sa \ -O encryption=aes-256-gcm -O keylocation=prompt -O keyformat=passphrase \ -O mountpoint=/ -R /mnt \ rpool /dev/sda2

You will have to enter your passphrase at this point. Choose wisely, as your passphrase is most likely the weakest link in this setup.

A few notes on the options supplied to zpool:

  • ashift=12 is recommended here because many drives today have 4KiB (or larger) physical sectors, even though they present 512B logical sectors
  • acltype=posixacl enables POSIX ACLs globally
  • normalization=formD eliminates some corner cases relating to UTF-8 filename normalization. It also enables `utf8only=on`, meaning that only files with valid UTF-8 filenames will be accepted.
  • xattr=sa vastly improves the performance of extended attributes, but is Linux-only. If you care about using this pool on other OpenZFS implementation don't specify this option.

After completing this, confirm that the pool has been created:

# zpool status

Should return something like:

     pool: rpool
    state: ONLINE
     scan: none requested
   config:
   
       NAME        STATE     READ WRITE CKSUM
       rpool       ONLINE       0     0     0
         sda2      ONLINE       0     0     0
   
   errors: No known data errors

Create the required datasets and mount root

zfs create -o mountpoint=none -o canmount=off rpool/ROOT zfs create -o mountpoint=legacy rpool/ROOT/alpine mount -t zfs rpool/ROOT/alpine /mnt/

Mount the /boot filesystem

mkdir /mnt/boot/ mount -t ext4 /dev/sda1 /mnt/boot/

Enable ZFS' services

rc-update add zfs-import sysinit rc-update add zfs-mount sysinit

Install Alpine Linux

setup-disk /mnt dd if=/usr/share/syslinux/mbr.bin of=/dev/sda # write mbr so we can boot

Reboot and enjoy!

NOTE: If you went with the optional step, be sure to disable root login after you reboot.

See also