User:Nathanlkoch/Tutorials/BTRFS Encryped Root On Bios

From Gentoo Wiki
Jump to:navigation Jump to:search

The following article should get you up and running with an encrypted luks and btrfs root system for BIOS. Typically I follow the handbook and the Full Disk Encryption documentation as I do similar installs.

Partition the drive

We create a bios boot partition and use the remaining space for the root partition.

root #gdisk /dev/sda
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048       2508799   1.2 GiB     8300 Linux filesystem 
   2            8192       250069679   119.2 GiB   8300  Linux filesystem
   3            8192?       250069679?   12 GiB   8300  Linux filesystem

Use cfdisk /dev/sda to set partition 1 as bootable. }}(After thought)

I advise you make a third partition. Do the same with 0n1p3 and use cryptsetup to format it. Then use mk.swap on the luks container and auto unlock it with crypttab. Remember you need to enable the "cryptsetup" flag on systemd.

Encrypt partition

First we'll format the partitions

root #cryptsetup luksFormat -s 256 -c aes-xts-plain64 /dev/sda2
root #cryptsetup luksFormat -s 256 -c aes-xts-plain64 /dev/sda3

Format the first partition for /boot.

root #mkfs.btrfs -L BTBOOT /dev/sda1

Finally we open the root partition

root #cryptsetup luksOpen /dev/sda2 Space
root #cryptsetup luksOpen /dev/sda3 Swap

Create filesystem, mountpoints and subvolumes

Now we format the mapped partition.

root #mkfs.btrfs -L BTROOT /dev/mapper/Space
root #mkswap /dev/mapper/Swap
root #swapon /dev/mapper/Swap

Next we create the mountpoints, mount the filesystems and create subvolumes

root #mkdir /mnt/btrfsmirror
root #mount -t btrfs -o defaults,noatime,compress=lzo,autodefrag /dev/mapper/Space /mnt/btrfsmirror
root #mkdir /mnt/newroot
root #btrfs subvol create /mnt/btrfsmirror/activeroot
root #mount -t btrfs -o defaults,noatime,compress=lzo,autodefrag,subvol=activeroot /dev/mapper/Space /mnt/newroot
root #mkdir /mnt/newroot/home
root #mkdir /mnt/newroot/boot
root #btrfs subvol create /mnt/btrfsmirror/home
root #mount -t btrfs -o defaults,noatime,compress=lzo,autodefrag,subvol=home /dev/mapper/Space /mnt/newroot/home
root #mount -t btrfs -o defaults,noatime /dev/sda1 /mnt/newroot/boot

Stage 3

As per the Gentoo handbook download and install stage3 to your /mnt/newroot directory and extract.



Enter the chroot

We now need to chroot into /mnt/newroot and do the usual chroot stuff.

root #mount --types proc /proc /mnt/newroot/proc
root #mount --rbind /sys /mnt/newroot/sys
root #mount --make-rslave /mnt/newroot/sys
root #mount --rbind /dev /mnt/newroot/dev
root #mount --make-rslave /mnt/newroot/dev
root #mount --bind /run /mnt/newroot/run
root #mount --make-slave /mnt/newroot/run
The --make-rslave operations are needed for systemd support later in the installation.
When using non-Gentoo installation media, this might not be sufficient. Some distributions make /dev/shm a symbolic link to /run/shm/ which, after the chroot, becomes invalid. Making /dev/shm/ a proper tmpfs mount up front can fix this:
root #test -L /dev/shm && rm /dev/shm && mkdir /dev/shm
root #mount --types tmpfs --options nosuid,nodev,noexec shm /dev/shm

Also ensure that mode 1777 is set:

root #chmod 1777 /dev/shm /run/shm

Entering the new environment

Now that all partitions are initialized and the base environment installed, it is time to enter the new installation environment by chrooting into it. This means that the session will change its root (most top-level location that can be accessed) from the current installation environment (installation CD or other installation medium) to the installation system (namely the initialized partitions). Hence the name, change root or chroot.

This chrooting is done in three steps:

  1. The root location is changed from / (on the installation medium) to /mnt/newroot/ (on the partitions) using chroot
  2. Some settings (those in /etc/profile) are reloaded in memory using the source command
  3. The primary prompt is changed to help us remember that this session is inside a chroot environment.
