TechEarl

Unlock LUKS Remotely Over SSH With Dropbear

Set up LUKS remote unlock over SSH with Dropbear in the initramfs, so an encrypted root server can finish booting after a reboot without a console or KVM.

Ishan Karunaratne⏱️ 12 min readUpdated
Share thisCopied
LUKS remote unlock over SSH with Dropbear: put an SSH server in the initramfs so you can type the disk passphrase remotely and finish booting an encrypted root server.

If your root filesystem is LUKS-encrypted, a remote server cannot finish booting on its own: it sits at the initramfs prompt waiting for someone to type the passphrase. The fix is to put a tiny SSH server (Dropbear) into the initramfs so you can SSH in early in boot and type the passphrase remotely. On Debian and Ubuntu that is one package:

bash
sudo apt install dropbear-initramfs

Add your public key to /etc/dropbear/initramfs/authorized_keys, rebuild the initramfs, and on the next reboot you SSH into the half-booted box, run one command to unlock the disk, and the boot continues. No console, no KVM, no IPMI Java applet. This is the whole job, and below is every step plus the parts that bite people.

If you have not encrypted the disk yet, do that first: encrypt a disk with LUKS and cryptsetup. This article assumes the LUKS volume already exists and is unlocked at boot from a console today.

Why the initramfs needs its own SSH server

The reason a normal sshd does not help here: at the point boot stalls, the root filesystem is still encrypted and not mounted. Your real OpenSSH server, its config, and its host keys all live on that locked disk. Nothing on root is reachable yet.

The initramfs is the small, unencrypted image the bootloader loads into RAM before root exists. It is the one place early enough in boot to run code while the disk is still locked. So the trick is to bake a minimal SSH server (Dropbear, chosen because it is tiny) plus a network stack into that initramfs. You SSH to that, unlock the disk from inside it, and the normal boot, including your real sshd, takes over.

Dropbear is a small SSH server and client written for embedded and memory-constrained environments. That is exactly the initramfs use case: a few hundred KB, no dependency on the encrypted root.

Install and add your key (Debian, Ubuntu)

Install the package, then drop your public key in:

bash
sudo apt install dropbear-initramfs

On current Debian (12 "bookworm" and later) and Ubuntu, the package is dropbear-initramfs, split out from the older monolithic dropbear package. The authorized-keys file lives at:

bash
sudo tee -a /etc/dropbear/initramfs/authorized_keys < ~/.ssh/id_ed25519.pub

This is a separate authorized_keys from your normal user account's. It only governs the early-boot Dropbear, and the only thing you can do once connected is unlock the disk, so keep it to the keys that genuinely need to reboot the box.

If you do not have a keypair yet, create an SSH key first. Use a plain Ed25519 key here; Dropbear has supported it for years. One caveat worth knowing: a FIDO2 hardware key (sk-ssh-ed25519) is not a good fit for the initramfs, because the busybox Dropbear has no ssh-sk middleware to negotiate the security-key challenge. Keep the hardware key for your normal account and use a standard Ed25519 key for early-boot unlock.

Rebuild the initramfs

Nothing you changed takes effect until you regenerate the initramfs image, because the key and the Dropbear binary get copied into it at build time:

bash
sudo update-initramfs -u

-u updates the initramfs for the current kernel. The build hook pulls in Dropbear, your authorized_keys, and the network bits. Confirm the key actually made it in before you trust it with a reboot:

bash
sudo lsinitramfs /boot/initrd.img-$(uname -r) | grep -E 'dropbear|authorized_keys'

You want to see both the Dropbear binary and authorized_keys listed. If authorized_keys is missing, the file was empty or in the wrong path, and you will lock yourself out. On a remote box this is the one mistake with no recovery short of console access, so never reboot until that grep returns both lines. If you can, do the very first reboot with a console or KVM still attached as a safety net.

Give the initramfs an IP address

The early environment has no DHCP client and no network config from your normal setup, so you have to tell it how to bring up networking. This is the step people forget, and the symptom is an SSH connection that just times out at boot.

You configure it with the kernel ip= boot parameter. The simplest reliable form is static:

bash
ip=192.0.2.10::192.0.2.1:255.255.255.0:myhost:eth0:off

The fields, in order, are: client IP, NFS/boot-server IP (left blank here, which is why you see the doubled ::), gateway, netmask, hostname, interface, and autoconf (off for static, dhcp to ask a DHCP server). Add it to GRUB_CMDLINE_LINUX in /etc/default/grub:

bash
GRUB_CMDLINE_LINUX="ip=192.0.2.10::192.0.2.1:255.255.255.0:myhost:eth0:off"

Then regenerate GRUB and the initramfs:

bash
sudo update-grub && sudo update-initramfs -u

Two real-world snags. First, the interface name: the initramfs may not run the same predictable-naming rules as your booted system, so a NIC that is enp1s0 once booted can be eth0 in early boot. If SSH times out, the wrong interface name is the first suspect. Second, dhcp works but it makes boot depend on a DHCP lease being granted in a narrow window; for a server you reboot rarely, a static ip= is more predictable.

Unlock the disk on the next reboot

