Part 1: Protecting Your Data in Linux - A Deeper Look at Disk Encryption
- How to do complete full disk (/dev/sda) encryption with dm-crypt + LUKS and in plain mode
- How to manually create initramfs and boot from a USB stick – no genkernel, busybox or anything else that makes your life easier. No boot loader, either.
So, you've bought a new, shiny, fancy notebook for work and travel and cannot wait a second to turn it on for the first time. You cannot you wait to wipe away pre-installed Windows and install your favorite Linux distro on it.Great! But, you should never forget about personal data protection. Especially regarding mobile devices, which might be left unattended or stolen by some punk.There are numerous articles over the Internet describing encryption in Linux: file system encryption, partitions encryption, so-called full-disk encryption using dm-crypt with LUKS, LUKS on LVM, LVM on LUKS, plain type encryption and other witchcraft.Side notes on system configuration for SSD drives:
- Avoid using swap file/partition as it burns SSD write cycles
- Try avoiding file system journaling for the same reason
- Avoid trimming partitions as it will do step 1 below pointless
Step 0Prepare and boot from a Live USB Linux distribution.I prefer Kali Linux, as it boots pretty well on modern UEFI USB 3.0 systems.NOTE:Step 5.1 below will involve installing a new Linux OS in chroot environment. Perhaps, you already have Linux installed and would like to preserve the configuration. In this case, simply backup your root partition somewhere and restore later when required.
Step 1. Prepare hard diskIt's highly recommended to securely wipe – fill with random data – hard disk before encryption. It's needed so that intruders could not figure out where encrypted data (e.g. partitions) start and finish, as both encrypted and free space will look pretty much the same.They're a couple of ways to fill disk drive with random data:Method 1# dd if=/dev/urandom of=/dev/sda bs=4096This method is uber slow. Last time I tried it on my 256G SSD, it took 30000 seconds (over 8 hours) to complete. But it gives good randomness.dd has no means of showing progress, which could be frustrating - especially for long-running tasks.To view dd progress, use Pipe Viewer:# dd if=/dev/urandom | pv | of=/dev/sdaMethod 2# shred /dev/sdaThis method is much quicker. You can specify -v option to view progress and change the number of overwrite iterations by -n NUMBER option. Default is 3.For better randomness you can also use --random-source=/dev/urandom option.
Step 2. Prepare USB stick to boot fromYou'll need a FAT formatted USB stick to boot with UEFI. The stick itself can have either legacy MBR or GPT partition scheme. If you choose MBR partitioning, then don't forget to enable legacy (CSM) boot mode in UEFI Setup > Boot Configuration. However, I'd recommend using GPT on a UEFI bootable devices to avoid issues. Or, at least make sure your firmware supports loading EFI binary in CSM mode.If you'd like the stick to contain multiple partitions, then FAT partition must be the first one in the list.For example, I use a 16G USB stick formatted the following way:Partition table: GPTPartition 1: FAT32, size: 8GPartition 2: ext2, size: 8GPlease note, that EFI System Partitions (ESP) on USB sticks are not readable in Windows. You won't be able to use the drive for data storage on Windows-based systems if you create ESP on it.Let's assume you want to use your Linux bootable medium for files transferring and would like to keep old good MBR partition to plug in older computers. In this case, you probably won't need to format the stick at all then. Just just skip the formatting part and go straight to creating UEFI system directories tree.FormattingLet our USB stick be /dev/sdb device. For disk formatting, I prefer parted. It's convenient to use it in non-interactive mode:# parted -s -- /dev/sdb mktable msdos mkpart primary 2mib 100% set 1 boot onOr, in interactive mode:# parted /dev/sdb> mktable msdos> mkpart primary 2mib 100%> set 1 boot on> qNow, format the drive as FAT32:# mkfs.vfat -F 32 /dev/sdb1Creating UEFI system directories treeWhen booting a 64-bit OS from a USB stick, UEFI looks for a BOOTX64.EFI executable in EFIBOOT directory, so let's create it.# mkdir /mnt/usb-boot# mount /dev/sdb1 /mnt/usb-boot# mkdir -p /mnt/usb-boot/EFI/BOOTThat's it for now.
Step 3. Create crypto key fileCrypto key file will be used by cryptsetup tool to encrypt and decrypt hard disk.Since hard disk is not yet ready for operation, we'll use the USB stick to temporarily store generated crypto key file. We'll need a 512 bits key (cryptsetup supports key files with size up to 8M, though).Let's create it:# dd if=/dev/urandom of=/mnt/usb-boot/key.file bs=512 count=1 Here, I'll split the teps in two sections:Section 1 will describe hard disk encryption with dm-crypt + LUKS.Section 2 will describe hard disk encryption with dm-crypt in plain mode and will go to Part 4 of the article.At this point, we say bye-bye to all wide spread tutorials on the Internet, as they suggest first creating partitions on a hard disk, and then formatting them for encryption. Conversely, we'll first prepare the disk for encryption and only then format it.The reason is simple: in the first case, the partition table remains unencrypted. So how could it be full disk encryption? The flip side of the coin – the variant described in this article is a bit more complicated.
1. DM_CRYPT + LUKS
Step 4. Format hard diskI'll use AES-XTS (with 256 bits key) cipher, which is designed specifically for block devices.First, we need to format hard disk for encryption with LUKS.# cryptsetup -c aes-xts-plain -s 512 -h sha512 -d /mnt/usb-boot/key.file luksFormat /dev/sdaPlease note: I'll use 256-bit key, but then I specify 512-bit key size with -s 512 option. This is because AES-XTS uses two different cipher keys, which it gets by splitting provided key in two halves.From now on /dev/sda device, which we're all familiar with, will not be usable. We'll need to open it, to use it further (decrypt):# cryptsetup -d /mnt/usb-boot/key.file luksOpen /dev/sda sdaThe above command will create a new device mapper node /dev/mapper/sda. What tutorials on the Internet don't say (probably because it's considered obvious) is that it's a symlink to /dev/dm-0 dm-crypt device. This will become important later, when creating initramfs.Now, format the hard disk with a file system of choice:# mkfs.ext2 /dev/mapper/sdaI'm not describing how to create swap, which must be encrypted as well. Actually, I don't use swap on my notebooks in real life. If you need swap and hibernate/resume, then this is for you to investigate. Tip: use swap file, not partition.Done!
Step 5.1 Install Linux distribution of your choiceMount the device# mkdir /mnt/chroot# mount /dev/mapper/sda1 /mnt/chrootAnd, install the Linux distribution of your choice. At this point, you should be familiar with how to install Linux distribution from chroot. Or, if you backed up your existing Linux configuration at step 0, this is the right time to restore it. WHAT TO DO IF NEED TO SHUT DOWN TO CONTINUE LATERIf you would like to stop at some point after this step and shut the system down to continue later, you 'll need to decrypt and open hard disk mapping again before you can continue.Below are the steps how to do it:1. Open LUKS device:# cryptsetup -d /mnt/usb-boot/key.file luksOpen /dev/sda sda2. This is important! luksOpen only creates a device mapping. It's like hot plugging a new hard disk to your system – in order to access partitions on it, you should first discover them and notify kernel. This can be done by various tools like partprobe, hdparm, blockdev, kpartx, etc.# partprobe /dev/mapper/sdaor# kpartx -u /dev/mapper/sda/dev/mapper/sda1, which is a symlink to /dev/dm-1, will appear in the system on success.Now, you can mount the partition, chroot to the system which is being installed, and proceed.
That's it for this part . The most exciting part awaits you next: we'll create initramfs!