LUKS
Encrypt a Partition
To encrypt e.g. /dev/sda3:
DEVICE=/dev/sda3
cryptsetup --verify-passphrase luksFormat $DEVICE
cryptsetup luksOpen $DEVICE cryptcontainer
mkfs.ext4 -L data /dev/mapper/cryptcontainer
Mount an encrypted Partition
To mount e.g. /dev/sda3:
DEVICE=/dev/sda3
MOUNTPOINT=/mnt/luks
cryptsetup luksOpen $DEVICE cryptcontainer
mkdir -p $MOUNTPOINT
mount /dev/mapper/cryptcontainer $MOUNTPOINT
Unmount an encrypted Partition
To unmount it:
MOUNTPOINT=/mnt/luks
umount $MOUNTPOINT
cryptsetup luksClose cryptcontainer
Linux Installation with Full Disk Encryption
The below commands are a condensed version of the information that can be found in the Arch Wiki and on Pavel Kogan's Blog
I used them with an Arch installation.
# Partition the disk
cfdisk /dev/sda
# create partition for whole disk of type Linux
# write partition table
# quit
cryptsetup luksFormat /dev/sda1
cryptsetup luksOpen /dev/sda1 lvm
pvcreate /dev/mapper/lvm
vgcreate vg /dev/mapper/lvm
# Adjust size for swap as needed
lvcreate -L 6G vg -n swap
# Adjust size for root fs and partition label as needed
lvcreate -L 75G vg -n os
# The rest is used for the data partition
lvcreate -l +100%FREE vg -n data
# create swap
mkswap -L swap /dev/mapper/vg-swap
# Formatting
mkfs.ext4 /dev/mapper/vg-os
mkfs.ext4 /dev/mapper/vg-data
# Mount the partitions to prepare for chroot
mount /dev/mapper/vg-os /mnt
mkdir -p /mnt/srv/my-data
mount /dev/mapper/vg-data /mnt/srv/my-data
swapon /dev/mapper/vg-swap
Now install the base system
The below info is mainly taken from Pavel Kogan's great guide on full disk encryption.
First, create a crypto key file to avoid having to type the crypt password twice upon boot:
dd bs=512 count=4 if=/dev/urandom of=/crypto_keyfile.bin
cryptsetup luksAddKey /dev/sda1 /crypto_keyfile.bin
chmod 000 /crypto_keyfile.bin # actually, even root doesn't need to access this
chmod -R g-rwx,o-rwx /boot # just to be safe
Add the lvm2 and encrypt hooks to /etc/mkinitcpio.conf My hooks line ended up looking as follows:
HOOKS="base udev autodetect modconf block encrypt lvm2 filesystems keyboard fsck"
Set the FILES option to the crypto keyfile just generated.
FILES=/crypto_keyfile.bin
Then, enable cryptodisks in /etc/default/grub Note the y, (not 1 !!) (The exact name of the variable seems to vary, so far I encountered the two below, just set them both to be sure)
GRUB_ENABLE_CRYPTODISK=y
GRUB_CRYPTODISK_ENABLE=y
... and the cryptdevice kernel parameter
GRUB_CMDLINE_LINUX="cryptdevice=/dev/sda1:lvm"
Then run
mkinitcpio -p linux
And finally
grub-mkconfig -o /boot/grub/grub.cfg
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=arch --recheck --debug /dev/sda
To reopen the volumes from a live system later on:
cryptsetup luksOpen /dev/sda1 lvm
# vgscan # to look for volume groups
vgchange -ay vg
# ls /dev/mapper/ # to show volumes
mount /dev/mapper/vg-os /mnt/
mount --rbind /dev /mnt/dev
mount --rbind /proc /mnt/proc
mount --rbind /sys /mnt/sys
mount --rbind /dev/pts /mnt/dev/pts
chroot /mnt /bin/bash
Alternative Initial Ram Filesystem creation with Dracut
The below worked on void-linux: Instead of mkinitcpio the initial ramdisk is created with dracut. The following config was needed:
Add the luks key kernel parameter in /etc/default/grub:
GRUB_CMDLINE_LINUX="cryptdevice=/dev/sda1:lvm"
Create an entry in /etc/crypttab (which will be included in the initialramfs so the crypto keyfile can be found).
Mind the counter-intuitive underscore in vg_os!!! Eventhough the device shows up as /dev/mapper/vg-os (with a dash) you MUST use an underscore in /etc/crypttab.
# crypttab: mappings for encrypted partitions
#
# Each mapped device will be created in /dev/mapper, so your /etc/fstab
# should use the /dev/mapper/<name> paths for encrypted devices.
#
# NOTE: Do not list your root (/) partition here.
# <name> <device> <password> <options>
vg_os /dev/sda1 /crypto_keyfile.bin luks
Now, for the keyfile to be available in the initial ramfilesystem, make dracut include it in the initial ramdisk by creating a dracut configuration file /etc/dracut.conf.d/10-crypt.conf:
install_items+="/crypto_keyfile.bin"
Dracut with unencrypted boot
Do NOT add an entry for the rootfs in /etc/crypttab. Otherwise you will be asked for the passphrase twice. (Once by the initialramfs and then during the actual os startup) Instead, activate automatic assembly of special device with the rd.auto kernel parameter in /etc/default/grub:
GRUB_CMDLINE_LINUX="rd.auto=1"
This will make dracut build the initial ramdisk such that it automatically asks you for the crypto passphrase of the rootfs. Now, short of using /etc/crypttab I have not found a way to specify the name to be used for the decrypted device. This is annoying at two places:
1) fstab -> Here it can be easily addressed by using disk labels
LABEL=void_rootfs / xfs defaults 0 2
2) Grub configuration. grub-mkconfig seems to determine the value for
the root= parameter based on the device that is currently mounted as the
rootfs. (It might be possible to change this behavior but I haven't
bothered finding out how). This is a problem when you run it for the
very first time in a chroot if you have manually unlocked the crypto
device and given it a random name. So for grub-mkconfig to do the right
thing you need to chroot into the system with the crypto device being
opened under the name it will be given by the initramfs. Using the
kernel parameters "rd.shell rd.debug lug_buf_len=1M" I found that
dracut names the device according to the following scheme:
"luks-
So, assuming that your crypto partition's UUID is 13068607-1f0d-4121-8449-23ed358c2f82 the procedure to build the "right" grub.cfg would be:
CRYPT_DEV=UUID="13068607-1f0d-4121-8449-23ed358c2f82"
cryptsetup luksOpen /dev/disk/by-uuid/${UUID} luks-${UUID}
# chroot into /dev/mapper/luks-${UUID}
# run grub-mkconfig / grub-install / dracut
Adding/Removing Slots
Slots can be listed with
cryptsetup luksDump /dev/sda1
And removed with
cryptsetup luksKillSlot `<device>` `<SLOT ID>
A new key can be added with
cryptsetup luksAddKey <device> (/path/to/<additionalkeyfile>) -d /path/to/<keyfile>
Creating a Container File
container_name=my_container
container_file=/path/to/cryptcontainers/${container_name}
container_mpt=/path/to/mountpoint
size_mb=56
dd if=/dev/urandom of=$container_file bs=1M count=$size_mb
sudo cryptsetup -c aes-xts-plain64 -s 512 -h sha512 -y luksFormat $container_file
sudo cryptsetup luksOpen $container_file $container_name
sudo mkfs.ext4 /dev/mapper/$container_name
sudo mount -t ext4 /dev/mapper/$container_name $container_mpt
sudo chown -R ${USER} $container_mpt
sudo umount $container_mpt
sudo cryptsetup close $container_name