Remote disk unlocking: Difference between revisions
Fix broken networkmanager DNS with boot.initrd.network.enable, see: https://github.com/NixOS/nixpkgs/issues/63941#issuecomment-2081126437. Use ed25519 host key. Use postCommands to directly prompt for password, shell option did not work for me. |
Added a point about publishing the initrd hostname when using DHCP. |
||
| (10 intermediate revisions by 5 users not shown) | |||
| Line 6: | Line 6: | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
# mkdir -p /etc/secrets/initrd | |||
# ssh-keygen -t ed25519 -N "" -f /etc/secrets/initrd/ssh_host_ed25519_key | # ssh-keygen -t ed25519 -N "" -f /etc/secrets/initrd/ssh_host_ed25519_key | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 26: | Line 27: | ||
postCommands = '' | postCommands = '' | ||
# Automatically ask for the password on SSH login | # Automatically ask for the password on SSH login | ||
echo 'cryptsetup-askpass || echo "Unlock was successful; exiting SSH session" && exit 1' >> /root/.profile | echo 'cryptsetup-askpass || echo "Unlock was successful; exiting SSH session" && exit 1'</nowiki> >> <nowiki>/root/.profile | ||
''; | ''; | ||
}; | }; | ||
| Line 36: | Line 37: | ||
* '''authorizedKeys''': Add the SSH public keys for the users which should be able to authenticate to the SSH daemon to the <code>authorizedKeys</code> option. | * '''authorizedKeys''': Add the SSH public keys for the users which should be able to authenticate to the SSH daemon to the <code>authorizedKeys</code> option. | ||
* '''availableKernelModules''': Most likely your network card is not working without its kernel module being part of the initrd, so you have to find out which module is used for your network. Use <code>lspci -v | grep -iA8 'network\|ethernet'</code> for that. | * '''availableKernelModules''': Most likely your network card is not working without its kernel module being part of the initrd, so you have to find out which module is used for your network. Use <code>lspci -v | grep -iA8 'network\|ethernet'</code> for that. | ||
* '''kernelParams''': | * '''kernelParams''': | ||
** When using a dynamic IP address with DHCP you might want to publish your hostname already in the initrd so it can be resolved in the local network: <code>boot.kernelParams = [ "ip=::::${config.networking.hostName}::dhcp" ];</code><ref>https://github.com/NixOS/nixpkgs/issues/63941#issuecomment-2628615604</ref> Note that when using DHCP, make sure your computer is always attached to the network and is able to get an IP adress, or the boot process will hang. | |||
** You could also configure a static IP <code>boot.kernelParams = [ "ip=10.25.0.2::10.25.0.1:255.255.255.0:myhost::none" ];</code>, where <code>10.25.0.2</code> is the client IP, <code>10.25.0.1</code> is the gateway IP. See [https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt the kernel documentation] for more information on the <code>ip=</code> parameter. | |||
| Line 77: | Line 80: | ||
Using systemd in initrd automatically continues the boot process after the target <code>/sysroot</code> is mounted. | Using systemd in initrd automatically continues the boot process after the target <code>/sysroot</code> is mounted. | ||
=== Wireguard in initrd === | |||
Considering you've already enabled the ssh daemon, configured networking (for example with DHCP or static IP) and configured an unlocking command, following additional snippet will enable [[WireGuard]] connectivity to a remote peer while in initrd.<syntaxhighlight lang="nix"> | |||
boot.initrd.availableKernelModules = [ "r8169" "wireguard" ]; | |||
boot.initrd.systemd = { | |||
enable = true; | |||
network = { | |||
netdevs."30-wg-initrd" = { | |||
netdevConfig = { | |||
Kind = "wireguard"; | |||
Name = "wg-initrd"; | |||
}; | |||
wireguardConfig = { PrivateKeyFile = "/etc/secrets/30-wg-initrd.key"; }; | |||
wireguardPeers = [{ | |||
AllowedIPs = [ "10.250.0.1/32" ]; | |||
PublicKey = "wUE//Lwi8DZVIvAjIAtMoy+ku+hJ0w28H7ofySwAJRk="; | |||
Endpoint = "198.51.100.1:51821"; | |||
PersistentKeepalive = 25; | |||
}]; | |||
}; | |||
networks."30-wg-initrd" = { | |||
name = "wg-initrd"; | |||
addresses = [{ Address = "10.250.0.2/24"; }]; | |||
}; | |||
}; | |||
}; | |||
boot.initrd.secrets."/etc/secrets/30-wg-initrd.key" = "/etc/wireguard/private-key"; | |||
</syntaxhighlight>First generate a private und public key pair as mentioned in the WireGuard article. Reference the private key in <code>boot.initrd.secrets</code>, in this exmaple <code>/etc/wireguard/private-key</code>. Put the <code>PublicKey</code> of the remote peer into the <code>wireguardPeers</code> array. | |||
Configure the IP addresses used by your initrd peer (<code>10.250.0.2</code>) and the remote peer (<code>10.250.0.1</code>). Also specify the IP and port of the remote peer in <code>Endpoint</code>, in our example <code>198.51.100.1:51821</code>. The remote peer also needs to know address configuration and the public key of the initrd peer. | |||
Last but not least add the <code>wireguard</code> kernel module to <code>boot.initrd.availableKernelModules</code> beside the module required by your network device. | |||
=== Tor in initrd === | === Tor in initrd === | ||
An example with an ssh server listening at a tor hidden service address can be found at [https://cgit.euer.krebsco.de/stockholm/ | An example with an ssh server listening at a tor hidden service address can be found at [https://cgit.euer.krebsco.de/makefu/stockholm/src/commit/9b1008814e981dc01afe9ee7446322ad512c1d72/krebs/2configs/tor/initrd.nix krebs/2configs/tor/initrd.nix in stockholm] | ||
==== Prepare the Onion ID ==== | ==== Prepare the Onion ID ==== | ||
| Line 90: | Line 125: | ||
* <code>hs_ed25519_secret_key</code> | * <code>hs_ed25519_secret_key</code> | ||
To create these files | To create these files: | ||
$ nix-shell -p mkp224o --command "mkp224o-donna snow -n 1 -d ." | |||
set workdir: ./ | |||
nixuum6flqthv6ar52j5e2ldulylfsfgezykeg37iy74kqowcp5gxfyd.onion | |||
The files you need are in the <code>*.onion</code> directory: | |||
$ ls *.onion | |||
hostname hs_ed25519_public_key hs_ed25519_secret_key | |||
==== Setup Tor ==== | ==== Setup Tor ==== | ||
| Line 117: | Line 139: | ||
<syntaxhighlight lang="nix"># copy your onion folder | <syntaxhighlight lang="nix"># copy your onion folder | ||
boot.initrd.secrets = { | boot.initrd.secrets = { | ||
"/etc/tor/onion/bootup" | "/etc/tor/onion/bootup" = /home/tony/tor/onion; # maybe find a better spot to store this. | ||
}; | }; | ||
| Line 189: | Line 211: | ||
=== Enable Wifi in initrd === | === Enable Wifi in initrd === | ||
Following example configuration by [https://discourse.nixos.org/t/wireless-connection-within-initrd/38317/13 @loutr] enables wifi connections inside initrd. Replace interface name <code>wlp0s20f0u4</code> with the name of your wifi adapter. Depending on your wifi device, you might need to add different kernel modules.<syntaxhighlight lang="nix"> | Following example configuration by [https://discourse.nixos.org/t/wireless-connection-within-initrd/38317/13 @loutr] enables wifi connections inside initrd. Replace interface name <code>wlp0s20f0u4</code> with the name of your wifi adapter. Depending on your wifi device, you might need to add different kernel modules.<syntaxhighlight lang="nix"> | ||
boot.initrd = { | { | ||
boot.initrd = { | |||
# crypto coprocessor and wifi modules | |||
availableKernelModules = [ | |||
"ccm" | |||
"ctr" | |||
"iwlmvm" | |||
"iwlwifi" | |||
]; | |||
systemd = { | |||
enable = true; | |||
packages = [ pkgs.wpa_supplicant ]; | |||
initrdBin = [ pkgs.wpa_supplicant ]; | |||
targets.initrd.wants = [ "wpa_supplicant@wlp0s20f0u4.service" ]; | |||
# prevent WPA supplicant from requiring `sysinit.target`. | |||
services."wpa_supplicant@".unitConfig.DefaultDependencies = false; | |||
users.root.shell = "/bin/systemd-tty-ask-password-agent"; | |||
network = { | |||
enable = true; | enable = true; | ||
networks."10-wlan" = { | |||
matchConfig.Name = "wlp0s20f0u4"; | |||
DHCP = "yes"; | |||
}; | |||
}; | }; | ||
}; | |||
network.ssh = { | |||
enable = true; | |||
port = 22; | |||
hostKeys = [ "/etc/ssh/ssh_host_ed25519_key" ]; | |||
authorizedKeys = default.user.openssh.authorizedKeys.keys; | |||
}; | }; | ||
secrets."/etc/wpa_supplicant/wpa_supplicant-wlp0s20f0u4.conf" = /root/secrets/wpa_supplicant.conf; | secrets."/etc/wpa_supplicant/wpa_supplicant-wlp0s20f0u4.conf" = /root/secrets/wpa_supplicant.conf; | ||
}; | }; | ||
</syntaxhighlight>The file <code> | } | ||
</syntaxhighlight>The file <code>wpa_supplicant-wlp0s20f0u4.conf</code> is the wireless profile used by [[wpa_supplicant]] which will get copied into the initramfs. | |||
[[Category:Server]] | [[Category:Server]] | ||
[[Category:Cookbook]] | [[Category:Cookbook]] | ||