Table of contents
Background
I recently received my new work computer, and the guys from the IT department asked me to perform encryption, at least of my home partition. This was the first time I tried to encrypt partitions during the Arch Linux install. I remember some of my friends trying to encrypt their home without encrypting their whole partition, and I remembered that they had had some problems, so I though I might as well encrypt the whole partition.
Another thing I remember from a long time ago is that it was considered a good
practice to have your /
and your /home
on two separate partitions in case
of crashes. I did that a couple of time, and when crashes occurred, I had
never managed to fix them without wiping the whole disk, so eventually I
stopped doing that.
This install caused me some problems, and this is why I write this post: if anyone else than myself reads it and finds help in it, I'm glad, but I mostly write it in case I need to do this once again.
So here I am, with my brand new machine, with an Ubuntu distribution that I obviously won't keep. I have my Arch Linux iso on my USB stick, and I'm ready to install.
The mistakes
When encrypting, if you have your /
and /home
on the same partition, and
you want to encrypt your home, well, you'll be encrypting your /
, and since
/boot
is in /
, it will also be encrypted. Maybe your want to encrypt your
/boot
for security reasons, but it wasn't specially my case. The thing is
encrypting your /boot
leads to extra complexity, since you'll need to decrypt
before booting.
This is why I decided to finally go back to putting /
and /home
on two
separate partitions. That way, I encrypt my home, and that's all.
Another thing that a lot of people that encrypt disks use is LVM. Honestly, I don't know much about LVM, I just know that is adds a layer of complexity to the setup, and if I can avoid that, I might as well.
The subtleties
Docker
If you use docker, you know that it tends to need a lot of storage, and if you
want to have a small /
partition to have more space in your home, docker will
be a problem very quickly.
The way I deal with this is to put the docker directory in /home/docker
. That
way, it will be encrypted (I don't know if it's very important, but if during
dev, I write some private key in clear, I think it can still be useful), but
most importantly, it's now in the partition where I have the most available
space.
To do this, I just edit the /etc/docker/daemon.json
file:
{
"data-root": "/home/docker"
}
Wake-on-Lan
If you want to have Wake-on-Lan on your computer, and encrypt your disk, you may have the following problem: when you will try to wake your computer, and then it will prompt for your passphrase... but if you're remote, you're going to have some troubles to type it.
My solution for this is to configure your marchine so that no encryption setup
is performed at boot: you skip a few steps (manual edition of
/etc/mkinitcpio.conf
and /etc/default/grub
, it will be indicated in this
tutorial), so that nothing special is performed at boot.
That way, when your computer boots, it won't ask for any passphrase, and simply won't mount your encrypted home.
Here where it gets tricky, on your /
partition (with encrypted home not
mounted), you will create a /home/$USER
directory with a few files, so that
your computer is usable without the home partition mounted. The only necessary
file will be your /home/$USER/.ssh/authorized_keys
, which will allow you to
SSH your machine so that you can remotely mount your encrypted partition, but
you can also have a nice .bashrc
(or .zshrc
) to help you mount your stuff.
I use my arch without login manager (lightdm or stuff like this), I just launch
login in the TTY, and run startx
to start my desktop manager, so my .zshrc
on my /
partition simply looks like this:
startx() {
# I'm used to running startx right after I login, to this first mount my
# disks and then runs startx.
mount-disk
# Don't start if disks aren't mounted.
if [ $? -ne 0 ]; then
return
fi
/bin/startx
}
mount-disk() {
# In my home on my encrypted partition, I have an empty file in
# $HOME/.mounted, this way, I can easily check if my encrypted partition is
# mounted or not.
if [ -f $HOME/.mounted ]; then
echo "already mounted" >&2
return
fi
# On my computer, I have two disks, one NVMe with my OS, and one HDD with
# more space. I want three attempts at typing the passphrase.
for retry in 1 2 3; do
# Because they're encrypted with the same passphrase, I read the
# passphrase once, and then decrypt both disks.
sudo echo -n "Enter your passphrase: "
read -s passphrase
# Mount the NVMe encrypted partition
echo "$passphrase" | sudo cryptsetup luksOpen /dev/nvme0n1p7 luks
# If mounted correctly, break this loop and mount other partitions.
if [ $? -eq 0 ]; then
break
elif [ $retry -eq 3 ]; then
# If the third attempt failed, exit
echo "Couldn't decrypt disk"
return 1
fi
done
sudo mount /dev/mapper/luks /home
echo "$passphrase" | sudo cryptsetup luksOpen /dev/sda1 luks2
sudo mount /dev/mapper/luks2 /mnt
# Since my root partition is quite small, I can't put docker files on it,
# so if docker is enabled in systemd, it will crash because the files are on
# the partition that are not mounted yet, so I start it manually here.
sudo systemctl start docker
# Because we mounted the home partition on /home, our current working dir is
# broken, so we re-cd to our home, and source our new zshrc.
cd /home/$USER
source .zshrc
}
The process
Booting the USB drive
As it always begin, I plug my USB drive into my computer, boot it and rapidly press F12, and make my computer boot on the USB drive. From there, I get a prompt, and as a french guy, with an azerty keyboard, I start by running
loadkeys fr
(which I need to type as loqdkeys fr
since the default keyboard layout is the
qwerty one).
Preparing the disk
Partitions
Then comes the part when we format the disk. As said previously, I'll have my
/
and /home
on two separate partitions, and since I don't believe in swap,
I made three partitions :
/dev/nvme0n1p1
that corresponds to/boot/efi
, 100MB;/dev/nvme0n1p2
that corresponds to/
,15GB (I want to keep it small because my laptop only has 512GB of SSD)50GB, even if you have a small disk, be large on this one or you'll be in trouble later (happened to me numerous times, nowdays, I tend to set it as 10% of my disk size);/dev/nvme0n1p3
that corresponds to/home
, that fills the rest of my disk and that will be encrypted.
Then, we need to format those partitions. So it starts as usual:
mkfs.vfat -F32 /dev/nvme0n1p1
mkfs.ext4 /dev/nvme0n1p2
mkfs.ext4 /dev/nvme0n1p3 # This may be useless but I'm not sure
Encryption
Then we need to setup the encryption of our /dev/nvme0n1p3
:
cryptsetup --type luks1 luksFormat /dev/nvme0n1p3
I'm not super sure the --type luks1
is required, but I use Grub as bootloader
and I'm not sure it supports luks2
.
Anyway, this will ask you for a passphrase. Finding a good passphrase is hard, but advice can be found online. I used diceware a source of inspiration.
When this is done, you need to mount your partitions to continue the install.
The following command remounts the encrypted disk to an unencrypted location:
cryptsetup luksOpen /dev/nvme0n1p3 luks
It creates a virtual disk in /dev/mapper/luks
that you then need to format as
well:
mkfs.ext4 /dev/mapper/luks
Note for non-qwerty keyboards
If you want your home partition to be decrypted on boot, and you have a beautiful passphrase but a non-qwerty keyboard, you may have a hard time typing in your passphrase when your computer will be booting, because changing your keyboard layout this early in the booting process is either very hard, or impossible.
The way I solve this issue (and I'm not the one who came up with this trick, I think I found it on stackoverflow but I can't find the original source), is to add a second decryption key, corresponding to what my passphrase would be if I typed it on the wrong keyboard layout.
I do this by:
- running
cryptsetup luksAddKey /dev/nvme0n1p3
, with my french keyboard layout; - typing in my current passphrase, with my french keyboard layout;
- switching to another TTY (Ctrl+Alt+F2), and logging in as root;
- changing my keyboard layout to us (
loadkeys us
, not sure if it should beus
oren
) - switching back to my first TTY (Ctrl+Alt+F1);
- typing in the same passphrase, and validating it.
If everything went well, you should now have two passphrases, corresponding to the same key strokes, but on different keyboard layouts, that way, if you're booting your computer, you'll use the qwerty keyboard layout, but if you're booting from a USB device to recover data after crashing your OS, you can still decrypt it with your regular keyboard layout.
Mount
If you don't care about Wake-on-Lan, you can start mounting everything everywhere:
mount /dev/nvme0n1p2 /mnt
mkdir -p /mnt/boot/efi && mount /dev/nvme0n1p1 /mnt/boot/efi
mkdir /mnt/home && mount /dev/mapper/luks /mnt/home
If you care about Wake-on-Lan, don't mount the home partition yet, so just mount the following:
mount /dev/nvme0n1p2 /mnt
mkdir -p /mnt/boot/efi && mount /dev/nvme0n1p1 /mnt/boot/efi
Install all the things
Now is the moment to pacstrap all the things. Make sure you have an internet
connection, edit your /etc/pacman.d/mirrorlist
to put the servers close to
you at the top of the file, and here we go:
# Pacman may crash yelling that packages are invalid or correputed because of
# PGP keys, so you might need the two following lines in order for pacstrap to
# work
pacman-key --init
pacman-key --populate archlinux
# Install basic things
pacstrap /mnt base base-devel linux linux-firmware netctl dhclient dhcpcd wireless_tools wpa_supplicant dialog
Those should let you connect to the internet once the install is finished. Make sure to also install your favorite text editor.
You should also generate your fstab file:
genfstab -Up /mnt >> /mnt/etc/fstab
This file describes which partitions should be mounted and where when the computer boots. If you didn't mount your home yet, it will not appear in the fstab file, and so it won't be mounted during boot, which will allow you to mount it later (via SSH for example).
The chroot
Now comes the time to chroot.
arch-chroot /mnt
Welcome to your new computer. You can configure things such as the machine name, the timezone, the keyboard layout, etc... Don't hesitate to check the official guide for these parts, encryption doesn't change anything until the Initramfs (mkinitcpio).
You will certainly want to install more packages, pacman may give you a hard time again because of PGP keys, so you may need to run the following:
pacman-key --init
pacman-key --populate archlinux
Also, don't forget to set the root password with the passwd
command.
Initramfs
To be honest, I have no idea what this does, but I know that it's very important.
Start by running mkinitcpio -p linux
. This should generate a file named
/etc/mkinitcpio.conf
.
If you want Wake-on-Lan, you can skip to the next section. If you want to
decrypt your encrypted partition on boot, you will need to edit
/etc/mkinitcpio.conf
.
In this file you should add ext4
in the modules line, my line looks like this:
MODULES=(ext4)
and add encrypt
just before filesystems
in the hooks line, my line looks
like this:
HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block encrypt filesystems fsck)
Then, run mkinitcpio -p linux
once again, and you're done with that part.
Grub
Ok, there surely are alternatives to Grub, but Grub is the only thing I know so that's what I use. To install grub, you need to install two other packages:
pacman -S grub efibootmgr
Normally, you should still have your internet connection active from before the chroot.
If you don't care about Wek-on-Lan, and want your home partition decrypted and
mounted, you will need to edit grub's default configuration . Edit the
/etc/default/grub
file. The line GRUB_ENABLE_CRYPTODISK=y
should be
uncommented, and I also changed the GRUB_CMDLINE_LINUX
line:
GRUB_CMDLINE_LINUX="cryptdevice=/dev/nvme0n1p3:luks"
Once those modifications are done (or not), you need to install the grub:
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=arch_grub
grub-mkconfig -o /boot/grub/grub.cfg
and normally you should be all set.
Reboot
You can now exit the chroot (Ctrl+D or exit
), umount the disks (umount -R /mnt
) and reboot your computer.
When booting again, grub should start and run Arch Linux, and if configured like so, it will prompt you for you passphrase. When the passphrase is entered, it will prompt for your login and password and you can then continue your configuration.