Skip to content
Go back

Tang & Clevis: LUKS Auto-Unlock Without a Typed Passphrase

By SumGuy 10 min read
Tang & Clevis: LUKS Auto-Unlock Without a Typed Passphrase
Contents

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:

  1. Clevis generates an ephemeral key pair
  2. Clevis uses Tang’s public key to derive a LUKS-unlocking key
  3. That derived key is stored in a LUKS key slot on the disk
  4. Tang only knows its own key pair: nothing about your disk

At boot time:

  1. Clevis (running from initramfs) contacts Tang
  2. Tang responds with its public key (no auth required; that’s fine because security comes from the crypto)
  3. Clevis re-derives the LUKS key and unlocks the drive
  4. 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.

docker-compose.yml
services:
tang:
image: latchset/tang:latest
restart: unless-stopped
ports:
- "7500:80"
volumes:
- tang-keys:/var/db/tang
volumes:
tang-keys:
Terminal window
docker compose up -d

Tang 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:

Terminal window
dnf install tang
systemctl enable --now tangd.socket

By 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

Terminal window
curl http://tang-server-ip:7500/adv

You 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:

Terminal window
# Fedora/RHEL
dnf install clevis clevis-luks clevis-dracut
# Debian/Ubuntu
apt install clevis clevis-luks clevis-initramfs

Now bind the LUKS partition to Tang. Replace /dev/sda2 with your actual encrypted partition (check with lsblk or blkid):

Terminal window
clevis luks bind -d /dev/sda2 tang '{"url":"http://tang-server-ip:7500"}'

Clevis will:

  1. Fetch Tang’s advertisement
  2. Ask you to confirm the Tang server’s thumbprint (verify this matches tang-show-keys on the server)
  3. Prompt for your existing LUKS passphrase to authorize the new key slot
  4. Write the Clevis metadata into a LUKS token slot

You can verify the binding worked:

Terminal window
clevis luks list -d /dev/sda2
1: 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.

Terminal window
# Fedora/RHEL
dracut -fv --regenerate-all
# Debian/Ubuntu (equivalent)
update-initramfs -u -k all

This 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:

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.

Terminal window
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:

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-basedTang (NBDE)TPM + Tang
Requires networkNoYesYes (Tang part)
Protects against disk theftYesYesYes
Protects against local attacker with diskDepends on PCR configYes (needs Tang)Yes
Good for laptopsYesNoPartial
Good for headless serversYesYesBest of both
Key escrow neededNoNoNo

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:

Terminal window
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:

Terminal window
# List current keys
ls /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.jwk
jose jwk gen -i '{"alg":"ECMR"}' > /var/db/tang/new-exchange.jwk
# Disable (but don't delete yet) old keys by renaming with leading dot
mv /var/db/tang/old-key.jwk /var/db/tang/.old-key.jwk

After 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:

Terminal window
# Remove old Tang binding
clevis luks unbind -d /dev/sda2 -s 1
# Re-bind with new key
clevis luks bind -d /dev/sda2 tang '{"url":"http://tang-server:7500"}'
# Regenerate initramfs
dracut -fv --regenerate-all

Quick Operational Checklist

Before you commit to NBDE-only unlock on a production headless box:

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.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Next Post
YubiKey + age: Hardware-Backed Encryption Without GPG

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts