Setup: I'm using a raspberry pi with a USB HDD, running arch linux and syncthing for my own "cloud" sync.

Problem: In case of a physical break-in where the HDD pi and HDD is stolen, I'd like to ensure that the files on the HDD remain confidential.

Current, high level idea: Encrypt HDD, store key on webserver. On boot, download key, decrypt and mount. Don't store key on HDD/SD card. In case of theft, stop serving key from webserver.

Question: How to go about implementing this?

(Can crypttab solve this? Is writing my own systemd units the way to go? Any other ideas, or maybe even solution are welcome)


The easiest way to set this up would be to have a cleartext system partition (on the SD card, I presume) and an encrypted data partition. Use dmcrypt to encrypt the data partition, with a key stored in a key file that's downloaded from the server.

First set up the server infrastructure, then download the key file and create the encrypted volume with cryptsetup luksFormat /dev/sdb1 /run/data.keyfile or add the key to the existing volume with cryptsetup luksAddKey /dev/mapper/encrypted /run/data.keyfile. Note that you can arrange for the volume to be unlocked with either a passphrase or a key file, which may be convenient for administration (you can type the passphrase even if the server is not available).

The key file doesn't have to be in any particular format. Just generate some random bytes on the server; 16 bytes is plenty (anything more won't give you better security, but anything less won't give you better performance): </dev/urandom head -c 16 >pi.keyfile.

Serve the key with HTTPS to avoid it being snooped. If you don't have a certificate that's validated by a CA, create your own and add it to /etc/ssl/certs, or pass it to the download command (wget --ca-certificate /etc/local/my.cert or curl --cacert /etc/local/my.cert).

You need to download the key before activating the encrypting volume. You can do that in one step with one of

wget -nv -O - https://myserver.example.com/pi.keyfile | cryptsetup luksOpen /dev/sdb1 --key-file /dev/stdin
curl https://myserver.example.com/pi.keyfile | cryptsetup luksOpen /dev/sdb1 --key-file /dev/stdin

or you can download the key to a temporary file, then activate the volume, and finally (not necessary, but may slightly improve security) remove the temporary file. The natural place for this temporary file is in /run, which is in RAM and writable only by root (don't download the key to persistent storage). You should make the file readable only by root (you can set umask 700 before downloading to arrange that), although it only matters if you don't control all the code that runs at boot time.

If you download the key to a temporary file, you can put the keyfile in /etc/crypttab, and add a systemd unit to download the keyfile that runs before the one that activates encrypted volume (but after the network is available) and another unit to remove the keyfile afterwards. Putting wget … | cryptsetup … in /etc/rc.local looks easier to set up.

You'll probably want to authenticate the client when it downloads the key. The authentication token will have to be stored in cleartext on the Pi. You can use an SSL client certificate:

curl --cert /etc/keyfile.cert https://myserver.example.com/pi.keyfile
wget --certificate /etc/keyfile.cert https://myserver.example.com/pi.keyfile

or a password with HTTP basic authentication, stored in /root/.netrc:

curl -n --user=pi https://myserver.example.com/pi.keyfile
wget --user=pi /etc/keyfile.cert https://myserver.example.com/pi.keyfile

Configuring basic authentication is perhaps easier to set up on the server side. Use a randomly-generated password with no special characters (e.g. </dev/urandom | head -c 16 | base64).

Note that whatever you do, someone who steals the Pi will get the password and will be able to download the key if you don't block it first on the sender side. Also, someone who gets physical access to the Pi can quickly pull out the SD card, make a copy, and insert it back; if you don't monitor anything other than uptime, this will look like a power failure. There's no way to completely protect against that. You can put the key in a smartcard, which would prevent the attacker from duplicating it, but not from stealing the smartcard or using it on the spot to download the key file.

Once again, you cannot protect against someone with physical access quickly downloading the key file, then stealing the disk and decrypting it at their leisure. If you want to protect against that, you need to look into tamper-resistant hardware, which is in a different price range.

  • Great input! Thanks. I find the limitations to the security acceptable - I simply wanna avoid petty thieves running through my stuff, I don't asume I can't really put up anything if someone really wants my data.. Will get back with results. – kidmose Sep 27 '15 at 0:00
  • 3
    @kidmose: Don't thank Gilles! ;-) If you like the answer, just click the little grey under the abysmally low number now turning it into beautiful green. If you do not like the answer, click on the little grey down-arrow below the 0, and if you really like the answer, click on the little grey checkmark and the little up-arrow... If you have any further questions, just ask another one! – Fabby Sep 28 '15 at 22:18

I have addressed the same problem using a slightly different solution: because I was using ZoL, I preferred to use EcryptFS. Also, as I wanted the key to be accessible, I stored it encrypted... in a file exchange service (e.g., Dropobox). Then, the proceeding is:

a) A systemd unit connects to the file exchange service, downloads the key and 
   decrypts it.
b) The dependent systemd units wait until the previous has finished and then use 
   the decrypted key to mount the file systems.
c) I have a service that monitors a box switch, so if the server box is opened I 
   receive an alert via pushbullet and the key is deleted from dropbox.

The idea is that when either the physical integrity of the server is compromised, the server is stolen, etc., the key is deleted from dropbox and the data becomes unreadable.

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.