Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why LUKS instead of .tar.gpg? #446

Open
koddo opened this issue Jun 14, 2024 · 3 comments
Open

Why LUKS instead of .tar.gpg? #446

koddo opened this issue Jun 14, 2024 · 3 comments

Comments

@koddo
Copy link

koddo commented Jun 14, 2024

Any particular reason? LUKS seems error-prone compared to a single command of encrypting a folder.

Thank you for the guide, by the way.

@drduh
Copy link
Owner

drduh commented Jun 30, 2024

Indeed, one could symmetrically encrypt the private key and backup contents with GPG (though I would still recommend using a different passphrase from identity). The resulting archive would be more portable and convenient to use.

However, portability and convenience of accessing backups is not a goal of this guide and, in a way, LUKS limits portability to encourage use of a secure-ish operating environment. I also suppose the argument could be made that using different encryption programs to secure key material is "better", but in practice this is likely not relevant. In other words, in terms of at-rest encryption protection, LUKS and GPG are likely equivalent.

I'm curious what you mean by LUKS being error-prone. If it truly is a hassle for readers, we could simplify the instructions and move LUKS to Optional Hardening. What do you think? Is there anything else to consider?

@koddo
Copy link
Author

koddo commented Jul 9, 2024

Maybe it's just me, but I never interact with LUKS directly, which means I don't know what all those commands mean, and there's a lot to learn already about gpg and yubikey-manager. Also, by error-prone I mean manipulation of partitions in /dev manually: commands like sudo dd if=/dev/zero of=/dev/sdc bs=4M count=1 seem dangerous for sleep-deprived users, I didn't mess up purely by luck. Everything else is recoverable.

@forbytten
Copy link
Contributor

forbytten commented Nov 21, 2024

Another option may be to use LUKS with a loop device, the latter of which is a file used as a block device, not to be confused with loop-AES, the latter of which seems to be an alternative to LUKs. Using a loop device has similar advantages to the current LUKs steps but has two, IMHO, significant advantages:

  1. Can be safely automated, addressing koddo's concerns. All destructive operations are restricted to a file, not an entire partition or disk. This is the approach I plan to try with the automation scripts I'm currently implementing for my use case.
  2. It's portable. Being able to back up data remotely may be recommended, depending on a user's specific security threat model, as well as their physical environment, such as living in a natural disaster prone region.

Disadvantages:

  1. If a user chooses not to use an ephemeral environment and they forget to delete the encrypted file after copying it to portable devices and/or remote storage, the file may be more vulnerable to exfiltration than the current physical disk based approach but this threat seems minor compared to the advantages and the file is encrypted.
  2. Nothing else obvious or significant that I can think of. However, I have minimal experience with LUKS and loop devices so it would be great if someone more experienced could comment on this approach.

I think this approach can also be used with the OpenBSD equivalent, virtual node devices, but I have not tried it.

Linux Steps

The steps have been tested on Debian Live 12.8.0:

009f482430b8505bba8099aeac3f59eab92ddfa30ae8910d6293f7e198194bad24fa625fcfa38813e6e25b2b7502a542fa04af4e4c2a52376c36162fea8debf7  debian-live-12.8.0-amd64-gnome.iso

user@debian:~$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
IMAGE_ID=live
BUILD_ID=20241109T101058Z

The loop device specific steps are based on the cryptsetup FAQ:

zcat /usr/share/doc/cryptsetup/FAQ.md.gz|grep -A 10 '2.6 How do I use LUKS with a loop-device?'
  * **2.6 How do I use LUKS with a loop-device?**

  This can be very handy for experiments.  Setup is just the same as with
  any block device.  If you want, for example, to use a 100MiB file as
  LUKS container, do something like this:
```
    head -c 100M /dev/zero > luksfile               # create empty file
    losetup /dev/loop0 luksfile                     # map file to /dev/loop0
    cryptsetup luksFormat --type luks2 /dev/loop0   # create LUKS2 container
```
  Afterwards just use /dev/loop0 as a you would use a LUKS partition.

I have marked the new/modified steps with (changed). All the other steps are existing from the guide.

(changed) Choose a name for the encrypted loop device file:

export LUKS_GPG_BACKUP_FILE="gpg_backup_luks"

(changed) Create a small (at least 20 Mb is recommended to account for the LUKS header size) loop device file for storing secret materials:

head -c 20M /dev/zero > "$LUKS_GPG_BACKUP_FILE"

(changed) Associate $LUKS_GPG_BACKUP_FILE with the next available loop device, automatically ensuring the file isn't mapped to multiple loop devices:

sudo losetup -f -L "$LUKS_GPG_BACKUP_FILE"

(changed) Ensure losetup is on non-sudo user PATH, which is needed on some OS's such as Debian Live 12.8.0:

export PATH="/usr/sbin:$PATH"

(changed) Determine what loop device was used:

export LUKS_GPG_BACKUP_LOOP_DEVICE=$(losetup -j "$LUKS_GPG_BACKUP_FILE" |cut -d: -f1)

Generate another unique Passphrase (ideally different from the one used for the Certify key) to protect the encrypted volume:

export LUKS_PASS=$(LC_ALL=C tr -dc 'A-Z1-9' < /dev/urandom | \
  tr -d "1IOS5U" | fold -w 30 | sed "-es/./ /"{1..26..5} | \
  cut -c2- | tr " " "-" | head -1) ; printf "\n$LUKS_PASS\n\n"

This passphrase will also be used infrequently to access the Certify key and should be very strong.

Write the passphrase down or memorize it.

(changed) Format the loop device:

echo $LUKS_PASS | sudo cryptsetup -q luksFormat "$LUKS_GPG_BACKUP_LOOP_DEVICE"

(changed) Mount the loop device

echo $LUKS_PASS | sudo cryptsetup -q luksOpen "$LUKS_GPG_BACKUP_LOOP_DEVICE" gnupg-secrets

Create an ext2 filesystem:

sudo mkfs.ext2 /dev/mapper/gnupg-secrets -L gnupg-$(date +%F)

Mount the filesystem and copy the temporary GnuPG working directory with key materials:

sudo mkdir /mnt/encrypted-storage

sudo mount /dev/mapper/gnupg-secrets /mnt/encrypted-storage

sudo cp -av $GNUPGHOME /mnt/encrypted-storage/

(changed) An example to better visualize the relationship between the underlying file gpg_backup_luks, the loop device and the LUKS container:

user@debian:~$ losetup -l -j gpg_backup_luks
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE                  DIO LOG-SEC
/dev/loop1         0      0         0  0 /home/user/gpg_backup_luks   0     512

user@debian:~$ lsblk -p /dev/loop1
NAME                        MAJ:MIN RM SIZE RO TYPE  MOUNTPOINTS
/dev/loop1                    7:1    0  20M  0 loop
└─/dev/mapper/gnupg-secrets 253:0    0   4M  0 crypt /mnt/encrypted-storage

(changed) Unmount and close the encrypted volume and detach the loop device:

sudo umount /mnt/encrypted-storage

sudo cryptsetup luksClose luksfile

sudo losetup -d "$LUKS_GPG_BACKUP_LOOP_DEVICE"

(changed) Copy $LUKS_GPG_BACKUP_FILE to multiple portable storage devices and potentially remote storage.
(changed) If you are not using an ephemeral OS, delete the local copy.

Signing

I'd also suggest with this approach to also sign the backing file. This would be especially useful if backing up the file to remote storage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants