When we use GRUB as the boot loader we can setup a full disk LUKS encryption system without any use of a separated unencrypted boot partition.
Normally a separate boot partition needs to remain unencrypted as the bootloader needs to be able to boot the kernel before invoking LUKS, but because GRUB can load encryption modules such as
cryptodisk.mod we can use GRUB in various settings and still gain a real full disk encryption model without the need for an unencrypted boot partition. This setup is not possible using other boot loaders such as systemd-boot or syslinux, because neither of those boot loaders support loading encryption modules (at least as of writing).
The benefits of running with a real full disk encryption rather than an unencryptet boot partition is that we can migitate numerous attacks that can occur before and during the boot process, such as an attacker installing a modified kernel that is able to harvest your password phrase. This doesn't mean that the system isn't vulnerable to tampering with the BIOS or the bootloader itself, however it does provide yet another level of security that makes it a bit more difficult to gain access to the encrypted information.
It is very difficult to prevent tampering with the BIOS and/or other hardware components if you leave your computer out-of-sight, however you can dump your MBR and take a look at it with a hexedecimal editor and compare it to an old secure dump.
Other more secure options exist such as using UEFI with custom signature keys and Secure Boot instead of MBR, or booting from another medium, but this tutorial is about a legacy BIOS setup.
To keep things as simple as possible we're not going to use LVM (Logical Volume Management). LVM is a system for partitioning and managing logical volumes, or filesystems, but it has nothing to do with encryption in itself. LVM is a much more advanced and flexible system than the traditional method of partitioning a disk. LVM is used for easy resizing and moving partitions. With LVM you can create as many Logical Volumes as you need and you can also use LVM to take snapshots of your filesystem. However, unless you actually need any of these features, adding the extra layer of complexity doesn't provide any benefits.
Our setup will simply consist of two disk partitions, one for swap, and one for our normal filesystem. It will look like this:
sdX1 (LUKS encrypted swap) sdX2 (LUKS with EXT4, XFS, Btrfs or something else)
Both partitions will be fully encrypted with LUKS.
In this example we'll use EXT4 as the filesystem, but you can easily change it into XFS or Btrfs or something else.
If you choose to go for Btrfs you need to look into how you setup your different subvolumes, but it's not difficult. First you setup your filesystem on partition sdX2 and afterwards you setup the different subvolumes.
You can find futher information in the Arch Wiki.
One minor downside to this setup with GRUB is that you have to enter your encryption password twice. Once for GRUB and another time during the system boot-up when the Linux initrd image is loaded. However, this can be avoided by adding a keyfile to the crypttab file. When the system is booted the keyfile resides in the ramfs, unencrypted, but at this point, so does the LUKS master key, so if an attacker can get a hold of your keyfile in this situation, he might as well get your master key. In such a situation you will need to do a lot more to secure your system, something which is well beyond the scope of this tutorial.
Lets get started.
Setup your keyboard:
# loadkeys dk-latin1
Locate your hard drive:
# fdisk -l
Overwrite your disk with some random data and partition the disk:
In this case my drive is
sda. Please make sure you validate the device name for your drive, it might be
sdb or something else.
Before you begin partitioning your disk it's a good idea to overwrite the disk with random data. You can do this with the
dd command. Please notice that this takes considerable time with a large disk.
# dd if=/dev/urandom of=/dev/sda
Remember to verify that you're using the correct disklabel type! Check and change it with
Next, lets partition the disk. If you're not comfortable using
cfdisk is a nice partitioning tool. We're going to create two partitions.
# cfdisk /dev/sda
Create the 2 partitions. One for swap and the other for / (the root filesystem). Remember to make the root filesystem bootable.
Format the root partition using LUKS:
# cryptsetup luksFormat /dev/sda2
Open the newly formattet LUKS partition:
# cryptsetup luksOpen /dev/sda2 cryptroot
In this case I have chosen the name "cryptroot" for the encrypted partition, but you can name it whatever you want, just remember to change it everywhere where I have used "cryptroot" in this tutorial.
Format the root volume with the filesystem of your choice (EXT4, XFS, Btrfs, etc.) In this case we're going to use EXT4.
# mkfs.ext4 /dev/mapper/cryptroot
Mount the root filesystem:
# mount /dev/mapper/cryptroot /mnt
If you have used the Btrfs filesystem now is the time to create subvolumes. Once created unmount the root filesystem and then mount the subvolumes instead.
Select the mirrors by placing the ones you prefer in the top:
# vi /etc/pacman.d/mirrorlist
Bootstrap the system:
# pacstrap /mnt base
Generate and verify the fstab:
# genfstab -U /mnt >> /mnt/etc/fstab # cat /mnt/etc/fstab
Currently the swap partition on
sda1 isn't setup. We don't bother with that yet.
chroot into the newly created system and set stuff up:
# arch-root /mnt # echo KEYMAP=dk-latin1 > /etc/vconsole.conf # ln -sf /usr/share/zoneinfo/Europe/Copenhagen /etc/localtime # hwclock --systohc # vi /etc/locale.gen (uncomment your locales) # locale-gen # echo LANG=da_DK.UTF-8 > /etc/locale.conf # echo my-hostname > /etc/hostname
Create the keyfile:
# dd bs=512 count=4 if=/dev/urandom of=/crypto_keyfile.bin # cryptsetup luksAddKey /dev/sda2 /crypto_keyfile.bin # chmod 000 /crypto_keyfile.bin
Add "encrypt" to the mkinitcpio hooks and the keyfile to the files section:
# vi /etc/mkinitcpio.conf HOOKS="base udev autodetect modconf block encrypt filesystems keyboard fsck" FILES="/crypto_keyfile.bin"
Create the boot image:
# mkinitcpio -p linux
Set the root password:
# pacman -Sy grub
Enable cryptdisk support in GRUB:
# vi /etc/default/grub
Add the following lines:
If you're using a SSD disk you need to add "allow-discards" in order to enable TRIM support:
# grub-mkconfig -o /boot/grub/grub.cfg
Install GRUB to the boot disk and reboot:
# grub-install --target=i386-pc /dev/sda # exit # reboot
After login we need to setup swap. Update crypttab:
# vi /etc/crypttab swap /dev/sda1 /dev/urandom swap,cipher=aes-cbc-essiv:sha256,size=256
Reboot the system again and after login verify that the encryptet swap partition is mapped correctly:
# ls -l /dev/mapper/ ... swap -> ../dm1
Enable the swap:
# swapon /dev/mapper/swap
You can verify a last time with:
# vi /etc/fstab /dev/mapper/swap swap swap defaults 0 0
Now you can setup the network and install additional users and packages:
# useradd -m -g wheel -s /bin/bash foo # passwd foo
I prefer to run with
systemd-networkd, so I'll set those up.
# rm /etc/resolv.conf # vi /etc/systemd/network/wired.network [Match] Name=enp2s0 [Network] DHCP=yes # systemctl enable systemd-resolved.service # systemctl enable systemd-networkd.service # systemctl start systemd-resolved.service # systemctl start systemd-networkd.service # ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
/etc/nsswitch.conf is used by GNU C Library (glibc) and certain other applications to determine the sources from which to obtain name service information in a range of categories and in what order. For example /etc/hosts is used by the
In my case I need to change the setup of nsswitch in order to avoid a very long resolve time.
hosts: files mymachines dns myhostname
Feel free to email me any suggestions or comments.