How To Set Up an Encrypted, Compressed Filesystem in Arch Linux
Written by J David Smith
Published on 15 August 2015
The best example I have of this is a large dataset I'm downloading from a REST API as we speak. The current uncompressed size is 25G. The amount of space used on this partition has only increased by about 5G so far.The size is reported by du -hs
, which does not report compressed size on a btrfs-compressed partition
This document is intended to be a guide on how to set up a disk (especially a SSD, which will best take advantage of the features) to use both encryption and compression. Please read the entire thing once at least before attempting installation. In particular, in step 4+ there are gaps in the process where 'normal' installation continues (and for which I have not duplicated the normal instructions). While none of them are irreversible, it will be easier if you understand everything before diving in.
The Goal
One frustration I've always had with FS setup guides is that they often don't start with what they intend to give you. I will not make that mistake. The ultimate result of this guide should be a fresh Arch Linux installation with:
- A
/boot
partition (On UEFI systems, this will become the EFI System Partition) - An encrypted
I make no guarantees about the security of theencryption. Note that in my setup I actually have options configuredthat break plausible deniability. If you need advanced securityguarantees like plausible deniability, this guide is not theplace to look! LVM volume containing: - A compressed
/
partition - A compressed
/home
partition - An uncompressed
swap
partition
- A compressed
WARNING: It is very important that you do not use a swapfile on btrfs! It will not work! You have been warned!
Note: Much of the LVM-on-LUKS material is now covered on the Arch Wiki, which I did not realize when beginning to write. The material used to be much more scattered. I pieced together much of the contents of this post from reading various blogs and the dm-crypt
wiki page.
Step 0: Pre-Setup
BACK UP YOUR DATA!
Unless you are working with a brand-new drive, do a double check to confirm that you have all the data you need. Unlike normal formatting, where blocks are typically touched in an ordered fashion, encrypted data will be spread across the drive. Thus, the chance to retrieve data will very quickly vanish!
With that said, grab the latest Arch CD and burn it to a disc. Boot from it.Remember to pull up this document on a phone or other computer, or to print it off!
Step 1: Initial Partitioning
Using your favorite partition editor (I personally am a fan of parted
), create 2 partitions:
/boot
(See this page for UEFI systems)- A blank partition consuming the rest of the drive (or some portion of it. Your choice)
For simplicity, I will use sda1/2
to refer to these partitions. In the real world, it is best to use their UUIDs to reference them.
Step 2: Encryption
Setting up disk encryptionAgain, I make no promises about the security of your data! The default cryptsetup
settings are pretty solid, but not necessarily optimal! is surprisingly easy with cryptsetup
.
# cryptsetup luksFormat /dev/sda2
This command sets up encryption on/dev/sda2
. It should prompt you for a passphrase.You can replace it with a key on a flash drive or some other setup later. Setting LUKS up to use anything other than the default passphrase setup is outside the scope of this guide Please remember this!# cryptsetup open –type luks /dev/sda2 vg
This command sets up a mapping from/dev/mapper/vg
to the (decrypted) contents of the drive.
Step 3: LVM
To create a set of LVMI use LVM here because – last I knew – swap partitions can't be on BTRFS sub-volumes. Since LVM is already needed, there isn't much point in adding yet another layer of indirection with BTRFS sub-volumes on top of LVM volumes. volumes:
# pvcreate /dev/mapper/vg
This command creates an LVM physical volume. See the man page for more details on what that actually means.# vgcreate vg /dev/mapper/vg
This command creates a volume group on the physical volume at/dev/mapper/vg
.# lvcreate -L <N>G vg -n swap
lvcreate
creates a logical volume in a volume group. Again, see the man page for more details on the actual meaning of the terminology.
Replace<N>
by the amount of RAM you have. So if you had 4GB, it'd be-L 4G
.# lvcreate -L 30G vg -n root
This partition will be used for/
. I like having a fairly large amount of space, especially as some dev kits (looking at you, Android) clock in at rather heinous sizes.# lvcreate -l +100%FREE vg -n home
Finally, use the rest of the space for home.# mkfs.btrfs /dev/vg/root; mkfs.btrfs /dev/vg/home; mkswap /dev/vg/swap
Create the filesystems on each of the partitions. Compression is set after creation.
Step 4: Compression
Continue with the normal installation with two exceptions:
When mounting either btrfs volume, use the -o compress=lzo
option to mount.In fact, existing btrfs partitions can be compressed on the fly simply by setting compress=lzo
or compress=zlib
in /etc/fstab
This will enable compression of newly-written data.
When generating the /etc/fstab
file, add the compress=lzo
option to the 4th column. If you are using an SSD, adding noatime,discard,ssd
Note that enabling discard
has security ramifications! Discard will remove any chance of claiming plausible deniability and will reveal some of the usage patterns of the disk. Discard will not reveal any data. In my case, I find it worthwhile to make this tradeoff in order to extend the life of the drive. is also recommended. When labeling the drives in /etc/fstab
the command lsblk -o NAME,LABEL,UUID
can be used to locate the LABELs or UUIDs of your volumes. *It is strongly recommended that you use those instead of the dev
-path* format!
Step 5: Bootloader
Continue with normal installation until you are setting up the boot loader.If this is your first time setting up a boot loader on UEFI, it may seem as if the world has suddenly become a confusing and dangerous place. I recommend using systemd-boot
(formerly known as gummiboot
). Any feelings about systemd
aside, it is really simple and easy to use. See the Arch Wiki for more info.
Step 5.1: Configure mkinitcpio
Two hooks need to be added to mkinitcpio
: encrypt
and lvm2
. Add them – in that order – to the HOOKS
line of /etc/mkinitcpio.conf
after the keyboard
hook and before the filesystem
hook. If you also want to set up hibernation, add the resume
hook just before the filesystem
hook. If you are using an alternate keymap (like colemak or dvorak), add the keymap
hook immediately before the keyboard
hook.
The placement of the hooks is important! They are run in the order they are listed. This ordering makes sure that the keyboard is enabled before decryption is attempted – otherwise no passphrase could be entered – and that decryption occurs before filesystems are mounted.
Run mkinitcpio -p linux
to rebuild the initramfs.
Step 5.2: Configure the Kernel Parameters
Any bootloader you use should provide a way to configure kernel parameters see the relevant wiki page for details on how to do it for your specific bootloader. There are three parameters that are important:
cryptdevice
This parameter should come first in the options line. It sets up decryption and the device mapping. In my case I have this set ascryptdevice=/dev/sda2:vg:allow-discards
. Make sure that you use the correct device (preferably via UUID, which is not a thing I am doing right now). If you do not havediscard
enabled, then leave off the:allow-discards
part.root
This parameter controls which partition is mounted as/
. This should be set asroot=/dev/vg/root
unless you chose names other thanvg
orroot
for your root volume.resume
This parameter is optional but recommended for enabling hibernation. It should point to your encrypted swap partition:resume=/dev/vg/swap
My entire (working!) kernel parameter line is:
cryptdevice=/dev/sda2:vg:allow-discards root=/dev/vg/root quiet rw resume=/dev/vg/swap
Step 6: Finish & Enjoy!
Everything should be in order, so finish the installation process and reboot. If you have set things up correctly, then after booting you should be greeted with a prompt for your passphrase.
That's it! Your /
and /home
partitions are both transparently compressed and encrypted (in that order), and your swap partition is encrypted!Additionally: if you followed the instructions to enable hibernation, then `systemctl hibernate` should work and rebooting should prompt for your passphrase before resuming.
On my laptop, compressing /home
has gotten me 15-30% more storage (depending on what I have on home
at any given time – large text files like JSON data compress better than small text files or binary data like videos). If I were using zlib
instead of lzo
or used the compress-force
mount option, it'd be even more. A 15% storage gain may not seem like much, but that's an extra 30GB of space on my 200GB /home
partition. Given that SSDs are typically smaller than their magnetic-platter siblings, every additional byte helps.