nixos-config/lib/fudo/initrd-network.nix

109 lines
2.8 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
hostname = config.instance.hostname;
host-cfg = config.fudo.hosts.${hostname};
ip = host-cfg.initrd-ip;
key-type = "ed25519";
key-filename = "ssh_host_${key-type}_key";
gen-host-keys = hostname: pkgs.stdenv.mkDerivation {
name = "${hostname}-initrd-ssh-keys";
phases = [ "installPhase" ];
buildInputs = with pkgs; [ openssh ];
installPhase = ''
mkdir $out
ssh-keygen -q -t ${key-type} -N "" -f $out/ssh_host_${key-type}_key
'';
};
gen-sshfp-records = host: key-pkg: pkgs.stdenv.mkDerivation {
name = "${hostname}-initrd-ssh-fingerprints";
phases = [ "installPhase" ];
buildInputs = with pkgs; [ openssh ];
installPhase = ''
mkdir $out
ssh-keygen -r REMOVEME -f "${key-pkg}/${key-filename}" | sed 's/^REMOVEME IN SSHFP //' >> $out/${key-filename}.sshfp
'';
};
host-keys = genAttrs (attrNames config.instance.local-hosts)
(hostname: gen-host-keys hostname);
in {
config = mkIf (ip != null) {
boot = let
hostname = config.instance.hostname;
in {
kernelParams = [
"ip=${ip}"
];
initrd = let
host-key-pkg = host-keys.${config.instance.hostname};
host-privkey = builtins.toPath "${host-key-pkg}/${key-filename}";
in {
secrets = {
"/var/run/initrd/ssh-host-key" =
config.fudo.secrets.host-secrets.${hostname}.initrd-ssh-host-key.target-file;
};
network = {
enable = true;
ssh = let
admin-ssh-keys =
concatMap (admin: config.fudo.users.${admin}.ssh-authorized-keys)
config.instance.local-admins;
in {
enable = true;
port = 22;
authorizedKeys = admin-ssh-keys;
hostKeys = [
"/var/run/initrd/ssh-host-key"
];
};
};
};
};
fudo = {
secrets.host-secrets = mapAttrs
(hostname: key-pkg: {
initrd-ssh-host-key = {
source-file = "${key-pkg}/${key-filename}";
target-file = "/var/run/ssh/${key-filename}";
user = "root";
};
})
host-keys;
local-network = {
network-definition.hosts = mapAttrs'
(hostname: hostOpts: nameValuePair "${hostname}-recovery"
{
ipv4-address = config.fudo.hosts.${hostname}.initrd-ip;
description = "${hostname} initrd host";
})
config.instance.local-hosts;
extra-records =
mapAttrs
(hostname: key-pkg: let
sshfp-pkg = gen-sshfp-records hostname key-pkg;
sshfps = read-lines "${sshfp-pkg}/${key-filename}.sshfp";
in map (sshfp: "${hostname} IN SSHFP ${sshfp}") sshfps)
host-keys;
};
};
};
}