This is a little guide (currently under construction) for how I handle encrypted disks on Linux. This won’t be the ultimate ‘tin foil hat’ guide, as the attack vector this is intended to protect from is physical theft of the hardware, so that the data can’t be accessed from elsewhere. It obviously will not handle a targeted hacking attempt or the $5 wrench method, but I believe it gives security and convenience to a level appropriate for me.
The reason this started is because my physical health is deteriorating and getting up to enter a password at the console on every reboot is tiresome. Therefore I came up with a new way of handling encrypted drives to not only increase security but also make things a bit more convenient.
Of course before following any of these instructions, you should be aware of my standard disclaimer.
Caution – You need to secure the location of where you store your key. If you fail to secure your key with an appropriate mechanism, this entire exercise is fruitless.
Examples include: IP restricting access to your key provisioning system, using a strong username and password, using an easy to revoke token based storage mechanism, verifying HTTPs transfer certificates and countless others.
Included below is a method similar to what I use to secure where I store my keys.
Create a keyfile
dd bs=256 count=1 if=/dev/random | base64 > data-keyfile
Upload the keyfile somewhere, for example a HTTPS server with a valid certificate, or S3 or Azure key storage, and then make a script to download the key from where you put it. If you’re storing your key on a HTTPS server, here is an example htaccess file to secure access to the directory to specific IPs and a user/password section to further increase security. This works with Apache 2.4 but the syntax may be different for later versions.
order deny,allow deny from all allow from 192.168.1.100 Options -Indexes AuthType Basic AuthName "Restricted Access" AuthUserFile "/secure/path/to/htpasswd" Require valid-user
Once you have uploaded it somewhere don’t forget to delete the original source file securely from your system (for example with shred).
#!/bin/sh set -e # Request the file from somewhere, maybe blob storage, asure, S3 or HTTPS Server, then pipe it through `base64 -d` to decode it from base64 curl -s --basic --user username:password "https://example.net/data-keyfile" | base64 -d
Then move the script somewhere and give it the right permissions
# Ensure the owner of this file is "root" chown root:root /etc/luks/get-key.sh # Allow only the owner (root) to read and execute the script chmod 0500 /etc/luks/get-key.sh
Create the raid
# if all drives are already blank and ready to be added. Replace drives as appropriate. mdadm --create /dev/md2 -l 1 -n 2 /dev/sdc1 /dev/sdd1 # if you need to create a 'degraded' array with a drive missing. mdadm --create /dev/md2 -l 1 -n 2 /dev/sdc1 missing
Then encrypt the array
# Encrypt the disk # Replace md2 with the correct array! /etc/luks/get-key.sh | cryptsetup -d - -v luksFormat /dev/md2 # Open the encrypted volume, with the name "data" # Replace md2 with the correct array! /etc/luks/get-key.sh | cryptsetup -d - -v luksOpen /dev/md2 data # Create a filesystem on the encrypted volume mkfs.ext4 -F /dev/mapper/data # Close the encrypted volume cryptsetup -v luksClose data
Find the encrypted partitions UUID
$ lsblk --fs NAME FSTYPE LABEL UUID [..] sdc └─sdc1 linux_raid_mem server:1 a38cbabe-0f12-3643-f3232-998822c5d42 └─md2 crypto_LUKS a17db19d-5037-4cbb-b50b-c85e3e074864
Then create a script to run on boot to automount
#!/bin/bash if [ -b "/dev/mapper/data" ] then if [[ $(findmnt -M "/disks/data") ]]; then : else echo "Not mounted but unlocked... trying to mount..." mount -t ext4 -o errors=remount-ro /dev/mapper/data /disks/data fi else curl -s --basic --user username:password "https://example.net/data-keyfile" | base64 -d | /sbin/cryptsetup -d - -v luksOpen /dev/disk/by-uuid/a17db19d-5037-4cbb-b50b-c85e3e074864 data mount -t ext4 -o errors=remount-ro /dev/mapper/data /disks/data fi if [[ $(findmnt -M "/disks/data") ]]; then # Anything you want to run after the disks are mounted echo "All disks mounted, starting services..." echo "Starting samba..." systemctl start smbd fi
and add it to root’s crontab on reboot.
# m h dom mon dow command @reboot sleep 30 && /etc/luks/start-crypto.sh
Don’t forget to disable any services you don’t want to run until the encrypted drives are mounted, for example samba
systemctl disable smbd
Create the mount point
And finally a script to stop encrypted drives (if required)
#!/bin/bash echo "Stopping Samba..." systemctl stop smbd if [[ $(findmnt -M "/disks/data") ]]; then echo "/disks/data is mounted, trying to unmount..." umount /dev/mapper/data echo "Attempting to close luks on /dev/mapper/data ..." if [ -b /dev/mapper/data ] then /sbin/cryptsetup -d - -v luksClose data fi else if [ -b /dev/mapper/data ] then echo "/disks/data is not mounted, but is unlocked, will attempt to close ...." /sbin/cryptsetup -d - -v luksClose data else echo "/disks/data is not unlocked or mounted, nothing to do." fi fi
This work was inspired by an article on https://withblue.ink/2020/01/19/auto-mounting-encrypted-drives-with-a-remote-key-on-linux.html by Alessandro Segala and adapted/changed to meet my requirements.