A Drop Bear Before Boot: Unlocking LUKS over SSH on Ubuntu 26.04 Source

1---
2title: "A Drop Bear Before Boot: Unlocking LUKS over SSH on Ubuntu 26.04"
3date: "2026-08-03"
4published: true
5tags: ["linux", "ubuntu", "ssh", "dropbear", "luks", "encryption", "security", "initramfs"]
6author: "Gavin Jackson"
7excerpt: "My encrypted server was secure right up until it rebooted and waited for a passphrase nobody could type remotely. Dropbear gave me a tiny SSH server inside the initramfs and a safe way to unlock LUKS from elsewhere."
8---
9
10# A Drop Bear Before Boot: Unlocking LUKS over SSH on Ubuntu 26.04
11
12<p align="center"><img src="/assets/dropbear-ssh/dropbear-luks-server.png" alt="An evil-looking drop bear guarding a locked server rack in a dark data centre" width="1600"></p>
13
14*The drop bear guarding the server is fictional. The problem it is guarding against is not.*
15
16Full-disk encryption on a server creates an awkward little contradiction.
17
18I wanted the root volume encrypted with LUKS so that taking the disks, or the whole machine, did not also mean taking the data. That worked exactly as intended. It also meant that every reboot stopped at the early boot prompt waiting for somebody to enter the LUKS passphrase.
19
20That is fine when the server is under a desk. It is less fine when it is headless, remote or simply on the other side of a locked door.
21
22My answer was **Dropbear**, a compact SSH server small enough to run from the initramfs. It brings up the network before the encrypted root filesystem is mounted, accepts a key-authenticated SSH connection and lets me run `cryptroot-unlock`. Once I enter the LUKS passphrase, the real root filesystem opens and Ubuntu continues booting normally.
23
24This article shows the setup I used on Ubuntu Server 26.04 LTS. It assumes the root volume is already encrypted with LUKS and the machine uses Ubuntu's usual `initramfs-tools` boot path.
25
26> Do not make your first test on a remote machine without working console access. A typo in early-boot networking can turn a routine reboot into a drive to the server.
27
28## What Dropbear actually is
29
30[Dropbear](https://matt.ucc.asn.au/dropbear/dropbear.html) is a small SSH 2 server and client written for constrained Unix-like systems. It supports OpenSSH public keys, can run as a standalone daemon and can be compiled with unwanted features removed. Its small dependency and memory footprint made it popular on routers and embedded Linux, but the same qualities also make it a very good fit for an initramfs.
31
32There is an Australian connection beyond the name. Dropbear's author is **[Matt Johnston](https://github.com/mkj)**, an Australian developer based in Perth whose site is hosted by the University Computer Club at the University of Western Australia. The name is a nod to the Australian drop bear: the allegedly vicious cousin of the koala that Australians warn visitors about with an entirely straight face.
33
34On Ubuntu, `dropbear-initramfs` does not replace the normal OpenSSH server. It installs the pieces needed to build a separate, temporary Dropbear environment into the initramfs. Ubuntu 26.04 packages Dropbear 2025.89 for this purpose in the `universe` repository.
35
36## Why the normal SSH server cannot help
37
38When an encrypted-root machine first starts, most of the operating system is still behind LUKS. `/etc/ssh`, user accounts, systemd units, firewall rules and the normal OpenSSH daemon are all sitting inside a filesystem the kernel cannot read yet.
39
40The initramfs is different. It is a small temporary filesystem loaded into memory alongside the kernel. It contains just enough tooling to discover storage, load drivers, unlock encrypted devices and mount the real root filesystem.
41
42Adding Dropbear changes the boot path to this:
43
44```text
45UEFI / firmware
46  -> GRUB loads the kernel and initramfs
47  -> initramfs loads the NIC driver and configures an IP address
48  -> Dropbear starts and accepts a public-key SSH login
49  -> cryptroot-unlock asks for the LUKS passphrase
50  -> the encrypted root volume opens
51  -> Ubuntu switches to the real root filesystem
52  -> the initramfs Dropbear process disappears
53  -> normal system services, including OpenSSH, start
54```
55
56That final handover is important. The early SSH server exists only to get the machine across the encrypted-root gap. It is not the SSH service I use after boot.
57
58## Before changing anything
59
60I made sure I had all of the following before starting:
61
62- A working fallback console. My plan B was the VM console in vCenter; on physical or hosted hardware, the equivalent might be IPMI, iDRAC, iLO or a hosting-provider serial console.
63- A wired Ethernet connection. Wi-Fi in the initramfs is possible, but firmware, authentication and roaming make it a much larger job.
64- Either a DHCP reservation or a known static address for the early-boot interface.
65- The name of the wired interface, from `ip link`.
66- A second computer from which to test the SSH connection.
67- A current backup, because this is boot configuration and optimism is not a recovery plan.
68
69The examples below use port `2222` for the initramfs service. Keeping it separate from the normal OpenSSH port makes the two host identities obvious and avoids confusing entries in `known_hosts`.
70
71I did not appreciate that choice when I followed the first tutorial I found. "Surely this is unnecessary," I thought. Then I tried using port 22, hit the host-key warning caused by Dropbear and OpenSSH presenting different keys for the same host, and it all became obvious. OpenSSH records host keys by host and port, so `[server]:2222` gives the temporary boot environment its own identity without teaching the client to ignore host-key checking.
72
73## 1. Install the initramfs packages
74
75Install Dropbear's initramfs integration and the cryptsetup hooks:
76
77```bash
78sudo apt update
79sudo apt install dropbear-initramfs cryptsetup-initramfs
80```
81
82If APT cannot find `dropbear-initramfs`, enable Ubuntu's `universe` component first:
83
84```bash
85sudo add-apt-repository universe
86sudo apt update
87sudo apt install dropbear-initramfs cryptsetup-initramfs
88```
89
90The package creates dedicated Dropbear host keys under `/etc/dropbear/initramfs/`. These are deliberately different from the OpenSSH keys used by the fully booted system.
91
92One Ubuntu 26.04 detail is worth highlighting: the current configuration directory is:
93
94```text
95/etc/dropbear/initramfs/
96```
97
98Many older guides use `/etc/dropbear-initramfs/`. That was the old location and is an easy way to spend an hour editing a file that never reaches the initramfs.
99
100## 2. Create a dedicated unlock key
101
102I generated a separate key on my admin workstation rather than reusing my everyday SSH identity:
103
104```bash
105ssh-keygen -t ed25519 -a 64 \
106  -f ~/.ssh/luks-unlock \
107  -C "LUKS remote unlock"
108```
109
110This creates:
111
112```text
113~/.ssh/luks-unlock      # private key - keep this on the admin machine
114~/.ssh/luks-unlock.pub  # public key - copy this to the server
115```
116
117I gave the private key a passphrase. The server must never receive that private key; it needs only the contents of the `.pub` file.
118
119## 3. Authorise only the unlock command
120
121On the server, create or edit the initramfs authorised-keys file:
122
123```bash
124sudo install -d -m 0700 /etc/dropbear/initramfs
125sudoedit /etc/dropbear/initramfs/authorized_keys
126```
127
128Paste the public key as one line, but put these restrictions in front of it:
129
130```text
131no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="/bin/cryptroot-unlock" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... LUKS remote unlock
132```
133
134The `AAAAC3...` portion must be the real public key from `~/.ssh/luks-unlock.pub`, not the abbreviated example above.
135
136Then fix the permissions:
137
138```bash
139sudo chmod 0600 /etc/dropbear/initramfs/authorized_keys
140```
141
142The forced command is an important guardrail. A successful login cannot choose an arbitrary shell command; Dropbear runs `/bin/cryptroot-unlock` instead. Port, agent and X11 forwarding are disabled as well. I still get the interactive terminal that `cryptroot-unlock` needs for the passphrase prompt.
143
144## 4. Lock down Dropbear and move it to port 2222
145
146Edit the current initramfs configuration file:
147
148```bash
149sudoedit /etc/dropbear/initramfs/dropbear.conf
150```
151
152Set the options to:
153
154```bash
155DROPBEAR_OPTIONS="-p 2222 -s -j -k"
156```
157
158Those flags select port 2222, disable password authentication, disable local forwarding and disable remote forwarding. The initramfs package already disables password logins, but I prefer the intent to be visible in the configuration too.
159
160Changing the port is not a security boundary. It separates the boot-time and normal SSH services; the key restrictions and network controls provide the actual protection.
161
162### What I actually wanted: port 22 all the way through
163
164Port 2222 neatly solved the host-key problem, but I still wanted Dropbear and OpenSSH to use port 22. They never listen at the same time: Dropbear owns the port while the machine is in the initramfs, then disappears before the normal OpenSSH service starts. There is no port collision.
165
166The real problem was identity. Dropbear and OpenSSH had different host keys, so an SSH client connecting to the same host on the same port quite correctly treated the change as suspicious. I needed both daemons to present the same host keys.
167
168Simply copying the OpenSSH private-key files does not work because OpenSSH and Dropbear store private keys in different formats. The [`dropbearconvert`](https://manpages.ubuntu.com/manpages/resolute/man1/dropbearconvert.1.html) tool converts the existing OpenSSH keys into Dropbear's binary format.
169
170I backed up the original Dropbear initramfs keys, then converted the standard Ubuntu host keys:
171
172```bash
173sudo dropbearconvert openssh dropbear \
174  /etc/ssh/ssh_host_rsa_key \
175  /etc/dropbear/initramfs/dropbear_rsa_host_key
176
177sudo dropbearconvert openssh dropbear \
178  /etc/ssh/ssh_host_ecdsa_key \
179  /etc/dropbear/initramfs/dropbear_ecdsa_host_key
180
181sudo dropbearconvert openssh dropbear \
182  /etc/ssh/ssh_host_ed25519_key \
183  /etc/dropbear/initramfs/dropbear_ed25519_host_key
184
185sudo chmod 0600 \
186  /etc/dropbear/initramfs/dropbear_rsa_host_key \
187  /etc/dropbear/initramfs/dropbear_ecdsa_host_key \
188  /etc/dropbear/initramfs/dropbear_ed25519_host_key
189```
190
191A default Ubuntu installation normally has all three keys. If one of the OpenSSH source files does not exist, skip that conversion rather than inventing a replacement. OpenSSH host keys are normally unencrypted, which matters because `dropbearconvert` cannot read an encrypted private key.
192
193I then changed `/etc/dropbear/initramfs/dropbear.conf` to use port 22:
194
195```bash
196DROPBEAR_OPTIONS="-p 22 -s -j -k"
197```
198
199After rebuilding the image, the `hostvars` error I had been seeing during the initramfs rebuild disappeared as well:
200
201```bash
202sudo update-initramfs -u -k all
203```
204
205I checked the Ed25519 fingerprints from both formats to confirm that the conversion had preserved the same key:
206
207```bash
208sudo dropbearkey -y \
209  -f /etc/dropbear/initramfs/dropbear_ed25519_host_key
210
211sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
212```
213
214With the same host identity on both sides of the handover, the client can use port 22 before and after the root volume unlocks without a host-key warning. The unlock connection no longer needs `-p 2222`, and its SSH config does not need a `Port 2222` line.
215
216There is a genuine trade-off here. Reusing the keys means private host-key material for the normal OpenSSH service is copied into the initramfs, which normally sits in unencrypted `/boot`. The package deliberately generates separate initramfs keys by default for exactly this reason. If exposing the main server identity there is unacceptable, port 2222 with separate keys and a separate `known_hosts` file remains the better design.
217
218The rest of this walkthrough uses port 2222 because it is the safer general-purpose default. The shared-key port 22 setup above is the variation I ultimately wanted.
219
220## 5. Give the initramfs a network address
221
222Dropbear is not useful until the initramfs can configure the network. The cleanest arrangement for my use case was DHCP plus a reservation on the router, so the server received the same early-boot address every time.
223
224Edit GRUB's defaults:
225
226```bash
227sudoedit /etc/default/grub
228```
229
230Add `ip=dhcp` to the existing value of `GRUB_CMDLINE_LINUX`. Preserve any arguments already there. A simple configuration might look like:
231
232```bash
233GRUB_CMDLINE_LINUX="ip=dhcp"
234```
235
236Then rebuild the GRUB configuration:
237
238```bash
239sudo update-grub
240```
241
242On a machine with several network interfaces, specify the interface explicitly. For example:
243
244```text
245ip=:::::enp2s0:dhcp
246```
247
248For a static address, the kernel parameter has this shape:
249
250```text
251ip=<client-ip>:<server-ip>:<gateway>:<netmask>:<hostname>:<interface>:<autoconf>
252```
253
254This example assigns `192.0.2.50` to `enp2s0` without autoconfiguration:
255
256```text
257ip=192.0.2.50::192.0.2.1:255.255.255.0:cryptbox:enp2s0:none
258```
259
260The `192.0.2.0/24` range is reserved for documentation. Replace every address and the interface name with values from the real network. The Linux kernel's [boot-time IP configuration documentation](https://docs.kernel.org/admin-guide/nfs/nfsroot.html) has the full field definition.
261
262The normal Netplan configuration does not solve this stage of boot because Netplan lives on the encrypted root filesystem. The address has to come from the kernel command line or other configuration included in the initramfs.
263
264## 6. Rebuild the initramfs
265
266Every change under `/etc/dropbear/initramfs/` must be copied into a new initramfs image:
267
268```bash
269sudo update-initramfs -u -k all
270```
271
272Do not skip this. Editing the source files changes nothing about the initramfs already stored in `/boot`.
273
274I checked the image for the important pieces before rebooting:
275
276```bash
277sudo lsinitramfs /boot/initrd.img-"$(uname -r)" \
278  | grep -E 'dropbear|authorized_keys|cryptroot-unlock'
279```
280
281It is also useful to record the fingerprint of the initramfs Ed25519 host key:
282
283```bash
284sudo dropbearkey -y \
285  -f /etc/dropbear/initramfs/dropbear_ed25519_host_key
286```
287
288I kept that fingerprint where I could compare it during the first connection. The initramfs host key is not supposed to match the normal OpenSSH host key.
289
290## 7. Reboot and unlock it
291
292For the first test I kept the server console open, started a continuous ping from another machine and rebooted:
293
294```bash
295sudo reboot
296```
297
298Once the machine reached the LUKS prompt and the early-boot address responded, I connected from the admin workstation:
299
300```bash
301ssh -t \
302  -p 2222 \
303  -i ~/.ssh/luks-unlock \
304  -o IdentitiesOnly=yes \
305  -o UserKnownHostsFile=~/.ssh/known_hosts-initramfs \
306  root@192.0.2.50
307```
308
309On the first connection, I compared the presented host-key fingerprint with the one recorded before the reboot. After accepting it, the forced command displayed the LUKS prompt. I entered the normal disk passphrase; it was not echoed to the screen.
310
311When the volume unlocked, the SSH session ended and boot continued. A short time later the normal OpenSSH service appeared on port 22.
312
313For repeat use, I added a client-side shortcut to `~/.ssh/config`:
314
315```sshconfig
316Host myserver-unlock
317    HostName 192.0.2.50
318    User root
319    Port 2222
320    IdentityFile ~/.ssh/luks-unlock
321    IdentitiesOnly yes
322    UserKnownHostsFile ~/.ssh/known_hosts-initramfs
323```
324
325The whole recovery procedure then became:
326
327```bash
328ssh -t myserver-unlock
329```
330
331## If the connection does not arrive
332
333Early boot is a small environment, so the diagnostic list is mercifully short.
334
335### The host never answers
336
337Check the console first. If it is waiting for the LUKS passphrase but does not have an address, confirm:
338
339- `ip=...` appears in `/proc/cmdline` after a successful local boot.
340- The initramfs interface name matches `ip link`.
341- The DHCP server has a lease for the wired NIC's MAC address.
342- The selected network can reach the server before its normal firewall and VPN services exist.
343- The NIC driver and any required firmware are present in the initramfs.
344
345Ubuntu normally includes a broad set of storage and network modules, but unusual adapters can still need help. The Dropbear package documentation recommends adding the required driver module name to `/etc/initramfs-tools/modules`, then rebuilding the initramfs again.
346
347### SSH says permission denied
348
349Confirm that the public key is one unbroken line in `/etc/dropbear/initramfs/authorized_keys`, its permissions are `0600`, the containing directory is not writable by other users and the client is using the matching private key. Rebuild the initramfs after every key change.
350
351### `cryptroot-unlock` is missing
352
353Make sure `cryptsetup-initramfs` is installed and visible in the `lsinitramfs` output. The package supplies the unlock helper and the hooks that copy it into the boot image.
354
355### The host key has changed
356
357Do not blindly switch off host-key checking. A package reinstall, deliberate host-key regeneration or rebuilt machine can explain the change, but verify the new fingerprint through the console before removing the old entry from `~/.ssh/known_hosts-initramfs`.
358
359### There is more than one encrypted volume
360
361With a terminal attached, `cryptroot-unlock` continues prompting until the initramfs has unlocked all required encrypted devices. If a non-root encrypted volume is not required during early boot, it may be handled later by the normal system instead; check its `/etc/crypttab` options.
362
363## The security trade-off
364
365This setup does not make the server automatically unlock itself. The LUKS passphrase remains with me and travels through an authenticated, encrypted SSH session only when the machine needs it.
366
367It does, however, add an SSH listener before the normal operating system and its firewall have started. I would not expose port 2222 directly to the public Internet. On a remote site, I would restrict it with an upstream firewall, management network or VPN provided by the router rather than depending on a VPN service stored inside the still-locked root filesystem.
368
369There is another subtle point: the initramfs and its Dropbear host private key normally live in unencrypted `/boot`. The LUKS passphrase is not stored there, but somebody who can replace the kernel or initramfs can create a fake unlock prompt that captures it. Secure Boot, controlled physical access and careful verification of unexpected host-key changes all matter. Remote unlocking solves an availability problem; it does not remove the need to trust the boot chain.
370
371My minimum controls are:
372
373- Public-key authentication only.
374- A dedicated, passphrase-protected client key.
375- A forced `cryptroot-unlock` command for that key.
376- Forwarding disabled in both the key and daemon configuration.
377- A separate port and `known_hosts` file for the initramfs identity.
378- Upstream network restrictions.
379- Console access for recovery and first-boot verification.
380- Regular patching and an initramfs rebuild after configuration changes.
381
382## Where else Dropbear is useful
383
384Remote LUKS unlock is a particularly satisfying use of Dropbear, but it is not the only one.
385
386### Routers and embedded devices
387
388This is Dropbear's traditional home. Its small binary, low memory use and configurable feature set suit routers, access points, appliances and other systems where installing a full OpenSSH stack may be wasteful. OpenWrt is probably where many administrators first meet it.
389
390### A headless initramfs rescue shell
391
392The same early SSH path can help diagnose storage discovery, broken LVM assembly, missing kernel modules or failed root mounts on a machine with no useful local console. I would use a separate, carefully restricted recovery key if I wanted an actual shell rather than weakening the LUKS-only key above.
393
394### Recovery and installation images
395
396Small recovery systems, custom installers and read-only maintenance images often need remote access without carrying a large userland. Dropbear can provide enough SSH for diagnosis, scripted provisioning or file transfer.
397
398### Small single-board computers
399
400Modern boards usually have enough resources for OpenSSH, but Dropbear remains useful when the root filesystem is tiny, storage writes are expensive or the system is deliberately stripped down.
401
402### Temporary maintenance access
403
404Dropbear can run standalone or under another service supervisor, which makes it useful as a short-lived maintenance daemon on specialist Unix systems. It still needs the same patching, key management and exposure decisions as any other SSH server.
405
406It is sometimes suggested as a way to put SSH inside an application container. I generally would not do that. A container is usually easier to inspect with the runtime's exec mechanism, and adding an SSH daemon creates another credential and patching surface. Small does not automatically mean appropriate.
407
408## A small tool in exactly the right place
409
410The clever part of this arrangement is not SSH itself. It is putting just enough SSH in the few seconds of boot where the normal server cannot possibly help.
411
412LUKS still does its job. The passphrase is still required. The server can still reboot without somebody standing beside it. Dropbear simply gives that somebody a narrow, authenticated path to the right prompt.
413
414That is a good systems tool: small, slightly obscure and extremely useful at precisely the moment everything larger is still locked away.
415
416---
417
418**Further reading:**
419
420- [Dropbear SSH project page](https://matt.ucc.asn.au/dropbear/dropbear.html)
421- [Ubuntu 26.04 `dropbear-initramfs` package](https://packages.ubuntu.com/resolute/all/dropbear-initramfs)
422- [Ubuntu 26.04 Dropbear manual](https://manpages.ubuntu.com/manpages/resolute/man8/dropbear.8.html)
423- [Ubuntu 26.04 `dropbearconvert` manual](https://manpages.ubuntu.com/manpages/resolute/man1/dropbearconvert.1.html)
424- [Current Debian/Ubuntu initramfs integration notes](https://sources.debian.org/src/dropbear/2025.89-1~deb13u1/debian/README.initramfs)
425- [Linux kernel boot-time IP configuration](https://docs.kernel.org/admin-guide/nfs/nfsroot.html)
426