summaryrefslogtreecommitdiff
path: root/site_root/blog/03-remote_full_system_encryption_with_arch.lua
blob: 43fccfaa839e8dcc5f3d1d5069ffec01b2dd2bd3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
return {
   title='remote-unlocking full system encryption with arch linux',
   layout='blog',
   date='2022-11-17',
   markdown=[[
I recently needed to set up a server with full system encryption and was faced with the conundrum: if I need to reboot, the keys are either (a) on the server, and thus not actually secure, or (b) need to be entered at boot, which typically means (I thought) that one needs to actually enter a password. However! I searched around a bit and saw that people used the dropbear ssh server in their initramfs images to log in remotely and thereby allow for a genuinely headless full-disk encrypted system. Unfortunately, almost all of the resources I could find on this was for Debian-based systems, and I had a hell of a time getting it to work on Arch.

So, to spare others the pain I went through getting this to work, here is **sanine's guide to remote-unlocking encrypted Arch systems**.


## 1. set up arch with full system encryption

The Arch wiki has fairly complete guides on how to do this! I used the [installation guide] and [encrypting an entire system guide] to get my initial installs set up.

A note on the bootloader steps, because this was not made clear to me the first time I did it: the kernel parameters are passed as *command-line* parameters. If you're using GRUB, for instance, they should be put in the `GRUB_CMDLINE_LINUX` variable, not as config variables in their own right.


## 2. install the needed packages

This should be a pretty easy step. On your lovely fresh install, just do

```
pacman -S mkinitcpio-netconf mkinitcpio-dropbear
```

The `netconf` hook will set up networking for us; the `dropbear` hook sets up an ssh server for us.


## 3. write a completely new initcpio hook

Yeah, sorry, this is where it got weird for me and I spent several days just reading the man pages convinced I had done something wrong. Nope! As it is now, if we set up the hooks, the dropbear server would run just fine but wouldn't actually accept any logins because there's no `/etc/passwd` file in the initramfs image for it to check if a user is valid. Luckily, it's pretty easy to create a hook that adds one for us. Create the file `/usr/lib/initcpio/install/rootpasswd` and write in it

```
#!/bin/bash

build ()
{
	echo "root::0:0::/root:/bin/sh" > /tmp/rootpasswd
	add_file /tmp/rootpasswd /etc/passwd
}
```

You can change the user if you want to, though you'll have to go modify the dropbear install file so that it sets up the `root_key` in the correct folder.


## 4. hack the encrypt hook

(If you're using the sd-encrypt hook: I have no idea how applicable any of this section will be to you. Try it and let me know!)

Okay, now it's possible to log in to the ssh server so what's the problem? Well, the default encrypt hook only checks if the target volume is present at the beginning. If you unlock it halfway through, when it's already prompted you for a password (say, for instance, by sshing in and decrypting it) it will just break. So we need to write *another* new hook. We still need the encrypt hook's install file though, so do

```
cd /usr/lib/initcpio/install
cp encrypt remote-encrypt
```

In your favorite text editor, enter the following into `/usr/lib/initcpio/hooks/remote-encrypt`:

```
#!/bin/sh

run_hook ()
{
	echo "waiting for ${root} to be available..."
	while ! [ -e "${root}" ]; do
		sleep 2;
	done
}
```

Okay, now you're finished writing hooks. Time to bring everything together.


## 5. bring everything together

Edit your `/etc/mkinitcpio.conf` HOOKS line so that it looks a little like this:

```
HOOKS=(base udev rootpasswd keyboard keymap consolefont
autodetect modconf block netconf dropbear remote-encrypt
lvm2 filesystems fsck)
```

Remember that the order of your hooks is important! When you're done, run `mkinitcpio -P` to regenerate your initramfs images.

Now, edit your chosen bootloader to add the kernel parameter `ip=dhcp` so that the `netconf` hook will work correctly. (If you're using GRUB, don't forget to regenerate your `grub.cfg`.)

Last but not least, make sure the ssh keys you want to use for unlocking are stored like an authorized_keys file in `/etc/dropbear/root_key`.


## 6. unlock remotely

If all went well, you should now be able to reboot and ssh into your machine before disk decryption. Decryption will be different based on how you set up your machine, but if you did LVM on LUKS like me, you can do

```
cryptsetup open [cryptdevice] [target] && exit
```

The "&& exit" isn't *critical*, but it does lead to some weird effects because for some reason you won't get booted out when dropbear is supposed to die? And this triggered some ugly segfault error messages when I actually did exit after the machine fully booted. Oh well.

[installation guide]: https://wiki.archlinux.org/title/Installation_guide
[encrypting an entire system guide]: https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system
]]}