Your Headless Box Just Asked for a Passphrase. At 3 AM. After a Power Outage.
You encrypted the boot drive. Good call: you’re not a monster. But now your NAS/media server/build box won’t come back up after an unexpected reboot unless you’re physically there typing a 30-character passphrase into a console that’s buried behind a rack panel.
This is the classic homelab LUKS trap. The encryption is doing exactly what it’s supposed to do, and it’s completely inconvenient.
There’s a proper solution to this that doesn’t involve disabling encryption, taping a passphrase to the front of the chassis, or storing keys in plaintext on a USB stick you’ll lose inside a couch cushion.
It’s called Network-Bound Disk Encryption (NBDE). The tools are Tang (the key server) and Clevis (the client-side unlock agent). Your disks unlock automatically when your box can reach the Tang server on your trusted network. Take the hardware offline (physically steal the drive, unplug it, carry it to Starbucks) and it stays locked.
No key escrow. No passphrase in memory. No cloud service holding your keys. Just a small server on your LAN acting as a cryptographic witness.
How It Actually Works
Tang uses the McCallum-Relyea exchange (specifically, elliptic curve Diffie-Hellman, or ECDH). The key point: Tang never sees your LUKS passphrase, and it never stores one.
The flow at bind time:
- Clevis generates an ephemeral key pair
- Clevis uses Tang’s public key to derive a LUKS-unlocking key
- That derived key is stored in a LUKS key slot on the disk
- Tang only knows its own key pair: nothing about your disk
At boot time:
- Clevis (running from initramfs) contacts Tang
- Tang responds with its public key (no auth required; that’s fine because security comes from the crypto)
- Clevis re-derives the LUKS key and unlocks the drive
- Boot continues, you never type anything
If Tang is unreachable? The derivation fails. The disk stays locked. That’s the entire threat model.
Set Up the Tang Server
You can run Tang as a container or as a bare systemd socket unit. Docker Compose is cleaner for homelab use.
services: tang: image: latchset/tang:latest restart: unless-stopped ports: - "7500:80" volumes: - tang-keys:/var/db/tang
volumes: tang-keys:docker compose up -dTang generates its signing keys the first time it starts and stores them in the volume. That’s it. No config files, no database, no TLS required (the protocol doesn’t need it; the crypto handles authenticity).
If you prefer a bare-metal approach, on Fedora/RHEL:
dnf install tangsystemctl enable --now tangd.socketBy default it listens on port 80. Adjust with systemctl edit tangd.socket if you want a different port.
Either way, note your Tang server’s IP or hostname: you’ll need it on the client side.
Verify Tang Is Alive
curl http://tang-server-ip:7500/advYou should get a JSON blob with the server’s advertisement keys. If you get a 200 and some JSON, Tang is working. If you get nothing, check your firewall and that the container/socket is actually running.
Bind a LUKS Volume with Clevis
On the client machine (the box whose disk you want to auto-unlock), install Clevis:
# Fedora/RHELdnf install clevis clevis-luks clevis-dracut
# Debian/Ubuntuapt install clevis clevis-luks clevis-initramfsNow bind the LUKS partition to Tang. Replace /dev/sda2 with your actual encrypted partition (check with lsblk or blkid):
clevis luks bind -d /dev/sda2 tang '{"url":"http://tang-server-ip:7500"}'Clevis will:
- Fetch Tang’s advertisement
- Ask you to confirm the Tang server’s thumbprint (verify this matches
tang-show-keyson the server) - Prompt for your existing LUKS passphrase to authorize the new key slot
- Write the Clevis metadata into a LUKS token slot
You can verify the binding worked:
clevis luks list -d /dev/sda21: tang '{"url":"http://tang-server-ip:7500","thp":"..."}'Good. The disk now has a Tang-derived key in addition to your manual passphrase. Don’t delete the passphrase yet; keep it as a fallback until you’ve confirmed auto-unlock works through a real reboot.
Regenerate Dracut (Critical Step)
The unlock has to happen in the initramfs, before the root filesystem is even mounted. That means you need to bake Clevis into the initrd.
# Fedora/RHELdracut -fv --regenerate-all
# Debian/Ubuntu (equivalent)update-initramfs -u -k allThis adds the clevis-dracut hooks that make the unlock happen at early boot. Skip this step and you’ll reboot into a passphrase prompt wondering why nothing changed.
Test It
Reboot. Watch the boot sequence. If Tang is reachable on your network, the drive should unlock automatically and boot continue without any prompt.
If it gets stuck at a passphrase prompt:
- Check that Tang is actually up and reachable from the initramfs network
- Make sure dracut/initramfs was regenerated after binding
- Check
journalctl -b -u clevis-luks-askpass.pathand similar units for errors - The initramfs may need network before it attempts unlock; verify with
rd.neednet=1in your kernel cmdline if you’re using dracut on a system where the network stack isn’t forced up early
Once you’ve confirmed auto-unlock works through two clean reboots, you can optionally remove the manual LUKS passphrase slot (but honestly, keep it; you want a fallback if Tang dies or you’re doing maintenance).
Multi-Tang Policies: 2-of-3 Key Servers
One Tang server is a single point of failure. If it’s down, your box won’t boot. For production homelab use, run multiple Tang instances and use Clevis’s policy engine to require N-of-M.
clevis luks bind -d /dev/sda2 sss \ '{"t":2,"pins":{"tang":[{"url":"http://tang1:7500"},{"url":"http://tang2:7500"},{"url":"http://tang3:7500"}]}}'The sss pin is Shamir’s Secret Sharing. "t":2 means 2 of the 3 Tang servers must respond to unlock. This gives you:
- Redundancy: one Tang server down doesn’t brick your box
- Still secure: an attacker would need to compromise 2 of your 3 Tang servers and have physical access to the disk
Run your Tang instances on separate machines, separate VLANs if you’re paranoid. Three Raspberry Pis on your home network is fine.
Threat Model: Where This Works and Where It Doesn’t
Physical theft: Someone walks off with your NAS drives. They’re offline, Tang is unreachable, drives stay locked. This is the primary use case and it works perfectly.
Network attacker: Someone on your LAN sniffing traffic. Tang’s responses are public (it’s designed that way), but the attacker still needs the LUKS metadata from the disk itself to do anything with Tang’s public key. Disk + network access together is a problem, but that’s a compromised network situation, not just eavesdropping.
Compromised Tang server: If an attacker roots your Tang server, they can answer unlock requests. They still need the disk. Combined disk + Tang compromise is bad, but that’s a whole different threat level than “someone grabbed a drive.”
Laptop at a coffee shop: Tang NBDE is specifically wrong for this. You’re on an untrusted network, Tang isn’t reachable, and the disk stays locked, but that’s actually correct behavior. The failure mode here is you can’t unlock your own laptop when you’re traveling. NBDE is for fixed infrastructure, not roaming devices. For laptops, TPM-based unlock (or TPM+PIN) is the right answer.
TPM vs. Tang: Pick Your Unlock Strategy
| TPM-based | Tang (NBDE) | TPM + Tang | |
|---|---|---|---|
| Requires network | No | Yes | Yes (Tang part) |
| Protects against disk theft | Yes | Yes | Yes |
| Protects against local attacker with disk | Depends on PCR config | Yes (needs Tang) | Yes |
| Good for laptops | Yes | No | Partial |
| Good for headless servers | Yes | Yes | Best of both |
| Key escrow needed | No | No | No |
TPM-based unlock (via systemd-cryptenroll or clevis-tpm2) binds the LUKS key to the machine’s TPM state: specific boot measurements (PCR values). If someone yanks the drive and puts it in another machine, it won’t unlock. But if they compromise the running system, all bets are off.
Tang doesn’t care about TPM state; it cares about network reachability. Stolen drive without network access = locked. Running system = already unlocked.
TPM + Tang together is the paranoid-but-reasonable hybrid. Both conditions must be true to unlock: correct TPM state (right machine, right boot chain) AND Tang reachable (trusted network). Either alone is insufficient.
Bind both with Clevis SSS:
clevis luks bind -d /dev/sda2 sss \ '{"t":2,"pins":{"tpm2":{},"tang":{"url":"http://tang-server:7500"}}}'Now unlocking requires the original machine and network access. Your 2 AM self might appreciate the belt-and-suspenders approach.
Key Rotation
Tang keys don’t last forever; you should rotate them periodically, or immediately if you suspect compromise. On the Tang server:
# List current keysls /var/db/tang/
# Generate new signing key (Tang auto-discovers new keys in the db dir)jose jwk gen -i '{"alg":"ES512"}' > /var/db/tang/new-signing.jwkjose jwk gen -i '{"alg":"ECMR"}' > /var/db/tang/new-exchange.jwk
# Disable (but don't delete yet) old keys by renaming with leading dotmv /var/db/tang/old-key.jwk /var/db/tang/.old-key.jwkAfter rotating, re-bind your clients before deleting the old keys. If you delete first, existing bound disks can’t unlock (the key they were bound to is gone).
Client re-bind:
# Remove old Tang bindingclevis luks unbind -d /dev/sda2 -s 1
# Re-bind with new keyclevis luks bind -d /dev/sda2 tang '{"url":"http://tang-server:7500"}'
# Regenerate initramfsdracut -fv --regenerate-allQuick Operational Checklist
Before you commit to NBDE-only unlock on a production headless box:
- Tang server is on a reliable host (not the same box you’re unlocking; that’s circular)
- At least two Tang instances if uptime matters
- Initramfs regenerated after every bind change
- Fallback LUKS passphrase documented somewhere secure (password manager, printed and locked away; not on the same network)
- Test by actually pulling network during boot and confirming it falls back gracefully
- Monitor Tang with something lightweight; if it silently dies, your next reboot becomes a manual intervention
The whole point is reducing operational toil without reducing security. Tang + Clevis does that well for fixed infrastructure. Set it up once, test it twice, and then forget about it until you’re glad it exists, which will be the first time a drive shows up in a different city.
Wrapping Up
LUKS encryption on headless servers is non-negotiable if you care about physical security. But LUKS + manual passphrase on a server that reboots at 3 AM after a power glitch is just pain.
Tang + Clevis gives you the security property you actually want: disks locked unless the hardware is on your trusted network, without key escrow, without cloud dependencies, without a USB stick duct-taped to the chassis.
Set up a Tang container. Bind your LUKS volumes. Regenerate dracut. Test it. Sleep better.
Your 2 AM self, staring at a disk unlock prompt through a KVM-over-IP console they forgot to set up, will wish they’d done this last weekend.