diff --git a/config/hardware/socrates.nix b/config/hardware/socrates.nix index 4a13786..584c7af 100644 --- a/config/hardware/socrates.nix +++ b/config/hardware/socrates.nix @@ -20,20 +20,20 @@ "r8169" ]; kernelModules = [ "dm-snapshot" ]; - network = { - enable = true; - ssh = { - enable = true; - port = 22; - authorizedKeys = [ - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDPwh522lvafTJYA0X2uFdP7Ws+Um1f8gZsARK1Y5nMzf6ZcWBF1jplTOKUVSOl4isMWni0Tu0TnX4zqCcgocWUVbwIwXSIRYqdiCPvVOH+/Ibc97n1/dYxk5JPMtbrsEw6/gWZxVg0qwe0J3dQWldEMiDY7iWhlrmIr7YL+Y3PUd7DOwp3PbfWfNyzTfE1kXcz5YvTeN+txFhbbXT0oS2R2wtc1vYXFZ/KbNstjqd+i8jszAq3ZkbbwL3aNR0RO4n8+GoIILGw8Ya4eP7D6+mYk608IhAoxpGyMrUch2TC2uvOK3rd/rw1hsTxf4AKjAZbrfd/FJaYru9ZeoLjD4bRGMdVp56F1m7pLvRiWRK62pV2Q/fjx+4KjHUrgyPd601eUIP0ayS/Rfuq8ijLpBJgO5/Y/6mFus/kjZIfRR9dXfLM67IMpyEzEITYrc/R2sedWf+YHxSh6eguAZ/kLzioar1nHLR7Wzgeu0tgWkD78WQGjpXGoefAz3xHeBg3Et0= niten@plato" - ]; - hostKeys = [ - "/state/ssh/ssh_host_ed25519_key" - "/state/ssh/ssh_host_rsa_key" - ]; - }; - }; + # network = { + # enable = true; + # ssh = { + # enable = true; + # port = 22; + # authorizedKeys = [ + # "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDPwh522lvafTJYA0X2uFdP7Ws+Um1f8gZsARK1Y5nMzf6ZcWBF1jplTOKUVSOl4isMWni0Tu0TnX4zqCcgocWUVbwIwXSIRYqdiCPvVOH+/Ibc97n1/dYxk5JPMtbrsEw6/gWZxVg0qwe0J3dQWldEMiDY7iWhlrmIr7YL+Y3PUd7DOwp3PbfWfNyzTfE1kXcz5YvTeN+txFhbbXT0oS2R2wtc1vYXFZ/KbNstjqd+i8jszAq3ZkbbwL3aNR0RO4n8+GoIILGw8Ya4eP7D6+mYk608IhAoxpGyMrUch2TC2uvOK3rd/rw1hsTxf4AKjAZbrfd/FJaYru9ZeoLjD4bRGMdVp56F1m7pLvRiWRK62pV2Q/fjx+4KjHUrgyPd601eUIP0ayS/Rfuq8ijLpBJgO5/Y/6mFus/kjZIfRR9dXfLM67IMpyEzEITYrc/R2sedWf+YHxSh6eguAZ/kLzioar1nHLR7Wzgeu0tgWkD78WQGjpXGoefAz3xHeBg3Et0= niten@plato" + # ]; + # hostKeys = [ + # "/state/ssh/ssh_host_ed25519_key" + # "/state/ssh/ssh_host_rsa_key" + # ]; + # }; + # }; }; loader = { diff --git a/config/hosts/lambda.nix b/config/hosts/lambda.nix index 7666888..6ebf1a2 100644 --- a/config/hosts/lambda.nix +++ b/config/hosts/lambda.nix @@ -22,4 +22,5 @@ arch = "x86_64-linux"; nixos-system = true; machine-id = "c031cda2e88a4cedb3b22f41f9042646"; + initrd-ip = "10.0.5.11"; } diff --git a/config/hosts/limina.nix b/config/hosts/limina.nix index 7c2a2ba..a37f078 100644 --- a/config/hosts/limina.nix +++ b/config/hosts/limina.nix @@ -21,4 +21,5 @@ public-key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA44EqP6HHjIPBFuxKvi2oZc1sNU+N4pNMtlS89KWuDm"; key-path = "/state/master-key/key"; }; + initrd-ip = "10.0.5.1"; } diff --git a/config/hosts/nostromo.nix b/config/hosts/nostromo.nix index 6d6164a..2dd9d1e 100644 --- a/config/hosts/nostromo.nix +++ b/config/hosts/nostromo.nix @@ -21,4 +21,5 @@ public-key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIODtNR4b43ZJgyGo9Hc+CmC4+bzgxbsVYI9fhDqjyRSo"; key-path = "/state/master-key/key"; }; + initrd-ip = "10.0.5.10"; } diff --git a/config/hosts/plato.nix b/config/hosts/plato.nix index 718e040..6b5d9ff 100644 --- a/config/hosts/plato.nix +++ b/config/hosts/plato.nix @@ -24,4 +24,5 @@ public-key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICgAzn6gyG1ze7L1WLU84poPGcoUntqfvgn+/s3bxhR2"; key-path = "/state/master-key/key"; }; + initrd-ip = "10.0.5.11"; } diff --git a/config/hosts/socrates.nix b/config/hosts/socrates.nix index 7ff7663..8577343 100644 --- a/config/hosts/socrates.nix +++ b/config/hosts/socrates.nix @@ -21,4 +21,5 @@ public-key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINmJJFbAV8P1V1LSZr56GJ5ul3LBgdapbh+MK3ixTsxf"; key-path = "/state/master-key/key"; }; + initrd-ip = "10.0.5.10"; } diff --git a/config/hosts/spark.nix b/config/hosts/spark.nix index 9558ab6..df17627 100644 --- a/config/hosts/spark.nix +++ b/config/hosts/spark.nix @@ -22,4 +22,5 @@ public-key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGs8MfR3d6f1Llqk5dn/ypODUT1Oi4SQGof/YvOPNf14"; key-path = "/state/master-key/key"; }; + initrd-ip = "10.0.5.108"; } diff --git a/config/hosts/system3.nix b/config/hosts/system3.nix index 2a915c8..8eb00b4 100644 --- a/config/hosts/system3.nix +++ b/config/hosts/system3.nix @@ -22,4 +22,5 @@ public-key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEaF5T7Pb613C31BJVj74WYx4Pytj/lmH+PqjkqoNNkQ"; key-path = "/state/master-key/key"; }; + initrd-ip = "10.0.5.111"; } diff --git a/config/hosts/zbox.nix b/config/hosts/zbox.nix index 806dc7e..3486ed2 100644 --- a/config/hosts/zbox.nix +++ b/config/hosts/zbox.nix @@ -22,4 +22,5 @@ public-key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDsn68vDKV4jnBuICSDX/2Gpnshbrz0r9t4lXIke1vqh"; key-path = "/state/master-key/key"; }; + initrd-ip = "10.0.5.110"; } diff --git a/config/sites.nix b/config/sites.nix index 7056529..c9cf998 100644 --- a/config/sites.nix +++ b/config/sites.nix @@ -6,7 +6,7 @@ gateway-v4 = "10.0.0.1"; nameservers = [ "10.0.0.1" ]; network = "10.0.0.0/16"; - dynamic-network = "10.0.1.0/24"; + dynamic-network = "10.0.100.0/24"; timezone = "America/Los_Angeles"; gateway-host = "nostromo"; deploy-pubkeys = [ diff --git a/config/users.nix b/config/users.nix index 248ab43..ed3c2bf 100644 --- a/config/users.nix +++ b/config/users.nix @@ -14,13 +14,9 @@ in { "$6$a1q2Duoe35hd5$IaZGXPfqyGv9uq5DQm7DZq0vIHsUs39sLktBiBBqMiwl/f/Z4jSvNZLJp9DZJYe5u2qGBYh1ca.jsXvQA8FPZ/"; ssh-authorized-keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDoWkjyeIfgwm0b78weToVYOQSD0RQ0qbNzpsN5NokbIFv2/980kLtnYrQEgIJ/JwMLlT3uJYacbCT5/a6Fb8oLxNpj0AF1EKaWZ3Rrlg72Sq+9SEwJwWWmZizX83sovMwUBMaUp6jWLhAhPpzBW5pfc5YWoc89wxGbELSwzgt5EgHbSJgvDnaHSp3fVaY01wfDXbL/oO160iNe7wv2HLMZu/FkWBkIjz6HmoGJJzYM89bUpHbyYG28lmCHB/8UPog5/BsjOn3/qupgf4zh6mMdMsXLvbR2jVwVjxcEMj9N5nCvc+Y3oi7Mij6VNrWbhkaAJMEzeMhWYrF3/pFQxUqG37aK3d0gw9kp5tMDLIlAPX4y1lfA87pIzoa0+Alql0CJQA1IJvp9SFG7lBmSthWQLmZvwwfoGg/ZjF6rOgsVoZ8TizpQnydWJDr6NboU9LL9Oa64OM5Rs0AU3cR2UbOF4QIcWFJ/7oDe3dOnfZ8QYqx9eXJyxoAUpDanaaTHYBiAKkeOBwQU+MVLKCcONKw9FZclf/1TpDB5b3/JeUFANjHQTv0UXA4YYU7iCx6H7XB4qwwtU9O19CGQYYfCfULX12/fRpYJw6VJaQWyyU4Bn5dk/dcB2nGI36jwbLMfhbUTIApujioAnd/GQIMakHEZ1+syPhMx9BxMkZb99B0A1Q== openpgp:0x4EC95B64" + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDGVez4of30f+j0cWKj5kYCKeFjyNsYvG9UbOMxF5hImD2lP5MSbFBv31gFgHjx3yCG4zQRZlpuyU5uWo0qIwe9N84/LcZcB9WrWKZXDmuof7zPFy0J+Hj+LVLDQI/mVXHNwkMhBMHpPrdwA05EYDAYCYklWT4cSByu10pHtST+olF8i+A+UQgUzgNZzdJVeiYZv6MBDTYsJWptGeDUkl2B0Es3gtbGYcCCfnyS3RC7DIXlDo3NBbAr7WaHY2MBbT+R/+jicn9E3IY3NCM5jENxqmvHy9MDsxEEYgFNm7IDwq4V1VRUWy277YsvRbmEaHb+osOA5u1VNN4z3UftOZcSZgR5C/vR71cENXoPt1YQpCzu7i38ojtvL+tDVEKT7sIovrQw8q1sszNlW2nXh8RSPiIq5TMnrV73MP0egKcr9n3tfxwi1BIkLjvfom/02BkTK9R9v+VMNhYU1YwROhORCiMIgoxUGiUvtH8u38JGr7E0hhMoAjCE5k80WPUivl0= niten@socrates" ]; home-directory = "/home/niten"; - # home-manager-generator = home-generator.generate-config { - # username = "niten"; - # user-email = "niten@fudo.org"; - # home-dir = "/home/niten"; - # }; k5login = [ "niten/root@FUDO.ORG" "niten/admin@FUDO.ORG" @@ -195,11 +191,6 @@ in { ldap-hashed-passwd = "{MD5}iecbyMpyVkmOaMBzSFy58Q=="; login-hashed-passwd = "$6$C8lYHrK7KvdKm/RE$cHZ2hg5gEOEjTV8Zoayik8sz5h.Vh0.ClCgOlQn8l/2Qx/qdxqZ7xCsAZ1GZ.IEyESfhJeJbjLpykXDwPpfVF0"; - # home-manager-generator = home-generator.generate-config { - # username = "xiaoxuan"; - # user-email = "xiaoxuan@fudo.org"; - # home-dir = "/home/fudo/xiaoxuan"; - # }; email = "xiaoxuan@fudo.org"; }; @@ -483,11 +474,6 @@ in { uid = 10115; primary-group = "informis"; common-name = "Viator"; - # home-manager-generator = home-generator.generate-config { - # username = "viator"; - # user-email = "viator@informis.land"; - # home-dir = "/home/viator"; - # }; ldap-hashed-passwd = "{SSHA}dF/5NGkafL8M1kpa3LYZKdh0Pc7a02gA"; login-hashed-passwd = "$6$a1q2Duoe35hd5$IaZGXPfqyGv9uq5DQm7DZq0vIHsUs39sLktBiBBqMiwl/f/Z4jSvNZLJp9DZJYe5u2qGBYh1ca.jsXvQA8FPZ/"; diff --git a/lib/default.nix b/lib/default.nix index f48fb3f..a54d000 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -20,6 +20,7 @@ with lib; { ./fudo/global.nix ./fudo/grafana.nix ./fudo/hosts.nix + ./fudo/initrd-network.nix ./fudo/ipfs.nix ./fudo/kdc.nix ./fudo/ldap.nix diff --git a/lib/fudo/hosts.nix b/lib/fudo/hosts.nix index 7986484..a5c9c59 100644 --- a/lib/fudo/hosts.nix +++ b/lib/fudo/hosts.nix @@ -106,8 +106,6 @@ in { autoPrune.enable = true; }; - boot.tmpOnTmpfs = host-cfg.tmp-on-tmpfs; - fudo = let try-attr = attr: set: if (hasAttr attr set) then set.${attr} else null; @@ -153,6 +151,8 @@ in { members = config.instance.local-admins; }; + boot.tmpOnTmpfs = host-cfg.tmp-on-tmpfs; + # programs.ssh.knownHosts = let # keyed-hosts = # filterAttrs (host: opts: opts.ssh-pubkeys != []) config.fudo.hosts; diff --git a/lib/fudo/initrd-network.nix b/lib/fudo/initrd-network.nix new file mode 100644 index 0000000..d2a3744 --- /dev/null +++ b/lib/fudo/initrd-network.nix @@ -0,0 +1,92 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + hostname = config.instance.hostname; + host-cfg = config.fudo.hosts.${hostname}; + ip = host-cfg.initrd-ip; + + 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 ed25519 -N "" -f $out/ssh_host_ed25519_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}/ssh_host_ed25519_key" | sed 's/^REMOVEME IN SSHFP //' >> $out/ssh_host_ed25519_key.sshfp + ''; + }; + + host-keys = genAttrs (attrNames config.instance.local-hosts) + (hostname: gen-host-keys hostname); + +in { + config = mkIf (ip != null) { + boot = { + kernelParams = [ + "ip=${ip}" + ]; + initrd = let + host-key-pkg = host-keys.${config.instance.hostname}; + host-privkey = "${key-pkg}/ssh_host_ed25519_key"; + initrd-keypath = "/var/run/secrets/ssh/ssh_host_ed25519_key"; + in { + secrets = { + "${initrd-keypath}" = host-privkey; + }; + + 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 = [ + initrd-keypath + ]; + }; + }; + }; + }; + + fudo = { + 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}/ssh_host_ed25519_key.sshfp"; + in map (sshfp: "${hostname} IN SSHFP ${sshfp}") sshfps) + host-keys; + }; + }; + }; +} diff --git a/lib/fudo/local-network.nix b/lib/fudo/local-network.nix index 55421b9..cbb7f44 100644 --- a/lib/fudo/local-network.nix +++ b/lib/fudo/local-network.nix @@ -74,13 +74,19 @@ in { default = [ ]; }; - network-definition = - let networkOpts = import ../types/network-definition.nix { inherit lib; }; - in mkOption { - type = submodule networkOpts; - description = "Definition of network to be served by local server."; - default = { }; - }; + network-definition = let + networkOpts = import ../types/network-definition.nix { inherit lib; }; + in mkOption { + type = submodule networkOpts; + description = "Definition of network to be served by local server."; + default = { }; + }; + + extra-records = mkOption { + type = listOf str; + description = "Extra records to add to the local zone."; + default = [ ]; + }; }; config = mkIf cfg.enable { @@ -224,6 +230,7 @@ in { ${join-lines (mapAttrsToList cnameRecord network.aliases)} ${join-lines network.verbatim-dns-records} ${pkgs.lib.fudo.dns.srvRecordsToBindZone network.srv-records} + ${join-lines cfg.extra-records} ''; }] ++ blockZones; }; diff --git a/lib/fudo/ssh.nix b/lib/fudo/ssh.nix index 2c8f254..2d573e4 100644 --- a/lib/fudo/ssh.nix +++ b/lib/fudo/ssh.nix @@ -51,8 +51,6 @@ in { filename = sshfp-filename hostname keypair; in read-lines "${fingerprint-derivation}/${filename}") keypairs; }) config.fudo.secrets.files.host-ssh-keypairs; - - }; services.openssh.hostKeys = map (keypair: { diff --git a/lib/types/host.nix b/lib/types/host.nix index 41eda4e..f186d5f 100644 --- a/lib/types/host.nix +++ b/lib/types/host.nix @@ -176,6 +176,38 @@ rec { }; android-dev = mkEnableOption "Enable ADB on the host."; + + # FIXME: This probably belongs elsewhere... + initrd-ip = mkOption { + type = nullOr str; + description = "IP to assign to the kernel/initrd, to allow access when boot fails."; + default = null; + }; + + initrd-ssh-keypair = let + keypair = { ... }: { + options = { + public-key = mkOption { + type = str; + description = "SSH public key."; + }; + + private-key = mkOption { + type = str; + description = "SSH private key."; + }; + + type = mkOption { + type = enum [ "rsa" "ecdsa" "ed25519" ]; + description = "SSH key type." + }; + }; + }; + in mkOption { + type = nullOr (submodule keypair); + description = "SSH Keypair to use for initrd."; + default = null; + }; }; }; }