Full-disk encryption (FDE) turns the data sitting on your server's storage into unreadable ciphertext whenever the disk is powered down or detached. On a VPS that protects you against the one scenario you cannot firewall away: someone gaining physical access to the underlying disk. This guide covers the threat model, how LUKS works, the remote-unlock problem unique to headless servers, and how to deploy an encrypted ServPrivacy VPS.
The threat model: data at rest
Encryption at rest defends against threats to the stored copy of your data, as opposed to data in transit (TLS) or data in use (RAM). The concrete scenarios it addresses:
- Physical seizure of the host or the drive it lives on.
- Disk decommissioning — drives that are RMA'd, resold, or scrapped without secure erase.
- Backend snapshot or image cloning of the block device while the instance is off.
- A compromised storage layer where an attacker can read raw blocks but not your running memory.
Choosing a privacy-respecting jurisdiction raises the legal bar for seizure, and FDE makes the data worthless even if the disk is physically taken. The two layers complement each other — see why offshore for the jurisdiction side.
How LUKS works
On Linux the standard for FDE is LUKS (Linux Unified Key Setup), implemented through dm-crypt. The model is two-tiered and worth understanding:
- The actual data is encrypted with a randomly generated master key (typically AES-256 in XTS mode).
- That master key is itself encrypted and stored in the LUKS header at the start of the partition, in up to several key slots.
- Each key slot is unlocked by a passphrase or key file. Your passphrase decrypts a slot, which releases the master key, which decrypts the disk.
This indirection is why you can change a passphrase without re-encrypting terabytes of data, and why you can have multiple passphrases for the same volume. The trade-off: if the LUKS header is destroyed, the data is gone permanently — there is no master key to recover. Back the header up.
Typical commands when working with a LUKS volume:
cryptsetup luksFormat /dev/sdX— initialise an encrypted volume.cryptsetup open /dev/sdX cryptroot— unlock it to/dev/mapper/cryptroot.cryptsetup luksHeaderBackup /dev/sdX --header-backup-file hdr.img— back up the header.cryptsetup luksAddKey /dev/sdX— add a second passphrase or key file.
The remote-unlock challenge
Here is the catch that makes FDE on a VPS different from a laptop. After every reboot the encrypted root must be unlocked before the operating system can start — but the OS is where your SSH server lives. On a laptop you simply type the passphrase at the console. On a headless, remote VPS there is no console you can reach, so a normal LUKS setup would hang at boot waiting for a passphrase nobody can enter.
The standard solution is to run a tiny SSH server inside the initramfs — the minimal early-boot environment — so you can connect and supply the passphrase before the real system boots. The tool for this is dropbear-initramfs:
- A lightweight Dropbear SSH daemon is baked into the initramfs with its own host key and your public key.
- At boot, the server brings up the network early and Dropbear listens (commonly on a chosen port).
- You SSH in, run the unlock command (
cryptroot-unlock), enter the passphrase, and the boot continues normally. - Dropbear then shuts down and your normal OpenSSH server takes over.
Some setups use a key file or a network-bound key (Tang/Clevis) to unlock automatically, but that means the unlock secret lives near the server — convenient, weaker. Manual passphrase entry over the initramfs SSH session keeps the secret in your head and off the machine.
Deploying an encrypted ServPrivacy VPS
The simplest path is to let us handle it: LUKS full-disk encryption is an optional add-on at checkout on every VPS and dedicated plan. Select it when you configure the server, complete payment (Monero recommended — see the Monero payment guide and the payments page), and the instance is provisioned with an encrypted root.
If you prefer to build it yourself on a fresh instance, the high-level path with a Debian/Ubuntu installer is:
- During installation, choose guided partitioning with encrypted LVM, or manually create a LUKS container and put the root filesystem inside it.
- Set a strong passphrase — a long, high-entropy phrase, since this is the only thing standing between an attacker and your data.
- After first boot, install the remote-unlock tooling:
apt install dropbear-initramfs. - Add your public key to
/etc/dropbear/initramfs/authorized_keys(use a dedicated key for unlock). - Configure early networking and the Dropbear port in
/etc/dropbear/initramfs/dropbear.conf, then rebuild the image withupdate-initramfs -u. - Reboot, SSH into the initramfs, run
cryptroot-unlock, and confirm the system boots through. - Back up the LUKS header off-server with
luksHeaderBackupand store it somewhere safe.
Trade-offs to weigh
- Every reboot needs you. Unattended reboots (after a kernel update or host maintenance) will pause until you unlock. Plan for that, or accept the convenience/security trade of an auto-unlock key.
- Small performance cost. Modern CPUs have AES-NI hardware acceleration, so the overhead on NVMe storage is typically negligible for most workloads.
- Lose the passphrase, lose the data. There is no backdoor. Use a password manager and back up the header.
- Not a runtime shield. A live, unlocked server with a root compromise is plaintext to the attacker — pair FDE with strong access controls.
Key takeaways
- FDE protects data at rest — seizure, decommissioned disks, offline cloning — not a running, unlocked system.
- LUKS encrypts the disk with a master key wrapped by passphrase-protected key slots stored in the header; back the header up.
- On a headless VPS, use dropbear-initramfs to SSH in at boot and run
cryptroot-unlockbefore the OS starts. - ServPrivacy offers LUKS as a checkout add-on, or you can build it yourself with encrypted LVM plus Dropbear.
- Trade-offs: every reboot needs manual unlock, a small (AES-NI-accelerated) performance cost, and no recovery if the passphrase or header is lost.