Introduction #
Encrypting data at rest ensures that even if your hardware is stolen or seized, the data remains inaccessible without the decryption key.
This approach enhances your security posture by ensuring that the key is not stored on the same server as the encrypted data.
Overview of the Remote Key Approach #
With this solution, your LUKS-encrypted volume’s decryption key is:
- Stored on a remote host (e.g., your laptop) running Docker.
- Transferred securely over Tor using SSH.
- Immediately shredded from the server after use.
This ensures the key is not persistently available on the server. If the server is compromised while powered off, the encrypted data cannot be accessed without the remote key server.
Note: If the encrypted volume is already mounted when the server is compromised, the data remains accessible in plaintext. Encryption at rest only protects data when the system is powered off or the volume is not mounted.
Prerequisite: Generating a Dedicated SSH Key Pair #
To set up the remote key-fetching process, generate a dedicated SSH key pair for secure communication between the LUKS server and the remote key host:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_auto -N ""
Upload the public key to the remote host’s authorized_keys
file:
ssh-copy-id -i ~/.ssh/id_ed25519_auto [email protected]
Ensure the authorized_keys
file is properly set up on the Docker container running the SSH server.
Setting Up the Remote Key Storage #
The remote host (e.g., your laptop) serves as the storage for the decryption key. Use Docker and Docker Compose to set up a Tor hidden service and an SSH server.
Example docker-compose.yml
#
services:
tor-service:
build: ./tor
networks:
- luks_key
volumes:
- type: bind
source: ./tor/var/lib/tor
target: /var/lib/tor
- type: bind
source: ./tor/etc/tor
target: /etc/tor
depends_on:
- openssh-server
restart: unless-stopped
openssh-server:
image: lscr.io/linuxserver/openssh-server@sha256:64285af57fd5f5d8d88c8b52ab91e4cba330199adcd6ae9b52eec811a2c9eb68
hostname: openssh-server
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- SUDO_ACCESS=false
- PASSWORD_ACCESS=false
- USER_NAME=luks
- LOG_STDOUT=true
networks:
- luks_key
volumes:
- ./conf/data/ssh:/config
ports:
- 2222:2222
restart: unless-stopped
networks:
luks_key:
driver: bridge
After starting the services with docker-compose up -d
, find the Tor hostname in ./tor/var/lib/tor/ssh/hostname
.
Setting Up the Server-Side Auto-Mount #
SSH Configuration #
On the server with the LUKS-encrypted volume, configure SSH to use Tor for connecting to the remote host. Update ~/.ssh/config
:
Host *
Compression yes
# Tunneling .onion connections over Tor
Host *.onion
ProxyCommand torsocks nc %h %p
# Map the .onion address to the remote key server
Host theremotehost.onion
User luks
IdentityFile ~/.ssh/id_ed25519_auto
Install torsocks
if it’s not already available on your system.
Auto-Mount Script #
Create a script ($HOME/bin/mount_data-tor.sh
) to automate the key-fetching and volume-mounting process:
#!/bin/bash
SSH_USER="luks"
SSH_REMOTE="theremotehost.onion"
ENCRYPTED_DEV="/dev/nvme0n1"
MOUNT_POINT="/data"
KEY_FILE_UUID="0b2c2c46-f990-4abd-b09b-f3ae41ece6ae"
KEY_FILE="$KEY_FILE_UUID.lek"
# Wait for network
for i in {1..30}
do
if ping -qc1 ping.sunet.se > /dev/null 2>&1; then
break
else
sleep 1
fi
done
# Fetch key, unlock volume, and mount filesystem
scp ${SSH_USER}@${SSH_REMOTE}:${KEY_FILE} . && sudo cryptsetup luksOpen "${ENCRYPTED_DEV}" "${KEY_FILE_UUID}" --key-file "./${KEY_FILE}" && sudo mount -o compress=zstd,autodefrag,space_cache=v2,noatime "/dev/mapper/${KEY_FILE_UUID}" "${MOUNT_POINT}" && shred -f "./${KEY_FILE}" || shred -f "./${KEY_FILE}"
Make the script executable:
chmod +x $HOME/bin/mount_data-tor.sh
Automating the Script #
Schedule the script to run on boot using crontab
:
@reboot /home/username/bin/mount_data-tor.sh
Alternatively, use a systemd service for finer control.
Dependencies #
Ensure the following tools and dependencies are installed on the server:
ssh
andscp
torsocks
cryptsetup
shred
ping
(for network readiness checks)
Security Considerations #
-
Key Storage
Ensure the private SSH key on the server is stored securely, ideally in an encrypted partition or another secure location. -
Availability Risks
If the remote key host is unavailable (e.g., powered off or unreachable), the server cannot mount the encrypted volume. This is a deliberate security feature but requires operational awareness. -
Logs and Monitoring
Monitor SSH and Tor logs for unauthorized access attempts. -
Fallback Options
Retain at least one other LUKS key slot with a manual passphrase for emergencies.
Conclusion #
By storing the LUKS decryption key on a remote host and fetching it securely over Tor, you can significantly enhance the security of your encrypted disks. This method ensures that your data remains protected even if the storage server is compromised, as long as the remote host is secure.