Auto mount encrypted drives, using 1Password and systemd

How I automatically mount the encrypted RAID array for my home server at boot time, using 1Password and systemd.
3 min read

Background & Motivation

I have a home server that I use for various things, such as my power usage, file storage, etc. It currently has a RAID1 array of two drives, although this will likely get upgraded in the near future. At the moment, I have the drives encrypted using LUKS, and I use 1Password to store the password for the drives. This is a guide on how I automatically mount the drives on boot.

I did an original post on this back in 2019, and I’ve since totally replaced the hardware and moved to a new set of drives on a new system. I’ll likely do a refresh of that post in the near future when I upgrade the drives.

Within the new system, I have LVM and LUKs on top of the RAID1 software array. The layout looks like this:

sda
└─sda1                         linux_raid_member 1.2
  └─md0                        crypto_LUKS       2
    └─crypt1                   LVM2_member       LVM2 001
      └─cryptvg-raidlv         ext4              1.0      datastore /mnt/raid1

The order I’m using is RAID > LUKS > LVM > FILESYSTEM. This ensures all data is encrypted. Since the encryption is nested inside of the RAID array, the system only needs to encrypt the contents once. If I recall correctly, I used this StackOverflow post as a basis for that decision.

Additional notes

I’m using 1Password here, but you could replace it with any other password manager or anything you can fetch using a shell script. Some additional notes - this server’s using Ubuntu, not Debian as in my original setup.

In some of the below commands, these are the paths and names I’m using. You’ll need to adjust these to match your setup.

The drives are /dev/sda and /dev/sdb, and the RAID array is /dev/md/beast.local:0. The LVM volume group is cryptvg, and the logical volume is raidlv. The mount point is /mnt/raid1.

The commands and scripts below are provided as-is, and you should understand what they do before running them. I make every effort to ensure content in this site is up to date, however I’m not responsible for any data loss or other issues that may arise from running or basing your setup on this guide.

1Password Setup

Create a new service account in 1Password, and give it access to the vault where the password is stored. I’d recommend creating a new vault to scope access to just the password for the drives. From there, you can copy the secret reference by right clicking on the a password and selecting

copy secret ref

Systemd Unit

[Unit]
Description=Mount Raid Crypt
# wait for network to be online, 1password needs this to be available
Wants=network-online.target
After=network.target network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
User=root
ExecStart=/bin/bash /root/mount-raid-crypt.sh
ExecStop=/bin/bash /root/unmount-raid-crypt.sh

[Install]
WantedBy=multi-user.target

The unmount script doesn’t do anything yet, since it’s not really needed for my use case. While it can unmount the drives there’s a plethora of services using it which would also need.

Mount Script

This can be anywhere, but since we’re running as root, I recommend securing it so only root can edit it.

This is called from the systemd unit, and is responsible for mounting the drives and unlocking the LUKS volume.

#!/bin/bash

# exit if anything fails
set -e

# set the 1password vault path
OP_VAULT_PATH="op://VAULT_NAME/ITEM_PATH"

# load service account token from token file
export OP_SERVICE_ACCOUNT_TOKEN="$(cat /home/rich/.1password_token)"

# open encrypted disk
echo "reading password and unlocking disk..."
op read "$OP_VAULT_PATH" | sudo cryptsetup luksOpen /dev/md/beast.local:0 crypt1

# scan for volumes
echo "updating filesystem nodes..."
vgscan --mknodes
vgchange -ay

# mount raid array
echo "mount the drive /mnt/raid1"
mount /dev/mapper/cryptvg-raidlv /mnt/raid1

Installing & Enabling the systemd unit

# copy the systemd unit to the correct location
sudo cp mount-raid-crypt.service /etc/systemd/system/mount-raid-crypt.service

# reload systemd
sudo systemctl daemon-reload

# enable and start the service
sudo systemctl enable mount-raid-crypt.service
sudo systemctl start mount-raid-crypt.service

At this point, the drives should be mounted. You can check the status of the service with systemctl status mount-raid-crypt.service. If you already mounted the drives manually, you might need to close them or reboot the system to test.

Security

This provides a good balance of security and convenience. The password for the disk encryption is stored in 1Password, and only a 1Password service account token is stored on-disk. This token can be quickly revoked if needed without physical access to the machine.

Subscribe to my Newsletter

Like this post? Subscribe to get notified for future posts like this.

Change Log

  • 7/14/2024 - Initial Revision

Found a typo or technical problem? file an issue!