Skip to content

Download dmcrypt (cryptsetup) encryption key from remote server and auto mount

One of the inconveniences of encryption is the need to open the encrypted volume by hand when the computer/server boots. Luckily, you can easily automate that securely. You need a machine that will act as a key server, whether that’s a Raspberry Pi or some VPS you hire.

Take a server that will act as a key server and create a passwordless user:

adduser --disabled-password cryptsetupkeys
su - cryptsetupkeys
mkdir keys
chmod go-rwx keys

We’re going to use ~/.ssh/authorized_keys to give access to the key to one public key, and only from one IP (to prevent someone stealing your computer from also auto-unlocking it):

from="2a01:1b0:5256:1:2:3:4:5",command="/usr/local/bin/catkey.sh keys/server1.key" ssh-rsa AAA...vJxw== root@server1
from="1.2.3.4",command="/usr/local/bin/catkey.sh keys/server2.key" ssh-rsa AAA...vJxw== root@server2

The /usr/local/bin/catkey.sh can be:

#!/bin/bash
#
# Script to be used as only permitted command to echo the key
# data for cryptsetup encrypted partitions. 
# 
# from="1.2.3.4",command="/usr/local/bin/catkey.sh keys/server1.key" ssh-rsa AAA...vJxw== root@server2
#
# http://blog.bigsmoke.us/2016/05/22/download-dmcrypt-cryptsetup-encryption-key-from-remote-server-and-auto-mount
 
keyname="$1"
keyfile="$HOME/$keyname"
hostname="$(hostname)"
mailto="you@example.com"
mailfrom="Autokeydecryptor <you@example.com>"
subject="Cryptsetup key access for '$keyname', '$USER' on '$hostname'"
 
if [ -z "$keyname" ]; then
  message="key name not specified"
  echo "$message"
  echo "$message" | mail -a "From: $mailfrom" -s "$subject" "$mailto"
  exit 1
fi
 
if [ ! -f "$keyfile" ]; then
  message="$keyfile not found or is not a regular file"
  echo "$message"
  echo "$message" | mail -a "From: $mailfrom" -s "$subject" "$mailto"
  exit 1
fi
 
cat -- "$keyname"
message="This is an audit of the access to cryptsetup keys on server '$hostname', account '${USER}', key '$keyname'. This should normally only happen on boot of the server which has the cryptsetup partition."
echo "$message" | mail -a "From: $mailfrom" -s "$subject" "$mailto"

Then on the machine that has the encrypted volume, put the following in something like /etc/rc.local:

ssh -4 -o PasswordAuthentication=no "cryptsetupkeys@server.example.com" "dummy" | cryptsetup --key-file - luksOpen /dev/raidvg/mainencrypted maindecrypted
# put the proper entry in /etc/fstab so this mount works
mount /mnt/decryptedvolume

Or better yet put that in a separate script to be called from /etc/rc.local, because /etc/rc.local often has -e in the shebang, so it would stop on any error in that script, possibly failing to execute your command. Why that -e is there is a mystery to me, but that’s another story.

The less obvious flags explained:

  • -4 is to make sure the from clause will always work, also if your ISP suddenly gives you IPv6.
  • -o PasswordAuthentication=no is necessary to be sure the command fails if the login fails. Otherwise, should your IP address change, the command may hang on password input (if it’s not smart enough to detect a non-interactive terminal).

    No Comments ( Add comment / trackback )