Reboot, then SSH to the box. Dropbear listens on port 22 by default (you can change it, see below), and it logs in as root even though your normal login may not:

bash
ssh root@192.0.2.10

You land in a minimal busybox shell. The right command depends on your distro's initramfs scripts. On a current cryptsetup-initramfs setup, run:

bash
cryptroot-unlock

It prompts for the LUKS passphrase, unlocks the mapped device, and boot continues. Your SSH session to the initramfs drops as the real system comes up, which is expected, not an error. A few seconds later you can SSH in normally to your actual user account.

Older guides tell you to echo the passphrase into a named pipe like /lib/cryptsetup/passfifo. That still works on some setups, but cryptroot-unlock is the supported wrapper and the one to reach for first.

Lock it down: separate port, no shell

Two hardening steps I always apply. Run Dropbear on a non-standard port so it does not collide with your real sshd in host-key caches and SSH config, and restrict the early key so a connection can only unlock, never drop to a shell.

Set Dropbear's options in /etc/dropbear/initramfs/dropbear.conf (older packages used /etc/dropbear-initramfs/config with a DROPBEAR_OPTIONS= line; check which your version ships):

bash
DROPBEAR_OPTIONS="-p 2222 -s -j -k -I 60"

-p 2222 moves it off 22. -s disables password logins (key-only, which is the point). -j and -k disable local and remote port forwarding. -I 60 idle-times-out the session after 60 seconds, so a forgotten connection does not sit open.

You can also force a single command per key by prefixing the line in authorized_keys:

bash
command="/bin/cryptroot-unlock" ssh-ed25519 AAAA... you@example.com

Now that key can do nothing but unlock the disk. Even if it leaks, it cannot get a busybox shell on your initramfs. (Dropbear also accepts -c cryptroot-unlock in DROPBEAR_OPTIONS to force that command for every login regardless of key; the per-key command= form is more explicit, so I prefer it.)

This is the early-boot half of the picture. The real OpenSSH server that takes over once root is mounted needs its own hardening, key-only auth in particular: see disable password authentication in sshd for that pass.

When this is and is not the right tool

ScenarioUse Dropbear remote unlock?
Remote VPS or dedicated box with LUKS root, no out-of-band consoleYes. This is the canonical use case.
Box you reboot rarely and only ever from a physical consoleOptional. The console is already enough.
You want fully unattended reboots, no human typing a passphraseNo, this still needs a human. Use a TPM-bound key or Clevis/Tang network-bound unlock instead.
Encrypted /home or a data volume, but root is plaintextNo. If root is unencrypted, the normal sshd boots fine; unlock the data volume after login.

The honest caveat: this is convenience, not extra security. The disk is exactly as encrypted as before. Worth weighing: an unattended TPM or Tang unlock removes the human but also removes the "someone must know the passphrase" property, so it is a different threat model, not strictly better. For a server I reboot a handful of times a year, typing a passphrase over SSH is the right trade.

A note on systemd-based initramfs

Some recent systems build a systemd-driven initramfs rather than the classic busybox one. The plumbing differs (the unlock prompt is handled by systemd-cryptsetup and you may need the dropbear systemd hook rather than the script hook), but the shape is identical: SSH server in the initramfs, connect early, unlock, boot continues. The Arch Wiki section linked at the foot of this page documents the systemd-hook variant if your distro uses it; the Debian/Ubuntu dropbear-initramfs package handles the script-based case described above for you.

See also

Sources

Authoritative references this article was fact-checked against.

TagsLUKSDropbearSSHinitramfscryptsetupFull Disk EncryptionLinuxSecurity

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Software Systems Architect · Senior Software Engineer · Engineering Leadership

Software systems architect and senior software engineer with more than two decades designing, building, and running production software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Now a CTO, though what I write here is drawn from the full arc of that work, across architecture, engineering, and operations, not any single job.

Keep reading

Related posts

Download an entire YouTube playlist or channel free with yt-dlp: use a download archive for incremental re-runs, organize files with output templates, grab item ranges, and rate-limit big channels.

Download a YouTube Playlist or Entire Channel with yt-dlp

Download a whole YouTube playlist or entire channel free with yt-dlp: point it at a playlist or @handle, use a download archive so re-runs skip what you already have, organize files with output templates, and rate-limit to dodge the bot wall.

Wire ElasticPress to WP_Query so WordPress queries hit Elasticsearch instead of MySQL. Install, indexable post types, ep_integrate, wp-cli index, faceted aggregations, and when ES actually beats MySQL FULLTEXT.

How to Use ElasticPress with WP_Query

Wire ElasticPress to WP_Query so WordPress queries hit Elasticsearch instead of MySQL. Covers installation, indexable post types, ep_integrate, the wp-cli index command, faceted search with aggregations, and when ES actually beats MySQL FULLTEXT.

Fifty-five HR jokes about the calendar invite with no agenda, the engagement survey that fixes nothing, and the exit interview that was the actual performance review.

HR Jokes Only Employees Who Have Met With HR Get

Fifty-five HR jokes about the calendar invite with no agenda, the open door policy that has a closed door, the engagement survey that fixes nothing, and the exit interview that was the actual review.