root #chroot /mnt/newroot /bin/bash
root #source /etc/profile
root #export PS1="(chroot) ${PS1}"

Now follow the install handbook like you normally would. Update world etc...

Required packages

First add the required use flags for the packages.

root #echo "sys-boot/grub device-mapper" >> /etc/portage/package.use

Set the grub type for your system in /etc/portage/make.conf

FILE /etc/portage/
root #env-update

Install the required packages

root #emerge --ask btrfs-progs

If this installs newer kernel sources, please change the symlink either using eselect kernel or do it manually, build the kernel and reboot. After that proceed from here.


Enable cryptsetup

FILE /etc/portage/package.use/systemd
sys-apps/systemd cryptsetup
root #env-update
root #emerge -av sys-apps/systemd
root #dd bs=512 count=4 if=/dev/random of=/etc/swap.key iflag=fullblock
root #openssl genrsa -out /etc/swap.key 4096
root #chmod -v 0400 /etc/swap.key
root #chown root:root /etc/swap.key
root #cryptsetup luksAddKey /dev/3RDPARTSWAPLUKS /etc/swap.key
FILE /etc/crypttab
swap UUID=youruuid /etc/swap.key luks


Check that /etc/mtab contains the following lines and if not, add them:

FILE /etc/mtab
/dev/mapper/Space / btrfs rw,noatime,compress=lzo,autodefrag,subvol=activeroot 0 0
/dev/mapper/Space /home btrfs rw,noatime,compress=lzo,autodefrag,subvol=home 0 0

Next change /etc/fstab to this:

FILE /etc/fstab
LABEL=BTROOT    /mnt/btrfsmirror    btrfs    defaults,noatime,compress=lzo,autodefrag    0 0
LABEL=BTROOT    /                   btrfs    defaults,noatime,compress=lzo,autodefrag,discard=async,subvol=activeroot    0 0
LABEL=BTROOT    /home               btrfs    defaults,noatime,compress=lzo,autodefrag,discard=async,subvol=home    0 0
LABEL=BTBOOT    /boot               btrfs    defaults,noatime    0 0
UUID=youruuid	none	swap	sw,discard	0 0

Build kernel and initramfs

Now we'll create the kernel with the required configuration.

root #genkernel --luks --btrfs --oldconfig --save-config --menuconfig --install --bootloader=grub all
KERNEL Enabling device mapper and crypt target
[*] Enable loadable module support
    Device Drivers --->
        [*] Multiple devices driver support (RAID and LVM) --->
            <*> Device mapper support
            <*> Crypt target support
KERNEL Enabling cryptographic API functions for the cipher you used
[*] Cryptographic API --->
    <*> SHA224 and SHA256 digest algorithm
    <*> XTS support
    <*> AES cipher algorithms
    <*> AES cipher algorithms (x86_64)
KERNEL Enabling initramfs support
General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
KERNEL Enable btrfs support
File Systems  --->
    [*] Btrfs filesystem support


Customize grub

We'll change /etc/default/grub to fit our needs.

You will need to point your grub loader to unlock the UUID of your encrypted luks disk.

You can find the UUID of the disk by:

root #blkid

Now /etc/default/grub should look like this (i use systemd!):

FILE /etc/default/grub

Install grub to disk

root #grub-install /dev/sda

Generate grub.cfg

We'll use grub-mkconfig to generate the grub.cfg

root #grub-mkconfig -o /boot/grub/grub.cfg

Booting from encrypted disk

Make sure you boot from /dev/sda !!

You'll be asked for the password to unlock the boot partition and after that it should boot up as normal (without further password request!)


At this point you should have a full encrypted and working system.

You should now reboot. Grub will ask you for the password.

After that you should not be prompted for password input anymore.


Advanced Configurations

I would like to figure out how to make the contents of /boot encrypted while leaving /boot/efi and /boot/grub unencryped and configure grub to unlock the crypto disk before attempting to load the kernel. Leaving the kernel and the initramfs within the encrypted luks disk. Grub theoretically can do it. I just can't get it working. I was following this tutorial Full Encrypted Btrfs/Native System Root Guide but couldn't get a prompt for password. It seems a bit out dated. After tinkering for a bit I opted for this method. Apparently it can be done but there are a bunch of external resources needed and appears to be complicated. I am currently investigating.