I’ve been backing up some of my larger files to Bluray lately, instead of trying to upload them over a 10 Mbps uplink.
In the past, I used GPG (on a .tar or compressed .tar.xz) or Veracrypt (on a file container) to encrypt at rest, before burning those files onto a standard UDF/ISO9660 optical disc. Now that I use a Linux desktop, I wanted something slightly more native — a method that
- protects the directory structure and filenames without needing to use an archive file (like .tar);
- would be generally unintelligible on a Windows PC (this is a feature, not a bug); and
- could be scripted on the command line for server backups, without requiring a GUI.
Based on some resources online, I settled on using LUKS.
1. Make an ISO container.
truncate -s 23500M image.iso
2. Set up a loop device.
sudo losetup /dev/loop1 image.iso
(If there has already been a loop device set up, you may have to increment the number.)
3. Format the loop device as a LUKS container.
sudo cryptsetup luksFormat /dev/loop1
4. Create a block device mapping for the LUKS container.
sudo cryptsetup luksOpen /dev/loop1 volume1
This will create a device-mapper block device at /dev/mapper/volume1
(or whatever other argument you gave the command).
5. Make a UDF filesystem on the block device.
You’ll need the mkudffs
executable to run this particular command. (On Fedora, sudo dnf install udftools
.)
sudo mkudffs --label='Give the filesystem a label' /dev/mapper/volume1
In actuality, there’s no need to use the UDF filesystem, since the filesystem isn’t being written raw to the disc — and this encrypted data disc won’t be going into any hardware video players. In theory, mkfs.ext4
could work just as well.
6. Now mount the UDF filesystem.
sudo mkdir /media/datadisc sudo mount -t udf /dev/mapper/volume1 /media/datadisc
To mount with the right permissions for a nonroot user, add the -o uid=XXXX,gid=XXXX
flag on the mount command.
7. Copy any files into the mount point.
8. Safely unmount the UDF filesystem.
sudo umount /dev/mapper/volume1
9. Close up the encrypted LUKS container and clean up the loop device.
sudo cryptsetup luksClose volume1 sudo losetup -d /dev/loop1
10. Burn the ISO file as-is to disc.
A standard way to burn the raw image to the optical disc:
growisofs -dvd-compat -Z /dev/sr0=image.iso
11. Mount the disc through 3 steps.
While your desktop environment may attempt to automatically mount the LUKS-encrypted disc, that seems to fail for some reason related to the readonly nature of the disc. Manual steps on the terminal:
sudo losetup /dev/loop1 /dev/sr0 sudo cryptsetup -r luksOpen /dev/loop1 volume1 sudo mount -t udf -o ro /dev/mapper/volume1 /media/datadisc
To later unmount, the steps in reverse:
sudo umount /dev/mapper/volume1 sudo cryptsetup luksClose volume1 sudo losetup -d /dev/loop1
Yes, since you use LUKS on a predefined size of course there is no benefit in using UDF.
A nice solution would be something like genisoimage with an option to encrypt using LUKS, so that you use only as much bytes as needed for the ISO and then using UDF for that thing.
In theory your solution could also be recognized by Gnome3 keyring and automatically mounted.
Then you would not need 3 manual steps to mount and unmount. With external HDDs and USB flash drives it works. In theory should not make a difference if it is a optical media or not.
The GNOME3 keyring does detect the optical disc and attempts to help with decrypting with LUKS. However, perhaps because the block device is read-only, that integration fails to successfully mount the disc.
Maybe the result is different with another filesystem.
Thanks for writing this up.
To solve the mounting issue, change the filesystem block size to 2048 with
-b 2048
to match the optical media’s sector size. See this post for more details: https://gitlab.com/cryptsetup/cryptsetup/issues/337#note_37678446. I ran into the same issue when using ext4 inside the LUKS container, and indeed, after changing the block size to 2048, mounting works perfectly (even in the GUI) without using an intermediate loop device.Thanks for the tip! I’ll update the blog post after I try it out.
You can use
losetup -f
to get first unused loop device.