2

I have several servers each with at least six dm-crypt partitions. I would like to have an automated way to make sure I always have a luks header backup stored in a safe place. I've been making header backups manually until now. My problem with that is that I tend to forget to make a new luks header backup when I have to swap out a hard drive or make other system changes.

I'm looking for an existing script that will check to see if a luks header backup exists, and if not, create one. I have to assume somebody has written such a script already. (The need for it seems obvious.)

If one does not exist, I'll attempt to make a bash script for the purpose.

My manual commands look like this:

cryptsetup luksHeaderBackup /dev/sdXN --header-backup-file /path/to/backup/$mountpoint_luksHeader_$devUUID.img

I would like to have both the mountpoint and the device UUID in the file name of the header image file.

The only clue I have about getting started is that I would need to iterate through all devices and find the partitions of type crypt, then find the corresponding mount point and UUID. I know most of that info exists in lsblk and blkid. I'm not sure how to extract it for use in a script.

EDIT: my goal is to name the files intelligently, based on mount points.

Each crypto_LUKS device contains one or more BTRFS subvolumes. For example, the crypto_LUKS device sysluks contains four btrfs subvolumes which are:

  • @root
  • @var_log
  • @root_snapshots
  • @var_log_snapshots

The command lsblk gives output like this, where only the last of those subvolumes to be mounted is shown as the mountpoint:

NAME         MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINT
sda            8:0    0  1.8T  0 disk  
└─sda2         8:2    0  1.8T  0 part  
└─sysluks  254:0    0  1.8T  0 crypt /var/log/.snapshots

Using /var/log/.snapshots as the name of the file that contains the backup for the root device is not ideal.

The command findmnt -t btrfs will show all mountpoints for a given source (such as /dev/mapper/sysluks). Running a few local tests, findmnt seems to always return a list ordered by mount order at system startup. Picking the first mount point from that list would work for my purposes of naming files, but picking the last, as lsblk does, it never ideal.

  • Did my script work for you? I noticed you let the bounty expire without selecting an answer so I'm curious if there was some error. – SurpriseDog May 31 '19 at 23:58
  • @Benjamin - I'm sorry, I did not see your answer. I got discouraged by the first answer and temporarily gave up. I will try your script and accept your answer if it works. Thank you. – MountainX-for-Monica Jun 2 '19 at 9:31
2
cd  /path/to/backup/
lsblk --fs --output FSTYPE,UUID | grep crypto_LUKS | tr -s ' ' | cut -d ' ' -f2 | \
while read uuid; do 
    mntpoint=$(lsblk /dev/disk/by-uuid/$uuid --output MOUNTPOINT | sed 1,1d | head -n 1)
    name="${mntpoint}_luksHeader_$uuid.img"
    if [[ ! -e "$name" ]]; then     
        cryptsetup luksHeaderBackup /dev/disk/by-uuid/$uuid --header-backup-file $name
    fi
done

Change your path/to/backup and it should be good to go. Just know that if the mountpoint for a device changes it will produce multiple header backups. Otherwise, it will ignore already backed up devices.

  • Thank you. Very useful. One issue is that many crypto_LUKS devices contain multiple BTRFS volumes (such as the root filesystem and separately /var/log or /home). One issue with the script is that lsblk /dev/disk/by-uuid/$uuid only finds the last mountpoint; therefore, the volume that I think of as holding the root filesystem is named by the script using /var/log/ as the mountpoint. Any thoughts on how to obtain the first, rather than the last mountpoint? – MountainX-for-Monica Jun 2 '19 at 9:55
  • mntpoint=$(lsblk /dev/disk/by-uuid/$uuid --output MOUNTPOINT | sed 1,1d | head -n 1) so you can only get the first mountpoint listed for a device – SurpriseDog Jun 3 '19 at 0:23
  • See my edit to the question. It may not be possible to pick the 1st mount point, but if it can be done, the additional information might help clarify my goal. – MountainX-for-Monica Jun 3 '19 at 2:44
0

you could loop a call to this script:

https://github.com/stanclai/luks_backup

and add it to cron.

Some notes/ideas:

  1. if your script does not automate rotation, consider adding the date of the backup to the path: /path/to/backup/$(date +%y%m%d)/$mountpoint_luksHeader_$devUUID.img, preceded by mkdir -p /path/to/backup/$(date +%y%m%d)
  2. /path/to/backup/ shall be on a different volume, preferably on a network location: you don't want to have your backups reside on the same disk/volume/server you are backing up, because in case of failure you will have no access.
  3. In both cases, consider an organic backup system to back up the generated files.

Cheers :)

  • 1
    That script doesn't address my requirements. It does other things that seem useful, but it doesn't do what I need. – MountainX-for-Monica May 10 '19 at 3:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.