From 4da2c85fb17ecc35c61c59b985f5bc1b9f847698 Mon Sep 17 00:00:00 2001
From: root <root@fudo.org>
Date: Sat, 3 Apr 2021 10:15:10 -0700
Subject: [PATCH 1/5] 'Fix' printer driver, set timezone

---
 config/sites/seattle.nix    | 3 +++
 lib/fudo/hosts.nix          | 2 ++
 packages/hll2380dw-cups.nix | 3 ++-
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/config/sites/seattle.nix b/config/sites/seattle.nix
index 0fd0a52..2a1a1b4 100644
--- a/config/sites/seattle.nix
+++ b/config/sites/seattle.nix
@@ -37,6 +37,9 @@ in {
   services.printing = {
     enable = true;
     drivers = [
+      pkgs.brlaser
+      pkgs.brgenml1lpr
+      pkgs.brgenml1cupswrapper
       pkgs.hll2380dw-cups
     ];
   };
diff --git a/lib/fudo/hosts.nix b/lib/fudo/hosts.nix
index b3ca95e..efcea43 100644
--- a/lib/fudo/hosts.nix
+++ b/lib/fudo/hosts.nix
@@ -138,6 +138,8 @@ in {
       hosts = { "127.0.0.1" = [ "${hostname}.${domain-name}" "${hostname}" ]; };
     };
 
+    time.timeZone = site.timezone;
+
     krb5.libdefaults.default_realm = domain.gssapi-realm;
 
     services.cron.mailto = domain.admin-email;
diff --git a/packages/hll2380dw-cups.nix b/packages/hll2380dw-cups.nix
index b0ed6dd..4e9059c 100644
--- a/packages/hll2380dw-cups.nix
+++ b/packages/hll2380dw-cups.nix
@@ -22,12 +22,13 @@ stdenv.mkDerivation rec {
           coreutils ghostscript gnugrep gnused
         ]}
     mkdir -p $out/lib/cups/filter/
-    ln -s $out/opt/brother/Printers/HLL2380DW/cupswrapper/brother_lpdwrapper_HLL2380W \
+    ln -s $out/opt/brother/Printers/HLL2380DW/cupswrapper/brother_lpdwrapper_HLL2380DW \
         $out/lib/cups/filter/brother_lpdwrapper_HLL2380DW
     ln -s $out/opt/brother/Printers/HLL2380DW/paperconfigml1 \
         $out/lib/cups/filter/
     mkdir -p $out/share/cups/model
     ln -s $out/opt/brother/Printers/HLL2380DW/cupswrapper/brother-HLL2380DW-cups-en.ppd $out/share/cups/model/
+    touch $out/HI
   '';
 
   meta = with stdenv.lib; {

From d850a71f357e5cc8088e58ad6fe8b33fc9560101 Mon Sep 17 00:00:00 2001
From: root <root@fudo.org>
Date: Mon, 5 Apr 2021 15:01:23 -0700
Subject: [PATCH 2/5] Changes...

---
 config/hosts.nix           | 16 +++++++
 config/profiles/common.nix | 14 ------
 home-manager/niten.nix     |  1 +
 lib/fudo/sites.nix         | 87 ++++++++++++++++++++++++++++++++------
 4 files changed, 92 insertions(+), 26 deletions(-)

diff --git a/config/hosts.nix b/config/hosts.nix
index 0012d47..ecc90d5 100644
--- a/config/hosts.nix
+++ b/config/hosts.nix
@@ -132,9 +132,17 @@
 
     spark = {
       description = "Niten's backup desktop.";
+      ssh-fingerprints = [
+        "1 1 d26812dee9b26a19a52c38d2b346442979093142"
+        "1 2 981db46fdd0ad1639651c700a527602425237c1d4999265372ed92e093a965b3"
+        "4 1 67fa0a36e51fd4a5ed2b71ff9817cb9a372d0a63"
+        "4 2 c17d46061d722e1e6c878341b8e3c0bf87ea6e0e1426c54a989107dfb604d81b"
+      ];
       rp = "niten";
       admin-email = "niten@fudo.org";
       enable-gui = true;
+      ssh-pubkey =
+        "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO67/CNhiG9UynaflmZUUK7f3O/GwFpnXri/PxpgHcPa";
     };
 
     upstairs-desktop = {
@@ -153,9 +161,17 @@
 
     zbox = {
       description = "Niten's primary desktop.";
+      ssh-fingerprints = [
+        "1 1 3aff8c913615c81512be3a42fc83daeb90d94a3d"
+        "1 2 39c7500f08022963f3f2db4f3ebb7aad08c92d0cc937984ba86c4eba204ed493"
+        "4 1 862842d99f5afb33db4f073d2f3d1154c6417110"
+        "4 2 373536d3d59f2354b1bfc25c02120c86e9b3af574b6c1984210d9e9c1d5244e3"
+      ];
       rp = "niten";
       admin-email = "niten@fudo.org";
       enable-gui = true;
+      ssh-pubkey =
+        "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKVhHfRf2086SAqOmu2dNbsJI9UUAQWop+1lrcJlNgl8";
     };
   };
 }
diff --git a/config/profiles/common.nix b/config/profiles/common.nix
index 19df54d..647bb48 100644
--- a/config/profiles/common.nix
+++ b/config/profiles/common.nix
@@ -53,20 +53,6 @@ in {
         GSSAPIKeyExchange yes
         GSSAPIStoreCredentialsOnRekey yes
       '';
-      # FIXME: add all the hosts we know about
-      knownHosts = {
-        # publicKey, hostNames
-      };
-    };
-
-    lshd = {
-      enable = true;
-      portNumber = 2112;
-      rootLogin = true;
-      srpKeyExchange = true;
-      tcpForwarding = false;
-      publicKeyAuthentication = true;
-      passwordAuthentication = false;
     };
 
     fail2ban = {
diff --git a/home-manager/niten.nix b/home-manager/niten.nix
index b883a69..58eeb6c 100644
--- a/home-manager/niten.nix
+++ b/home-manager/niten.nix
@@ -26,6 +26,7 @@ let
     imagemagick
     ipfs
     iptables
+    jdk
     jq
     leiningen
     libisofs
diff --git a/lib/fudo/sites.nix b/lib/fudo/sites.nix
index 61179bb..03599be 100644
--- a/lib/fudo/sites.nix
+++ b/lib/fudo/sites.nix
@@ -2,58 +2,62 @@
 
 with lib;
 let
+  hostname = config.instance.hostname;
+  site-name = config.fudo.hosts.${hostname}.site;
+  site-cfg = config.fudo.sites.${site-name};
+
   siteOpts = { site, ... }: {
-    options = {
+    options = with types; {
       site = mkOption {
-        type = types.str;
+        type = str;
         description = "Site name.";
         default = site;
       };
 
       network = mkOption {
-        type = types.str;
+        type = str;
         description = "Network to be treated as local.";
       };
 
       dynamic-network = mkOption {
-        type = with types; nullOr str;
+        type = nullOr str;
         description = "Network to be allocated by DHCP.";
         default = null;
       };
 
       gateway-v4 = mkOption {
-        type = with types; nullOr str;
+        type = nullOr str;
         description = "Gateway to use for public ipv4 internet access.";
         default = null;
       };
 
       gateway-v6 = mkOption {
-        type = with types; nullOr str;
+        type = nullOr str;
         description = "Gateway to use for public ipv6 internet access.";
         default = null;
       };
 
       gateway-host = mkOption {
-        type = with types; nullOr str;
+        type = nullOr str;
         description = "Identity of the host to act as a gateway.";
         default = null;
       };
 
       local-groups = mkOption {
-        type = with types; listOf str;
+        type = listOf str;
         description = "List of groups which should exist at this site.";
         default = [ ];
       };
 
       local-users = mkOption {
-        type = with types; listOf str;
+        type = listOf str;
         description =
           "List of users which should exist on all hosts at this site.";
         default = [ ];
       };
 
       local-admins = mkOption {
-        type = with types; listOf str;
+        type = listOf str;
         description =
           "List of admin users which should exist on all hosts at this site.";
         default = [ ];
@@ -63,16 +67,34 @@ let
         mkEnableOption "Enable site-wide monitoring with prometheus.";
 
       nameservers = mkOption {
-        type = with types; listOf str;
+        type = listOf str;
         description = "List of nameservers to be used by hosts at this site.";
         default = [ ];
       };
 
       timezone = mkOption {
-        type = types.str;
+        type = str;
         description = "Timezone of the site.";
         example = "America/Winnipeg";
       };
+
+      deploy-pubkey = mkOption {
+        type = nullOr str;
+        description = "SSH pubkey of site deploy key. Used by dropbear daemon.";
+        default = null;
+      };
+
+      dropbear-rsa-key-path = mkOption {
+        type = str;
+        description = "Location of Dropbear RSA key.";
+        default = "/etc/dropbear/host_rsa_key";
+      };
+
+      dropbear-ecdsa-key-path = mkOption {
+        type = str;
+        description = "Location of Dropbear ECDSA key.";
+        default = "/etc/dropbear/host_ecdsa_key";
+      };
     };
   };
 
@@ -82,4 +104,45 @@ in {
     description = "Site configurations for all sites known to the system.";
     default = { };
   };
+
+  config = mkIf (site-cfg.deploy-pubkey != null) {
+    environment.etc."dropbear/authorized_keys" = {
+      text = "root@deploy ${site-cfg.deploy-pubkey}";
+      mode = "0400";
+    };
+
+    systemd.services = let dropbear-port = 2112;
+    in {
+
+      dropbear-init = {
+        wantedBy = [ "multi-user.target" ];
+        script = ''
+          if [ ! -d /etc/dropbear ]; then
+            mkdir /etc/dropbear
+            chmod 700 /etc/dropbear
+          fi
+
+          if [ ! -f ${site-cfg.dropbear-rsa-key-path} ]; then
+            ${pkgs.dropbear}/bin/dropbearkey -t rsa -f ${site-cfg.dropbear-rsa-key-path}
+            ${pkgs.coreutils}/bin/chmod 0400 ${site-cfg.dropbear-rsa-key-path}
+          fi
+
+          if [ ! -f ${site-cfg.dropbear-ecdsa-key-path} ]; then
+            ${pkgs.dropbear}/bin/dropbearkey -t ecdsa -f ${site-cfg.dropbear-ecdsa-key-path}
+            ${pkgs.coreutils}/bin/chmod 0400 ${site-cfg.dropbear-ecdsa-key-path}
+          fi
+        '';
+      };
+
+      dropbear = {
+        requires = [ "dropbear-init.service" ];
+        wantedBy = [ "multi-user.target" ];
+        after = [ "network.target" ];
+        serviceConfig = {
+          type = "simple";
+          ExecStart = "${pkgs.dropbear} -F -m -s -j -k -p ${dropbear-port}";
+        };
+      };
+    };
+  };
 }

From 555fcd869eeeac9416706b375299d0a381779390 Mon Sep 17 00:00:00 2001
From: Root <root@fudo.org>
Date: Mon, 5 Apr 2021 15:44:45 -0700
Subject: [PATCH 3/5] Added limina

---
 config/hardware/limina.nix       | 112 +++++++++++++++++++++++++++++++
 config/hosts/limina.nix          |  56 ++++++++++++++++
 config/networks/sea.fudo.org.nix |   4 ++
 config/profiles/server.nix       |   6 --
 4 files changed, 172 insertions(+), 6 deletions(-)
 create mode 100644 config/hardware/limina.nix
 create mode 100644 config/hosts/limina.nix

diff --git a/config/hardware/limina.nix b/config/hardware/limina.nix
new file mode 100644
index 0000000..afbc313
--- /dev/null
+++ b/config/hardware/limina.nix
@@ -0,0 +1,112 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+{
+  imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ];
+
+  boot = {
+    initrd = {
+      availableKernelModules =
+        [ "ahci" "xhci_pci" "ehci_pci" "usbhid" "usb_storage" "sd_mod" ];
+      kernelModules = [ ];
+    };
+    kernelModules = [ "kvm-intel" ];
+    extraModulePackages = [ ];
+    loader = {
+      systemd-boot.enable = true;
+      efi.canTouchEfiVariables = true;
+    };
+
+    supportedFilesystems = [ "zfs" ];
+    kernelPackages = pkgs.linuxPackages_latest;
+  };
+
+  fileSystems = {
+    "/boot" = {
+      device = "/dev/disk/by-label/BOOT";
+      fsType = "vfat";
+    };
+
+    "/" = {
+      device = "zroot/transient/root";
+      fsType = "zfs";
+    };
+
+    "/nix" = {
+      device = "zroot/transient/nix";
+      fsType = "zfs";
+    };
+
+    "/var/log" = {
+      device = "zroot/transient/logs";
+      fsType = "zfs";
+      neededForBoot = true;
+    };
+
+    "/home" = {
+      device = "zroot/persistent/home";
+      fsType = "zfs";
+    };
+
+    "/state" = {
+      device = "zroot/persistent/state";
+      fsType = "zfs";
+    };
+  };
+
+  services.zfs.autoScrub.enable = true;
+
+  swapDevices = [{ device = "/dev/disk/by-label/swap"; }];
+
+  nix.maxJobs = lib.mkDefault 4;
+
+  hardware.bluetooth.enable = false;
+
+  networking = {
+    hostId = substring 0 8 (fileContents /state/etc/machine-id);
+
+    macvlans = {
+      extif0 = {
+        interface = "enp1s0";
+        mode = "bridge";
+      };
+      intif0 = {
+        interface = "enp2s0";
+        mode = "bridge";
+      };
+      intif1 = {
+        interface = "enp3s0";
+        mode = "bridge";
+      };
+      intif2 = {
+        interface = "enp4s0";
+        mode = "bridge";
+      };
+    };
+
+    interfaces = {
+      enp1s0.useDHCP = false;
+      enp2s0.useDHCP = false;
+      enp3s0.useDHCP = false;
+      enp4s0.useDHCP = false;
+      
+      # output of: echo limina-${if}|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/'
+      extif0 = {
+        macAddress = "02:fd:79:94:a2:a8";
+        useDHCP = true;
+      };
+
+      intif0 = {
+        macAddress = "02:dc:59:b4:a7:8c";
+      };
+
+      intif1 = {
+        macAddress = "02:df:43:1d:8a:63";
+      };
+
+      intif2 = {
+        macAddress = "02:55:d9:05:23:36";
+      };
+    };
+  };
+}
diff --git a/config/hosts/limina.nix b/config/hosts/limina.nix
new file mode 100644
index 0000000..9743b00
--- /dev/null
+++ b/config/hosts/limina.nix
@@ -0,0 +1,56 @@
+{ config, lib, pkgs, ... }:
+
+with lib; {
+  config = {
+  
+    # TODO: remove?
+    nixpkgs.config.permittedInsecurePackages = [
+      "openssh-with-gssapi-8.4p1" # CVE-2021-28041
+    ];
+  
+    environment.etc = {
+      nixos.source = "/state/nixos";
+      adjtime.source = "/state/etc/adjtime";
+      NIXOS.source = "/state/etc/NIXOS";
+      machine-id.source = "/state/etc/machine-id";
+      "host-config.nix".source = "/state/etc/host-config.nix";
+    };
+
+    system.stateVersion = "20.09";
+
+    boot.initrd.postDeviceCommands = lib.mkAfter ''
+      ${pkgs.zfs}/bin/zfs rollback -r zroot/transient/root@blank
+    '';
+
+    security.sudo.extraConfig = ''
+      # rollback results in sudo lectures after each reboot
+      Defaults lecture = never
+    '';
+
+    systemd.tmpfiles.rules = [
+      "L /root/.gnupg - - - - /state/root/gnupg"
+      "L /root/.emacs.d - - - - /state/root/emacs.d"
+      "L /root/.ssh/id_rsa - - - - /state/root/ssh/id_rsa"
+      "L /root/.ssh/id_rsa.pub - - - - /state/root/ssh/id_rsa.pub"
+      "L /root/.ssh/known_hosts - - - - /state/root/ssh/known_hosts"
+      "L /etc/ssh/ssh_host_ed25519_key - - - - /state/ssh/ssh_host_ed25519_key"
+      "L /etc/ssh/ssh_host_rsa_key - - - - /state/ssh/ssh_host_rsa_key"
+    ];
+
+    services = {
+      openssh = {
+        hostKeys = [
+          {
+            path = "/state/ssh/ssh_host_ed25519_key";
+            type = "ed25519";
+          }
+          {
+            path = "/state/ssh/ssh_host_rsa_key";
+            type = "rsa";
+            bits = 4096;
+          }
+        ];
+      };
+    };
+  };
+}
diff --git a/config/networks/sea.fudo.org.nix b/config/networks/sea.fudo.org.nix
index dd22863..3cc9857 100644
--- a/config/networks/sea.fudo.org.nix
+++ b/config/networks/sea.fudo.org.nix
@@ -67,6 +67,10 @@ in {
   };
 
   hosts = {
+    limina = {
+      ip-address = "10.0.0.6";
+      mac-address = "02:fd:79:94:a2:a8";
+    };    
     nostromo = {
       ip-address = "10.0.0.1";
       mac-address = "46:54:76:06:f1:10";
diff --git a/config/profiles/server.nix b/config/profiles/server.nix
index a8cd609..2803c7c 100644
--- a/config/profiles/server.nix
+++ b/config/profiles/server.nix
@@ -4,10 +4,6 @@ with lib;
 let
   serverPackages = with pkgs; [
     emacs-nox
-    ldns
-    ldns.examples
-    jdk14_headless
-    racket-minimal
     reboot-if-necessary
     test-config
   ];
@@ -55,8 +51,6 @@ in {
   config = {
     environment = {
       systemPackages = serverPackages;
-
-      # noXlibs = lib.mkForce true;
     };
 
     system.autoUpgrade.enable = false;

From 418c04170cd6dd1bc36ce41661e7a92da77f5803 Mon Sep 17 00:00:00 2001
From: Root <root@fudo.org>
Date: Wed, 7 Apr 2021 14:03:52 -0700
Subject: [PATCH 4/5] Switch to using a common hostconfig at build and config
 time.

---
 .../{domains => domain-config}/fudo.org.nix   |   0
 .../informis.land.nix                         |   0
 .../rus.selby.ca.nix                          |   0
 .../sea.fudo.org.nix                          |   0
 config/hardware/limina.nix                    |  24 +--
 config/host-config/atom.nix                   |   9 +
 config/host-config/clunk.nix                  | 168 +++++++++++++++
 config/host-config/france.nix                 | 179 ++++++++++++++++
 config/host-config/lambda.nix                 |  32 +++
 config/host-config/limina.nix                 | 185 +++++++++++++++++
 config/host-config/nostromo.nix               | 169 +++++++++++++++
 config/host-config/plato.nix                  |  50 +++++
 config/host-config/spark.nix                  |  16 ++
 config/host-config/zbox.nix                   |  19 ++
 config/hosts.nix                              | 185 ++---------------
 config/hosts/atom.nix                         |  14 +-
 config/hosts/clunk.nix                        | 181 ++--------------
 config/hosts/downstairs-desktop.nix           |  18 ++
 config/hosts/france.nix                       | 194 ++----------------
 config/hosts/lambda.nix                       |  45 ++--
 config/hosts/limina.nix                       |  70 ++-----
 config/hosts/nostromo.nix                     | 184 ++---------------
 config/hosts/plato.nix                        |  64 ++----
 config/hosts/procul.nix                       |   4 +
 config/hosts/pselby-work.nix                  |   3 +
 config/hosts/spark.nix                        |  24 +--
 config/hosts/upstairs-desktop.nix             |  13 ++
 config/hosts/zbox.nix                         |  27 +--
 .../common-ui.nix                             |   0
 .../{profiles => profile-config}/common.nix   |   0
 .../{profiles => profile-config}/desktop.nix  |   0
 .../{profiles => profile-config}/laptop.nix   |   0
 .../{profiles => profile-config}/server.nix   |   0
 .../joes-datacenter-0.nix                     |   0
 config/{sites => site-config}/portage.nix     |   0
 config/{sites => site-config}/russell.nix     |   0
 config/{sites => site-config}/seattle.nix     |   0
 configuration.nix                             |   3 -
 initialize.nix                                |  21 +-
 lib/fudo/hosts.nix                            |   2 +-
 40 files changed, 1015 insertions(+), 888 deletions(-)
 rename config/{domains => domain-config}/fudo.org.nix (100%)
 rename config/{domains => domain-config}/informis.land.nix (100%)
 rename config/{domains => domain-config}/rus.selby.ca.nix (100%)
 rename config/{domains => domain-config}/sea.fudo.org.nix (100%)
 create mode 100644 config/host-config/atom.nix
 create mode 100644 config/host-config/clunk.nix
 create mode 100644 config/host-config/france.nix
 create mode 100644 config/host-config/lambda.nix
 create mode 100644 config/host-config/limina.nix
 create mode 100644 config/host-config/nostromo.nix
 create mode 100644 config/host-config/plato.nix
 create mode 100644 config/host-config/spark.nix
 create mode 100644 config/host-config/zbox.nix
 create mode 100644 config/hosts/downstairs-desktop.nix
 create mode 100644 config/hosts/procul.nix
 create mode 100644 config/hosts/pselby-work.nix
 create mode 100644 config/hosts/upstairs-desktop.nix
 rename config/{profiles => profile-config}/common-ui.nix (100%)
 rename config/{profiles => profile-config}/common.nix (100%)
 rename config/{profiles => profile-config}/desktop.nix (100%)
 rename config/{profiles => profile-config}/laptop.nix (100%)
 rename config/{profiles => profile-config}/server.nix (100%)
 rename config/{sites => site-config}/joes-datacenter-0.nix (100%)
 rename config/{sites => site-config}/portage.nix (100%)
 rename config/{sites => site-config}/russell.nix (100%)
 rename config/{sites => site-config}/seattle.nix (100%)

diff --git a/config/domains/fudo.org.nix b/config/domain-config/fudo.org.nix
similarity index 100%
rename from config/domains/fudo.org.nix
rename to config/domain-config/fudo.org.nix
diff --git a/config/domains/informis.land.nix b/config/domain-config/informis.land.nix
similarity index 100%
rename from config/domains/informis.land.nix
rename to config/domain-config/informis.land.nix
diff --git a/config/domains/rus.selby.ca.nix b/config/domain-config/rus.selby.ca.nix
similarity index 100%
rename from config/domains/rus.selby.ca.nix
rename to config/domain-config/rus.selby.ca.nix
diff --git a/config/domains/sea.fudo.org.nix b/config/domain-config/sea.fudo.org.nix
similarity index 100%
rename from config/domains/sea.fudo.org.nix
rename to config/domain-config/sea.fudo.org.nix
diff --git a/config/hardware/limina.nix b/config/hardware/limina.nix
index afbc313..6c970d8 100644
--- a/config/hardware/limina.nix
+++ b/config/hardware/limina.nix
@@ -1,9 +1,10 @@
 { config, lib, pkgs, ... }:
 
-with lib;
-{
+with lib; {
   imports = [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix> ];
 
+  system.stateVersion = "20.09";
+
   boot = {
     initrd = {
       availableKernelModules =
@@ -89,24 +90,15 @@ with lib;
       enp2s0.useDHCP = false;
       enp3s0.useDHCP = false;
       enp4s0.useDHCP = false;
-      
+
       # output of: echo limina-${if}|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/'
-      extif0 = {
-        macAddress = "02:fd:79:94:a2:a8";
-        useDHCP = true;
-      };
+      extif0 = { macAddress = "02:fd:79:94:a2:a8"; };
 
-      intif0 = {
-        macAddress = "02:dc:59:b4:a7:8c";
-      };
+      intif0 = { macAddress = "02:dc:59:b4:a7:8c"; };
 
-      intif1 = {
-        macAddress = "02:df:43:1d:8a:63";
-      };
+      intif1 = { macAddress = "02:df:43:1d:8a:63"; };
 
-      intif2 = {
-        macAddress = "02:55:d9:05:23:36";
-      };
+      intif2 = { macAddress = "02:55:d9:05:23:36"; };
     };
   };
 }
diff --git a/config/host-config/atom.nix b/config/host-config/atom.nix
new file mode 100644
index 0000000..abc7d91
--- /dev/null
+++ b/config/host-config/atom.nix
@@ -0,0 +1,9 @@
+{ config, lib, pkgs, ... }:
+
+{
+  fudo.laptop.use-network-manager = false;
+
+  fudo.slynk.enable = true;
+
+  services.xserver = { videoDrivers = [ "nvidia" ]; };
+}
diff --git a/config/host-config/clunk.nix b/config/host-config/clunk.nix
new file mode 100644
index 0000000..5cd326f
--- /dev/null
+++ b/config/host-config/clunk.nix
@@ -0,0 +1,168 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  primary-ip = "10.0.0.1";
+
+  dns-proxy-port = 5335;
+
+  host-packages = with pkgs; [
+    nixops
+  ];
+
+  site-name = config.fudo.hosts.${config.instance.hostname}.site;
+  site = config.fudo.site.${site-name};
+
+in {
+  system = {
+    # # DO force all DNS traffic to use the local server
+    # activationScripts.force-local-dns = let
+    #   wifi-ip =
+    #     config.fudo.networks."rus.selby.ca".hosts.google-wifi.ipv4-address;
+    # in ''
+    #   ${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p udp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53
+    #   ${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p tcp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53
+    # '';
+  };
+
+  environment.systemPackages = host-packages;
+
+  fudo.local-network = let
+    host-config = config.fudo.hosts.${config.instance.hostname};
+    site-name = host-config.site;
+    site = config.fudo.sites.${site-name};
+    domain-name = host-config.domain;
+    domain = config.fudo.domains.${domain-name};
+
+  in {
+    enable = true;
+    # NOTE: requests go:
+    #  - local bind instance
+    #  - pi-hole
+    #  - DoH resolver
+    domain = domain-name;
+    dns-servers = [ primary-ip ];
+    gateway = primary-ip;
+    dhcp-interfaces = [ "intif0" ];
+    dns-listen-ips = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ];
+    recursive-resolver = "${primary-ip} port 5353";
+    network = site.network;
+    dhcp-dynamic-network = site.dynamic-network;
+    search-domains = [ "selby.ca" ];
+    enable-reverse-mappings = true;
+    network-definition = config.fudo.networks."rus.selby.ca";
+  };
+
+  networking = {
+    firewall = {
+      enable = true;
+      trustedInterfaces = [ "intif0" "docker0" ];
+      allowedTCPPorts = [ 22 ];
+    };
+
+    interfaces = {
+      enp1s0.useDHCP = true;
+
+      enp2s0.useDHCP = false;
+      enp3s0.useDHCP = false;
+      enp4s0.useDHCP = false;
+
+      intif0 = {
+        useDHCP = false;
+        ipv4.addresses = [{
+          address = primary-ip;
+          prefixLength = 22;
+        }];
+      };
+    };
+
+    nat = {
+      enable = true;
+      externalInterface = "enp1s0";
+      internalInterfaces = [ "intif0" ];
+      forwardPorts = [{
+        destination = "127.0.0.1:53";
+        sourcePort = 53;
+        proto = "udp";
+      }];
+    };
+  };
+
+  fudo = {
+    garbage-collector = {
+      enable = true;
+      timing = "weekly";
+    };
+
+    auth.kdc = {
+      enable = true;
+      realm = "RUS.SELBY.CA";
+      bind-addresses = [ "10.0.0.1" "127.0.0.1" "::1" ];
+      acl = {
+        "niten" = { perms = [ "add" "change-password" "list" ]; };
+        "*/root" = { perms = [ "all" ]; };
+      };
+    };
+
+    secure-dns-proxy = {
+      enable = true;
+      listen-port = dns-proxy-port;
+      upstream-dns =
+        [ "https://1.1.1.1/dns-query" "https://1.0.0.1/dns-query" ];
+      bootstrap-dns = "1.1.1.1";
+      allowed-networks =
+        [ "1.1.1.1/32" "1.0.0.1/32" "10.0.0.0/16" "localhost" "link-local" ];
+      listen-ips = [ primary-ip ];
+    };
+  };
+
+  virtualisation = {
+    docker = {
+      enable = true;
+      autoPrune.enable = true;
+      enableOnBoot = true;
+    };
+
+    oci-containers = {
+      backend = "docker";
+      containers = {
+        pihole = {
+          image = "pihole/pihole:v5.7";
+          autoStart = true;
+          ports = [ "5353:53/tcp" "5353:53/udp" "3080:80/tcp" ];
+          environment = {
+            # ServerIP = primary-ip;
+            VIRTUAL_HOST = "dns-hole.rus.selby.ca";
+            DNS1 = "${primary-ip}#${toString dns-proxy-port}";
+          };
+          volumes = [
+            "/srv/pihole/etc-pihole/:/etc/pihole/"
+            "/srv/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/"
+          ];
+        };
+      };
+    };
+  };
+
+  services.nginx = {
+    enable = true;
+
+    recommendedOptimisation = true;
+    recommendedGzipSettings = true;
+    recommendedProxySettings = true;
+
+    virtualHosts = {
+      "dns-hole.rus.selby.ca" = {
+        serverAliases = [
+          "pihole.rus.selby.ca"
+          "hole.rus.selby.ca"
+          "pihole"
+          "dns-hole"
+          "hole"
+        ];
+
+        locations."/" = { proxyPass = "http://127.0.0.1:3080"; };
+      };
+    };
+  };
+}
diff --git a/config/host-config/france.nix b/config/host-config/france.nix
new file mode 100644
index 0000000..f4fe89a
--- /dev/null
+++ b/config/host-config/france.nix
@@ -0,0 +1,179 @@
+{ config, lib, pkgs, ... }:
+
+let
+  primary-ip = "208.81.3.117";
+  hostname = config.instance.hostname;
+  domain-name = config.fudo.hosts.${hostname}.domain;
+  domain = config.fudo.domains.${domain-name};
+  host-fqdn = "${hostname}.${domain-name}";
+  mail-hostname = "mail.fudo.org";
+
+in {
+  imports = [ ./france/postgresql.nix ];
+
+  config = {
+    fudo = {
+      auth = {
+        ldap = {
+          enable = true;
+          base = "dc=fudo,dc=org";
+          organization = "Fudo";
+          rootpw-file = "FIXME";
+          kerberos-host = host-fqdn;
+          kerberos-keytab = "FIXME";
+
+          sslCert = "FIXME";
+          sslKey = "FIXME";
+          sslCaCert = "FIXME";
+
+          listen-uris = [ "ldap:///" "ldaps:///" "ldapi:///" ];
+
+          users = config.fudo.users;
+          groups = config.fudo.groups;
+          system-users = config.fudo.system-users;
+        };
+
+        kdc = let realm = "FUDO.ORG";
+        in {
+          enable = true;
+          database-path = "FIXME";
+          realm = realm;
+          mkey-file = "FIXME";
+          acl = [
+            {
+              principal = "pam_migrate/*.fudo.org@${realm}";
+              access = "add";
+            }
+            {
+              principal = "host/*.fudo.org@${realm}";
+              access = "add";
+            }
+          ] ++ (concatMap (user: [
+            {
+              principal = "${user}@${realm}";
+              access = "add,list,modify";
+            }
+            {
+              principal = "${user}/root@${realm}";
+              access = "all";
+            }
+          ]) domain.admin-users);
+          bind-addresses = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ];
+        };
+      };
+
+      prometheus = {
+        enable = true;
+        hostname = "metrics.fudo.org";
+        service-discovery-dns = let dns-root = "_metrics._tcp.fudo.org";
+        in {
+          node = [ "node.${dns-root}" ];
+          postfix = [ "postfix.${dns-root}" ];
+          dovecot = [ "dovecot.${dns-root}" ];
+          rspamd = [ "rspamd.${dns-root}" ];
+        };
+      };
+
+      postgresql = {
+        enable = true;
+        # FIXME: ssl-private-key && ssl certificate
+        keytab = "/srv/postgres/secure/postgres.keytab";
+        local-networks = getHostLocalNetworks hostname;
+        admin-users = domain.admin-users;
+      };
+
+      client.dns = {
+        enable = true;
+        ipv4 = true;
+        ipv6 = true;
+        user = "FIXME";
+        external-interface = "extif0";
+        password-file = "FIXME";
+      };
+
+      mail-server = domain.mail-config // {
+        enableContainer = true;
+        monitoring = true;
+
+        hostname = mail-hostname;
+
+        state-directory = "FIXME";
+        mail-directory = "FIXME";
+
+        dovecot.ldap = {
+          reader-dn = "FIXME";
+          reader-password = "FIXME";
+          server-urls = [ "FIXME" ];
+        };
+
+        clamav.enable = true;
+        dkim.signing = true;
+      };
+
+      git = {
+        enable = true;
+        hostname = "git.fudo.org";
+        site-name = "Fudo Git";
+        user = "FIXME";
+        database = {
+          user = "FIXME";
+          password-file = "FIXME";
+          hostname = "127.0.0.1";
+          name = "FIXME";
+        };
+        repository-dir = "FIXME";
+        state-dir = "FIXME";
+        ssh = {
+          listen-ip = git-server-ip;
+          listen-port = 22;
+        };
+      };
+
+      minecraft-server = {
+        enable = true;
+        package = pkgs.minecraft-current;
+        data-dir = "FIXME";
+        world-name = "selbyland";
+        motd = "Welcome to the Selby Minecraft server.";
+      };
+    };
+
+    networking = {
+      intif0 = {
+        ipv4.addresses = [{
+          address = "192.168.11.1";
+          prefixLength = 24;
+        }];
+      };
+      extif0 = {
+        ipv4.addresses = [
+          {
+            address = primary-ip;
+            prefixLength = 28;
+          }
+          {
+            address = git-server-ip;
+            prefixLength = 32;
+          }
+        ];
+      };
+    };
+
+    services = {
+      nginx = {
+        enable = true;
+        recommendedGzipSettings = true;
+        recommendedOptimisations = true;
+        recommendedTlsSettings = true;
+        recommendedProxySettings = true;
+
+        virtualHosts = {
+          "mail.fudo.org" = {
+            enableACME = true;
+            locations."/".return = "301 https://webmail.fudo.org$request_uri";
+          };
+        };
+      };
+    };
+  };
+}
diff --git a/config/host-config/lambda.nix b/config/host-config/lambda.nix
new file mode 100644
index 0000000..90349aa
--- /dev/null
+++ b/config/host-config/lambda.nix
@@ -0,0 +1,32 @@
+{ config, lib, pkgs, ... }:
+
+let primary-ip = "10.0.0.3";
+
+in {
+  fudo.slynk.enable = true;
+
+  networking = {
+    interfaces = {
+      enp3s0f0.useDHCP = false;
+      enp3s0f1.useDHCP = false;
+      enp4s0f0.useDHCP = false;
+      enp4s0f1.useDHCP = false;
+
+      extif0 = {
+        useDHCP = false;
+        ipv4.addresses = [{
+          address = primary-ip;
+          prefixLength = 22;
+        }];
+      };
+    };
+  };
+
+  fudo.ipfs = {
+    enable = true;
+    users = [ "niten" ];
+    api-address = "/ip4/${primary-ip}/tcp/5001";
+  };
+
+  # TODO: add camera
+}
diff --git a/config/host-config/limina.nix b/config/host-config/limina.nix
new file mode 100644
index 0000000..c716753
--- /dev/null
+++ b/config/host-config/limina.nix
@@ -0,0 +1,185 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  primary-ip = "10.0.0.6";
+
+  host-config = config.fudo.hosts.${config.instance.hostname};
+  site-name = host-config.site;
+  site = config.fudo.sites.${site-name};
+  domain-name = host-config.domain;
+  domain = config.fudo.domains.${domain-name};
+
+  dns-proxy-port = 5335;
+
+in {
+  config = {
+
+    # TODO: remove?
+    nixpkgs.config.permittedInsecurePackages = [
+      "openssh-with-gssapi-8.4p1" # CVE-2021-28041
+    ];
+
+    networking = {
+      firewall = {
+        enable = true;
+        trustedInterfaces = [ "intif0" "intif1" "intif2" "lo" ];
+        allowedTCPPorts = [ 22 ];
+      };
+
+      interfaces = {
+        extif0 = { useDHCP = true; };
+
+        intif0 = {
+          useDHCP = false;
+          ipv4.addresses = [{
+            address = primary-ip;
+            prefixLength = 22;
+          }];
+        };
+        intif1 = { useDHCP = false; };
+        intif2 = { useDHCP = false; };
+      };
+
+      nat = {
+        enable = true;
+        externalInterface = "extif0";
+        internalInterfaces = [ "intif0" ];
+      };
+    };
+
+    fudo = {
+      local-network = {
+        enable = false;
+        domain = domain-name;
+        dns-servers = [ primary-ip ];
+        gateway = primary-ip;
+        dhcp-interfaces = [ "intif0" ];
+        dns-listen-ips = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ];
+        recursive-resolver = "1.1.1.1";
+        network = site.network;
+        dhcp-dynamic-network = site.dynamic-network;
+        search-domains = [ domain-name "fudo.org" ];
+        enable-reverse-mappings = true;
+        network-definition = config.fudo.networks.${domain-name};
+      };
+
+      client.dns = {
+        enable = true;
+        ipv4 = true;
+        ipv6 = true;
+        user = "fudo-client";
+        external-interface = "extif0";
+        password-file = "/srv/client/secure/client.passwd";
+      };
+
+      garbage-collector = {
+        enable = true;
+        timing = "weekly";
+      };
+
+      secure-dns-proxy = {
+        enable = true;
+        listen-port = dns-proxy-port;
+        upstream-dns =
+          [ "https://1.1.1.1/dns-query" "https://1.0.0.1/dns-query" ];
+        bootstrap-dns = "1.1.1.1";
+        allowed-networks =
+          [ "1.1.1.1/32" "1.0.0.1/32" "10.0.0.0/16" "localhost" "link-local" ];
+        listen-ips = [ primary-ip ];
+      };
+    };
+
+    virtualisation = {
+      docker = {
+        enable = true;
+        autoPrune.enable = true;
+        enableOnBoot = true;
+      };
+
+      oci-containers = {
+        backend = "docker";
+        containers = {
+          pihole = {
+            image = "pihole/pihole:v5.7";
+            autoStart = true;
+            ports = [ "5353:53/tcp" "5353:53/udp" "3080:80/tcp" ];
+            environment = {
+              # ServerIP = primary-ip;
+              VIRTUAL_HOST = "dns-hole.sea.fudo.org";
+              DNS1 = "${primary-ip}#${toString dns-proxy-port}";
+            };
+            volumes = [
+              "/srv/pihole/etc-pihole/:/etc/pihole/"
+              "/srv/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/"
+            ];
+          };
+        };
+      };
+    };
+
+    services.nginx = {
+      enable = true;
+
+      recommendedOptimisation = true;
+      recommendedGzipSettings = true;
+      recommendedProxySettings = true;
+
+      virtualHosts = {
+        "dns-hole.${domain-name}" = {
+          serverAliases = [
+            "pihole.${domain-name}"
+            "hole.${domain-name}"
+            "pihole"
+            "dns-hole"
+            "hole"
+          ];
+
+          locations."/" = { proxyPass = "http://127.0.0.1:3080"; };
+        };
+      };
+    };
+
+    # Support for statelessness
+    environment.etc = {
+      nixos.source = "/state/nixos";
+      adjtime.source = "/state/etc/adjtime";
+      NIXOS.source = "/state/etc/NIXOS";
+      machine-id.source = "/state/etc/machine-id";
+      "host-config.nix".source = "/state/etc/host-config.nix";
+    };
+
+    boot.initrd.postDeviceCommands = lib.mkAfter ''
+      ${pkgs.zfs}/bin/zfs rollback -r zroot/transient/root@blank
+    '';
+
+    security.sudo.extraConfig = ''
+      # rollback results in sudo lectures after each reboot
+      Defaults lecture = never
+    '';
+
+    systemd.tmpfiles.rules = [
+      "L /root/.gnupg - - - - /state/root/gnupg"
+      "L /root/.emacs.d - - - - /state/root/emacs.d"
+      "L /root/.ssh/id_rsa - - - - /state/root/ssh/id_rsa"
+      "L /root/.ssh/id_rsa.pub - - - - /state/root/ssh/id_rsa.pub"
+      "L /root/.ssh/known_hosts - - - - /state/root/ssh/known_hosts"
+      "L /etc/ssh/ssh_host_ed25519_key - - - - /state/ssh/ssh_host_ed25519_key"
+      "L /etc/ssh/ssh_host_rsa_key - - - - /state/ssh/ssh_host_rsa_key"
+    ];
+
+    services.openssh = {
+      hostKeys = [
+        {
+          path = "/state/ssh/ssh_host_ed25519_key";
+          type = "ed25519";
+        }
+        {
+          path = "/state/ssh/ssh_host_rsa_key";
+          type = "rsa";
+          bits = 4096;
+        }
+      ];
+    };
+  };
+}
diff --git a/config/host-config/nostromo.nix b/config/host-config/nostromo.nix
new file mode 100644
index 0000000..deabe7d
--- /dev/null
+++ b/config/host-config/nostromo.nix
@@ -0,0 +1,169 @@
+{ config, lib, pkgs, ... }:
+
+let
+  primary-ip = "10.0.0.1";
+  dns-proxy-ip = "10.0.0.5";
+
+in {
+  fudo.local-network = let
+    hostname = config.instance.hostname;
+    site-name = config.fudo.hosts.${hostname}.site;
+    site = config.fudo.site.${site-name};
+
+  in {
+    enable = true;
+    dns-servers = site.dns-servers;
+    gateway = site.gateway;
+    dhcp-interfaces = [ "intif0" ];
+    dns-serve-ips = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ];
+    recursive-resolver = "${primary-ip} port 5353";
+    server-ip = primary-ip;
+  };
+
+  fudo.slynk.enable = true;
+
+  # systemd.network.networks.eno2 = {
+  #   extraConfig = {
+  #     IPv6AcceptRA = true;
+  #     IPv6PrefixDelegation = "dhcpv6";
+  #   };
+  # };
+
+  networking = {
+    # dhcpd.extraConfig = ''
+    #   interface eno2
+    #     ia_na 1
+    #     ia_pd 2 eno2/0
+    # '';
+
+    eno1.useDHCP = false;
+    eno2.useDHCP = false;
+    eno3.useDHCP = false;
+    eno4.useDHCP = false;
+    enp33s0f0.useDHCP = false;
+    enp33s0f1.useDHCP = false;
+    enp9s0f0.useDHCP = false;
+    enp9s0f1.useDHCP = false;
+
+    intif0 = {
+      useDHCP = false;
+      ipv4.addresses = [
+        {
+          address = primary-ip;
+          prefixLength = 22;
+        }
+        {
+          address = dns-proxy-ip;
+          prefixLength = 32;
+        }
+      ];
+    };
+
+    extif0 = { useDHCP = true; };
+
+    nat = {
+      enable = true;
+      externalInterface = "extif0";
+      internalInterfaces = [ "intif0" ];
+    };
+  };
+
+  fudo = {
+    client.dns = {
+      enable = true;
+      ipv4 = true;
+      ipv6 = true;
+      user = "fudo-client";
+      external-interface = "extif0";
+      password-file = "/srv/client/secure/client.passwd";
+    };
+
+    secure-dns-proxy = {
+      enable = true;
+      port = 3535;
+      upstream-dns =
+        [ "https://1.1.1.1/dns-query" "https://1.0.0.1/dns-query" ];
+      bootstrap-dns = "1.1.1.1";
+      listen-ips = [ dns-proxy-ip ];
+    };
+  };
+
+  virtualization = {
+    docker = {
+      enable = true;
+      autoPrune.enable = true;
+      enableOnBoot = true;
+    };
+
+    libvirtd = {
+      enable = true;
+      qemuPackage = pkgs.qemu_kvm;
+      onShutdown = "shutdown";
+    };
+  };
+
+  docker-containers = {
+    pihole = {
+      image = "pihole/pihole:4.3.2-1";
+      ports = [ "5353:53/tcp" "5353:53/udp" "3080:80/tcp" ];
+      environment = {
+        ServerIP = primary-ip;
+        VIRTUAL_HOST = "dns-hole.sea.fudo.org";
+        DNS1 = dns-proxy-ip;
+      };
+      volumes = [
+        "/srv/pihole/etc-pihole/:/etc/pihole/"
+        "/srv/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/"
+      ];
+    };
+  };
+
+  security.acme.certs = {
+    "sea-camera.fudo.link".email = "niten@fudo.org";
+    "sea-camera-od.fudo.link".email = "niten@fudo.org";
+  };
+
+  services = {
+    nginx = {
+      enable = true;
+      recommendedGzipSettings = true;
+      recommendedOptimisation = true;
+      recommendedTlsSettings = true;
+      recommendedProxySettings = true;
+
+      virtualHosts = {
+        "sea-camera.fudo.link" = {
+          enableACME = true;
+          forceSSL = true;
+          locations."/" = {
+            proxyPass = "http://panopticon.sea.fudo.org/";
+            extraConfig = ''
+              proxy_http_version 1.1;
+              proxy_set_header Upgrade $http_upgrade;
+              proxy_set_header Connection "Upgrade";
+            '';
+          };
+        };
+
+        # Supposed to be for object detection...
+        "sea-camera-od.fudo.link" = {
+          enableACME = true;
+          forceSSL = true;
+          locations."/" = {
+            proxyPass = "http://panopticon-od.sea.fudo.org/";
+            extraConfig = ''
+              proxy_http_version 1.1;
+              proxy_set_header Upgrade $http_upgrade;
+              proxy_set_header Connection "Upgrade";
+            '';
+          };
+        };
+
+        "pihole.sea.fudo.org" = {
+          serverAliases = [ "dns-hole.sea.fudo.org" "hole.sea.fudo.org" ];
+          locations."/" = { proxyPass = "http://127.0.0.1:3000"; };
+        };
+      };
+    };
+  };
+}
diff --git a/config/host-config/plato.nix b/config/host-config/plato.nix
new file mode 100644
index 0000000..6db97c7
--- /dev/null
+++ b/config/host-config/plato.nix
@@ -0,0 +1,50 @@
+{ config, lib, pkgs, ... }:
+
+with lib; {
+  config = {
+    environment.etc = {
+      nixos.source = "/state/nixos";
+      adjtime.source = "/state/etc/adjtime";
+      NIXOS.source = "/state/etc/NIXOS";
+      machine-id.source = "/state/etc/machine-id";
+      "host-config.nix".source = "/state/etc/host-config.nix";
+    };
+
+    system.stateVersion = "20.09";
+
+    boot.initrd.postDeviceCommands = lib.mkAfter ''
+      ${pkgs.zfs}/bin/zfs rollback -r zroot/transient/root@blank
+    '';
+
+    security.sudo.extraConfig = ''
+      # rollback results in sudo lectures after each reboot
+      Defaults lecture = never
+    '';
+
+    systemd.tmpfiles.rules = [
+      "L /root/.gnupg - - - - /state/root/gnupg"
+      "L /root/.emacs.d - - - - /state/root/emacs.d"
+      "L /root/.ssh/id_rsa - - - - /state/root/ssh/id_rsa"
+      "L /root/.ssh/id_rsa.pub - - - - /state/root/ssh/id_rsa.pub"
+      "L /root/.ssh/known_hosts - - - - /state/root/ssh/known_hosts"
+      "L /etc/ssh/ssh_host_ed25519_key - - - - /state/ssh/ssh_host_ed25519_key"
+      "L /etc/ssh/ssh_host_rsa_key - - - - /state/ssh/ssh_host_rsa_key"
+    ];
+
+    services = {
+      openssh = {
+        hostKeys = [
+          {
+            path = "/state/ssh/ssh_host_ed25519_key";
+            type = "ed25519";
+          }
+          {
+            path = "/state/ssh/ssh_host_rsa_key";
+            type = "rsa";
+            bits = 4096;
+          }
+        ];
+      };
+    };
+  };
+}
diff --git a/config/host-config/spark.nix b/config/host-config/spark.nix
new file mode 100644
index 0000000..e6b83d5
--- /dev/null
+++ b/config/host-config/spark.nix
@@ -0,0 +1,16 @@
+{ config, lib, pkgs, ... }:
+
+{
+  # TODO: remove?
+  nixpkgs.config.permittedInsecurePackages = [
+    "openssh-with-gssapi-8.4p1" # CVE-2021-28041
+  ];
+
+  fudo.slynk.enable = true;
+
+  networking = {
+    interfaces = {
+      extif0 = { useDHCP = true; };
+    };
+  };
+}
diff --git a/config/host-config/zbox.nix b/config/host-config/zbox.nix
new file mode 100644
index 0000000..a90ce5b
--- /dev/null
+++ b/config/host-config/zbox.nix
@@ -0,0 +1,19 @@
+{ config, lib, pkgs, ... }:
+
+{
+  system.stateVersion = "20.09";
+  
+  # TODO: remove?
+  nixpkgs.config.permittedInsecurePackages = [
+    "openssh-with-gssapi-8.4p1" # CVE-2021-28041
+  ];
+
+  fudo.slynk.enable = true;
+
+  networking = {
+    interfaces = {
+      eno1.useDHCP = false;
+      intif0 = { useDHCP = true; };
+    };
+  };
+}
diff --git a/config/hosts.nix b/config/hosts.nix
index ecc90d5..23c39cf 100644
--- a/config/hosts.nix
+++ b/config/hosts.nix
@@ -1,177 +1,16 @@
 { config, lib, pkgs, ... }:
 
-{
-  config.fudo.hosts = {
-    atom = {
-      description = "Niten's toy laptop.";
-      enable-gui = false;
-      rp = "niten";
-      admin-email = "niten@fudo.org";
-      domain = "sea.fudo.org";
-      site = "seattle";
-      profile = "laptop";
-    };
+with lib;
+let
+  is-nix-file = filename: type: (builtins.match ".+\.nix$" filename) != null;
+  is-regular-file = filename: type: type == "regular" || type == "link";
+  hostname-from-file = filename: builtins.replaceStrings [".nix"] [""] filename;
+  
+  host-files = attrNames (filterAttrs is-nix-file (filterAttrs is-regular-file (builtins.readDir ./hosts)));
+  hosts = map hostname-from-file host-files;
 
-    clunk = {
-      description = "rus.selby.ca gateway box.";
-      docker-server = true;
-      ssh-fingerprints = [
-        "1 1 0e23d2156b1f9fca8552a0105c125aed76e51728"
-        "1 2 6d8dfc355102c9870945c6d79c1d19934d29e8b63303260101df51716963b7f5"
-        "4 1 c31a6ecaa02210e3ad72a835a072a05f043c2ef4"
-        "4 2 296ce1b91ac942a8b91e5c6316ea520d0cec14ac819a04bb262af6d4bdced696"
-      ];
-      rp = "niten";
-      admin-email = "niten@fudo.org";
-      domain = "rus.selby.ca";
-      site = "russell";
-      profile = "server";
-      ssh-pubkey =
-        "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB07Jf/NB4OlFSEI/eLJlNLA2sM9cHw1hX43r43nQ7a5";
-    };
-
-    downstairs-desktop = {
-      description = "Downstairs desktop in Russell.";
-      ssh-fingerprints = [
-        "1 1 ce704716ec0c3e330a243648531a10a2c78dd1ff"
-        "1 2 6042bbc9b16122a4b63b1cfb84e179ae65911361e9d88ee3f0cd6659428ba27e"
-        "3 1 de6dda3f72ee7043c804a7ad382033f3565b3b84"
-        "3 2 cb611dd503fa15e913a101be15295f9084fa585b3225b6c1084521bff9b2140b"
-        "4 1 a9a139b92851b3d9df2742a13bfea59c3e6e842e"
-        "4 2 2260bfab177ab1ffb6a855b02b5a1aa719d765610e6a7bc79b09c340ce7c1236"
-      ];
-      rp = "niten";
-      admin-email = "niten@fudo.org";
-      domain = "rus.selby.ca";
-      site = "russell";
-      profile = "desktop";
-      ssh-pubkey =
-        "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPqyDT/JqTxWZbpOXzy1Sxba2z2hNzt2BqjLspPvJLVc9zks1GMlnKAY5Nb7y7oi+CzeZMU+KAa069wZ/mYvpas=";
-    };
-
-    france = {
-      description = "Primary fudo.org server.";
-      docker-server = true;
-      ssh-fingerprints = [
-        "1 1 1b6d62dafae9ebc59169dfb4ef828582a5450d94"
-        "1 2 079e7a57873542541095bf3d2f97b7350bb457d027b423a6fb56f7f6aa84ac80"
-        "4 1 c95a198f504a589fc62893a95424b12f0b24732d"
-        "4 2 3e7dad879d6cab7f7fb6769e156d7988d0c01281618d03b793834eea2f09bc96"
-      ];
-      rp = "admin";
-      admin-email = "admin@fudo.org";
-      domain = "fudo.org";
-      site = "portage";
-      profile = "server";
-      ssh-pubkey =
-        "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1COad5NSK3mi66WK5uWf79NLMf5rk350kvJGsEdDmn";
-    };
-
-    google-wifi = {
-      description = "Google WiFi router.";
-      rp = "niten";
-    };
-
-    lambda = {
-      description = "sea.fudo.org experiment server.";
-      docker-server = true;
-      ssh-fingerprints = [
-        "1 1 128919958a358d44d1c8d76d29b1fa1514f9ad35"
-        "1 2 cd0ae0bb7e65f4058efdb2d7073de97ac403b1ef6f1527a23c60390d9a6bad88"
-        "4 1 a689caa9f1e75c6378efed592bc0d623e4b7d199"
-        "4 2 5856ae661077203fba74a226dd77a17d69d6fda8ab960bfeb22a14c253f4472f"
-      ];
-      rp = "niten";
-      admin-email = "niten@fudo.org";
-      domain = "sea.fudo.org";
-      site = "seattle";
-      profile = "server";
-    };
-
-    nostromo = {
-      description = "sea.fudo.org gateway box and primary server.";
-      docker-server = true;
-      ssh-fingerprints = [
-        "1 1 075ee0ae86debffa6fd61436984b39e4699c93c6"
-        "1 2 17a555b21fe08841c8dfb0d598dc2da117b94bf5a94cbf2c6b391eafd3e2c15e"
-        "4 1 ce86eabbe6f015e6422d0f5ef9ae32cc7beb1f42"
-        "4 2 44a5741825d43e571f6f9eb91e8c102eea75a4632dd8a9c80668e091a5fdf7f5"
-      ];
-      rp = "niten";
-      admin-email = "niten@fudo.org";
-      domain = "sea.fudo.org";
-      site = "seattle";
-      profile = "server";
-      ssh-pubkey =
-        "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHT8Uf6m8ZrSn4nmPyIO+JWLbgXJGX4jJTk0wfqDzzjb";
-    };
-
-    plato = {
-      description = "Niten's toy server.";
-      ssh-fingerprints = [
-        "4 1 9cc052ed00cbfd82c60530ebb3a35c25c0aeace9"
-        "4 2 5938044054e9fa6cf3ad8176ef8e81b86eede598c19388220d4b07587f6f1c3c"
-        "1 1 eebe1d4a24e0e2dbc46a7cb1107333c06e60d89e"
-        "1 2 a96609da442372bd73044d823b4b56bbaa597725c846b4326be76c323bb47ab3"
-      ];
-      rp = "niten";
-      admin-email = "niten@fudo.org";
-      domain = "rus.selby.ca";
-      site = "russell";
-      profile = "server";
-      ssh-pubkey =
-        "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGuClWAtkOMBOVFAFFdWosCT8NvuJBps46P4RV+Qqz4b";
-    };
-
-    procul = {
-      description = "informis.land server.";
-      docker-server = true;
-    };
-
-    pselby-work = { description = "Google Lenovo work laptop."; };
-
-    spark = {
-      description = "Niten's backup desktop.";
-      ssh-fingerprints = [
-        "1 1 d26812dee9b26a19a52c38d2b346442979093142"
-        "1 2 981db46fdd0ad1639651c700a527602425237c1d4999265372ed92e093a965b3"
-        "4 1 67fa0a36e51fd4a5ed2b71ff9817cb9a372d0a63"
-        "4 2 c17d46061d722e1e6c878341b8e3c0bf87ea6e0e1426c54a989107dfb604d81b"
-      ];
-      rp = "niten";
-      admin-email = "niten@fudo.org";
-      enable-gui = true;
-      ssh-pubkey =
-        "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO67/CNhiG9UynaflmZUUK7f3O/GwFpnXri/PxpgHcPa";
-    };
-
-    upstairs-desktop = {
-      description = "Upstairs desktop in Russell.";
-      ssh-fingerprints = [
-        "1 1 f927527d712391b57aef6d2e7c3f225a86b62bf4"
-        "1 2 17aece61156ba14c439aeae2e7b0f86daf97eea904241c35980f974ca1744c3d"
-        "3 1 70f5f613e66e53a74534d33cd7ebf248cfdc3024"
-        "3 2 774f1f00614751e51faa0add55183973893313d3a236d269adc3ab3c1f67c952"
-        "4 1 e81e07d1ae7526c457a46ab1f18af3c016b4f48e"
-        "4 2 e5af579cfb7f68b22492f5286b5249c5de74debf2a6cac78c070790f424566aa"
-      ];
-      rp = "niten";
-      admin-email = "niten@fudo.org";
-    };
-
-    zbox = {
-      description = "Niten's primary desktop.";
-      ssh-fingerprints = [
-        "1 1 3aff8c913615c81512be3a42fc83daeb90d94a3d"
-        "1 2 39c7500f08022963f3f2db4f3ebb7aad08c92d0cc937984ba86c4eba204ed493"
-        "4 1 862842d99f5afb33db4f073d2f3d1154c6417110"
-        "4 2 373536d3d59f2354b1bfc25c02120c86e9b3af574b6c1984210d9e9c1d5244e3"
-      ];
-      rp = "niten";
-      admin-email = "niten@fudo.org";
-      enable-gui = true;
-      ssh-pubkey =
-        "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKVhHfRf2086SAqOmu2dNbsJI9UUAQWop+1lrcJlNgl8";
-    };
-  };
+  load-host-file = hostname: import (./. + "/hosts/${hostname}.nix");
+    
+in {
+  config.fudo.hosts = genAttrs hosts (hostname: load-host-file hostname);
 }
diff --git a/config/hosts/atom.nix b/config/hosts/atom.nix
index abc7d91..1202aa8 100644
--- a/config/hosts/atom.nix
+++ b/config/hosts/atom.nix
@@ -1,9 +1,9 @@
-{ config, lib, pkgs, ... }:
-
 {
-  fudo.laptop.use-network-manager = false;
-
-  fudo.slynk.enable = true;
-
-  services.xserver = { videoDrivers = [ "nvidia" ]; };
+  description = "Niten's toy laptop.";
+  enable-gui = false;
+  rp = "niten";
+  admin-email = "niten@fudo.org";
+  domain = "sea.fudo.org";
+  site = "seattle";
+  profile = "laptop";
 }
diff --git a/config/hosts/clunk.nix b/config/hosts/clunk.nix
index 5cd326f..f3c931c 100644
--- a/config/hosts/clunk.nix
+++ b/config/hosts/clunk.nix
@@ -1,168 +1,17 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
-let
-  primary-ip = "10.0.0.1";
-
-  dns-proxy-port = 5335;
-
-  host-packages = with pkgs; [
-    nixops
+{
+  description = "rus.selby.ca gateway box.";
+  docker-server = true;
+  ssh-fingerprints = [
+    "1 1 0e23d2156b1f9fca8552a0105c125aed76e51728"
+    "1 2 6d8dfc355102c9870945c6d79c1d19934d29e8b63303260101df51716963b7f5"
+    "4 1 c31a6ecaa02210e3ad72a835a072a05f043c2ef4"
+    "4 2 296ce1b91ac942a8b91e5c6316ea520d0cec14ac819a04bb262af6d4bdced696"
   ];
-
-  site-name = config.fudo.hosts.${config.instance.hostname}.site;
-  site = config.fudo.site.${site-name};
-
-in {
-  system = {
-    # # DO force all DNS traffic to use the local server
-    # activationScripts.force-local-dns = let
-    #   wifi-ip =
-    #     config.fudo.networks."rus.selby.ca".hosts.google-wifi.ipv4-address;
-    # in ''
-    #   ${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p udp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53
-    #   ${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p tcp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53
-    # '';
-  };
-
-  environment.systemPackages = host-packages;
-
-  fudo.local-network = let
-    host-config = config.fudo.hosts.${config.instance.hostname};
-    site-name = host-config.site;
-    site = config.fudo.sites.${site-name};
-    domain-name = host-config.domain;
-    domain = config.fudo.domains.${domain-name};
-
-  in {
-    enable = true;
-    # NOTE: requests go:
-    #  - local bind instance
-    #  - pi-hole
-    #  - DoH resolver
-    domain = domain-name;
-    dns-servers = [ primary-ip ];
-    gateway = primary-ip;
-    dhcp-interfaces = [ "intif0" ];
-    dns-listen-ips = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ];
-    recursive-resolver = "${primary-ip} port 5353";
-    network = site.network;
-    dhcp-dynamic-network = site.dynamic-network;
-    search-domains = [ "selby.ca" ];
-    enable-reverse-mappings = true;
-    network-definition = config.fudo.networks."rus.selby.ca";
-  };
-
-  networking = {
-    firewall = {
-      enable = true;
-      trustedInterfaces = [ "intif0" "docker0" ];
-      allowedTCPPorts = [ 22 ];
-    };
-
-    interfaces = {
-      enp1s0.useDHCP = true;
-
-      enp2s0.useDHCP = false;
-      enp3s0.useDHCP = false;
-      enp4s0.useDHCP = false;
-
-      intif0 = {
-        useDHCP = false;
-        ipv4.addresses = [{
-          address = primary-ip;
-          prefixLength = 22;
-        }];
-      };
-    };
-
-    nat = {
-      enable = true;
-      externalInterface = "enp1s0";
-      internalInterfaces = [ "intif0" ];
-      forwardPorts = [{
-        destination = "127.0.0.1:53";
-        sourcePort = 53;
-        proto = "udp";
-      }];
-    };
-  };
-
-  fudo = {
-    garbage-collector = {
-      enable = true;
-      timing = "weekly";
-    };
-
-    auth.kdc = {
-      enable = true;
-      realm = "RUS.SELBY.CA";
-      bind-addresses = [ "10.0.0.1" "127.0.0.1" "::1" ];
-      acl = {
-        "niten" = { perms = [ "add" "change-password" "list" ]; };
-        "*/root" = { perms = [ "all" ]; };
-      };
-    };
-
-    secure-dns-proxy = {
-      enable = true;
-      listen-port = dns-proxy-port;
-      upstream-dns =
-        [ "https://1.1.1.1/dns-query" "https://1.0.0.1/dns-query" ];
-      bootstrap-dns = "1.1.1.1";
-      allowed-networks =
-        [ "1.1.1.1/32" "1.0.0.1/32" "10.0.0.0/16" "localhost" "link-local" ];
-      listen-ips = [ primary-ip ];
-    };
-  };
-
-  virtualisation = {
-    docker = {
-      enable = true;
-      autoPrune.enable = true;
-      enableOnBoot = true;
-    };
-
-    oci-containers = {
-      backend = "docker";
-      containers = {
-        pihole = {
-          image = "pihole/pihole:v5.7";
-          autoStart = true;
-          ports = [ "5353:53/tcp" "5353:53/udp" "3080:80/tcp" ];
-          environment = {
-            # ServerIP = primary-ip;
-            VIRTUAL_HOST = "dns-hole.rus.selby.ca";
-            DNS1 = "${primary-ip}#${toString dns-proxy-port}";
-          };
-          volumes = [
-            "/srv/pihole/etc-pihole/:/etc/pihole/"
-            "/srv/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/"
-          ];
-        };
-      };
-    };
-  };
-
-  services.nginx = {
-    enable = true;
-
-    recommendedOptimisation = true;
-    recommendedGzipSettings = true;
-    recommendedProxySettings = true;
-
-    virtualHosts = {
-      "dns-hole.rus.selby.ca" = {
-        serverAliases = [
-          "pihole.rus.selby.ca"
-          "hole.rus.selby.ca"
-          "pihole"
-          "dns-hole"
-          "hole"
-        ];
-
-        locations."/" = { proxyPass = "http://127.0.0.1:3080"; };
-      };
-    };
-  };
+  rp = "niten";
+  admin-email = "niten@fudo.org";
+  domain = "rus.selby.ca";
+  site = "russell";
+  profile = "server";
+  ssh-pubkey =
+    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB07Jf/NB4OlFSEI/eLJlNLA2sM9cHw1hX43r43nQ7a5";
 }
diff --git a/config/hosts/downstairs-desktop.nix b/config/hosts/downstairs-desktop.nix
new file mode 100644
index 0000000..b6c7184
--- /dev/null
+++ b/config/hosts/downstairs-desktop.nix
@@ -0,0 +1,18 @@
+{
+  description = "Downstairs desktop in Russell.";
+  ssh-fingerprints = [
+    "1 1 ce704716ec0c3e330a243648531a10a2c78dd1ff"
+    "1 2 6042bbc9b16122a4b63b1cfb84e179ae65911361e9d88ee3f0cd6659428ba27e"
+    "3 1 de6dda3f72ee7043c804a7ad382033f3565b3b84"
+    "3 2 cb611dd503fa15e913a101be15295f9084fa585b3225b6c1084521bff9b2140b"
+    "4 1 a9a139b92851b3d9df2742a13bfea59c3e6e842e"
+    "4 2 2260bfab177ab1ffb6a855b02b5a1aa719d765610e6a7bc79b09c340ce7c1236"
+  ];
+  rp = "niten";
+  admin-email = "niten@fudo.org";
+  domain = "rus.selby.ca";
+  site = "russell";
+  profile = "desktop";
+  ssh-pubkey =
+    "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPqyDT/JqTxWZbpOXzy1Sxba2z2hNzt2BqjLspPvJLVc9zks1GMlnKAY5Nb7y7oi+CzeZMU+KAa069wZ/mYvpas=";
+}
diff --git a/config/hosts/france.nix b/config/hosts/france.nix
index f4fe89a..ca71c85 100644
--- a/config/hosts/france.nix
+++ b/config/hosts/france.nix
@@ -1,179 +1,17 @@
-{ config, lib, pkgs, ... }:
-
-let
-  primary-ip = "208.81.3.117";
-  hostname = config.instance.hostname;
-  domain-name = config.fudo.hosts.${hostname}.domain;
-  domain = config.fudo.domains.${domain-name};
-  host-fqdn = "${hostname}.${domain-name}";
-  mail-hostname = "mail.fudo.org";
-
-in {
-  imports = [ ./france/postgresql.nix ];
-
-  config = {
-    fudo = {
-      auth = {
-        ldap = {
-          enable = true;
-          base = "dc=fudo,dc=org";
-          organization = "Fudo";
-          rootpw-file = "FIXME";
-          kerberos-host = host-fqdn;
-          kerberos-keytab = "FIXME";
-
-          sslCert = "FIXME";
-          sslKey = "FIXME";
-          sslCaCert = "FIXME";
-
-          listen-uris = [ "ldap:///" "ldaps:///" "ldapi:///" ];
-
-          users = config.fudo.users;
-          groups = config.fudo.groups;
-          system-users = config.fudo.system-users;
-        };
-
-        kdc = let realm = "FUDO.ORG";
-        in {
-          enable = true;
-          database-path = "FIXME";
-          realm = realm;
-          mkey-file = "FIXME";
-          acl = [
-            {
-              principal = "pam_migrate/*.fudo.org@${realm}";
-              access = "add";
-            }
-            {
-              principal = "host/*.fudo.org@${realm}";
-              access = "add";
-            }
-          ] ++ (concatMap (user: [
-            {
-              principal = "${user}@${realm}";
-              access = "add,list,modify";
-            }
-            {
-              principal = "${user}/root@${realm}";
-              access = "all";
-            }
-          ]) domain.admin-users);
-          bind-addresses = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ];
-        };
-      };
-
-      prometheus = {
-        enable = true;
-        hostname = "metrics.fudo.org";
-        service-discovery-dns = let dns-root = "_metrics._tcp.fudo.org";
-        in {
-          node = [ "node.${dns-root}" ];
-          postfix = [ "postfix.${dns-root}" ];
-          dovecot = [ "dovecot.${dns-root}" ];
-          rspamd = [ "rspamd.${dns-root}" ];
-        };
-      };
-
-      postgresql = {
-        enable = true;
-        # FIXME: ssl-private-key && ssl certificate
-        keytab = "/srv/postgres/secure/postgres.keytab";
-        local-networks = getHostLocalNetworks hostname;
-        admin-users = domain.admin-users;
-      };
-
-      client.dns = {
-        enable = true;
-        ipv4 = true;
-        ipv6 = true;
-        user = "FIXME";
-        external-interface = "extif0";
-        password-file = "FIXME";
-      };
-
-      mail-server = domain.mail-config // {
-        enableContainer = true;
-        monitoring = true;
-
-        hostname = mail-hostname;
-
-        state-directory = "FIXME";
-        mail-directory = "FIXME";
-
-        dovecot.ldap = {
-          reader-dn = "FIXME";
-          reader-password = "FIXME";
-          server-urls = [ "FIXME" ];
-        };
-
-        clamav.enable = true;
-        dkim.signing = true;
-      };
-
-      git = {
-        enable = true;
-        hostname = "git.fudo.org";
-        site-name = "Fudo Git";
-        user = "FIXME";
-        database = {
-          user = "FIXME";
-          password-file = "FIXME";
-          hostname = "127.0.0.1";
-          name = "FIXME";
-        };
-        repository-dir = "FIXME";
-        state-dir = "FIXME";
-        ssh = {
-          listen-ip = git-server-ip;
-          listen-port = 22;
-        };
-      };
-
-      minecraft-server = {
-        enable = true;
-        package = pkgs.minecraft-current;
-        data-dir = "FIXME";
-        world-name = "selbyland";
-        motd = "Welcome to the Selby Minecraft server.";
-      };
-    };
-
-    networking = {
-      intif0 = {
-        ipv4.addresses = [{
-          address = "192.168.11.1";
-          prefixLength = 24;
-        }];
-      };
-      extif0 = {
-        ipv4.addresses = [
-          {
-            address = primary-ip;
-            prefixLength = 28;
-          }
-          {
-            address = git-server-ip;
-            prefixLength = 32;
-          }
-        ];
-      };
-    };
-
-    services = {
-      nginx = {
-        enable = true;
-        recommendedGzipSettings = true;
-        recommendedOptimisations = true;
-        recommendedTlsSettings = true;
-        recommendedProxySettings = true;
-
-        virtualHosts = {
-          "mail.fudo.org" = {
-            enableACME = true;
-            locations."/".return = "301 https://webmail.fudo.org$request_uri";
-          };
-        };
-      };
-    };
-  };
+{
+  description = "Primary fudo.org server.";
+  docker-server = true;
+  ssh-fingerprints = [
+    "1 1 1b6d62dafae9ebc59169dfb4ef828582a5450d94"
+    "1 2 079e7a57873542541095bf3d2f97b7350bb457d027b423a6fb56f7f6aa84ac80"
+    "4 1 c95a198f504a589fc62893a95424b12f0b24732d"
+    "4 2 3e7dad879d6cab7f7fb6769e156d7988d0c01281618d03b793834eea2f09bc96"
+  ];
+  rp = "admin";
+  admin-email = "admin@fudo.org";
+  domain = "fudo.org";
+  site = "portage";
+  profile = "server";
+  ssh-pubkey =
+    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1COad5NSK3mi66WK5uWf79NLMf5rk350kvJGsEdDmn";
 }
diff --git a/config/hosts/lambda.nix b/config/hosts/lambda.nix
index 90349aa..46758ee 100644
--- a/config/hosts/lambda.nix
+++ b/config/hosts/lambda.nix
@@ -1,32 +1,15 @@
-{ config, lib, pkgs, ... }:
-
-let primary-ip = "10.0.0.3";
-
-in {
-  fudo.slynk.enable = true;
-
-  networking = {
-    interfaces = {
-      enp3s0f0.useDHCP = false;
-      enp3s0f1.useDHCP = false;
-      enp4s0f0.useDHCP = false;
-      enp4s0f1.useDHCP = false;
-
-      extif0 = {
-        useDHCP = false;
-        ipv4.addresses = [{
-          address = primary-ip;
-          prefixLength = 22;
-        }];
-      };
-    };
-  };
-
-  fudo.ipfs = {
-    enable = true;
-    users = [ "niten" ];
-    api-address = "/ip4/${primary-ip}/tcp/5001";
-  };
-
-  # TODO: add camera
+{
+  description = "sea.fudo.org experiment server.";
+  docker-server = true;
+  ssh-fingerprints = [
+    "1 1 128919958a358d44d1c8d76d29b1fa1514f9ad35"
+    "1 2 cd0ae0bb7e65f4058efdb2d7073de97ac403b1ef6f1527a23c60390d9a6bad88"
+    "4 1 a689caa9f1e75c6378efed592bc0d623e4b7d199"
+    "4 2 5856ae661077203fba74a226dd77a17d69d6fda8ab960bfeb22a14c253f4472f"
+  ];
+  rp = "niten";
+  admin-email = "niten@fudo.org";
+  domain = "sea.fudo.org";
+  site = "seattle";
+  profile = "server";
 }
diff --git a/config/hosts/limina.nix b/config/hosts/limina.nix
index 9743b00..04fb8f6 100644
--- a/config/hosts/limina.nix
+++ b/config/hosts/limina.nix
@@ -1,56 +1,16 @@
-{ config, lib, pkgs, ... }:
-
-with lib; {
-  config = {
-  
-    # TODO: remove?
-    nixpkgs.config.permittedInsecurePackages = [
-      "openssh-with-gssapi-8.4p1" # CVE-2021-28041
-    ];
-  
-    environment.etc = {
-      nixos.source = "/state/nixos";
-      adjtime.source = "/state/etc/adjtime";
-      NIXOS.source = "/state/etc/NIXOS";
-      machine-id.source = "/state/etc/machine-id";
-      "host-config.nix".source = "/state/etc/host-config.nix";
-    };
-
-    system.stateVersion = "20.09";
-
-    boot.initrd.postDeviceCommands = lib.mkAfter ''
-      ${pkgs.zfs}/bin/zfs rollback -r zroot/transient/root@blank
-    '';
-
-    security.sudo.extraConfig = ''
-      # rollback results in sudo lectures after each reboot
-      Defaults lecture = never
-    '';
-
-    systemd.tmpfiles.rules = [
-      "L /root/.gnupg - - - - /state/root/gnupg"
-      "L /root/.emacs.d - - - - /state/root/emacs.d"
-      "L /root/.ssh/id_rsa - - - - /state/root/ssh/id_rsa"
-      "L /root/.ssh/id_rsa.pub - - - - /state/root/ssh/id_rsa.pub"
-      "L /root/.ssh/known_hosts - - - - /state/root/ssh/known_hosts"
-      "L /etc/ssh/ssh_host_ed25519_key - - - - /state/ssh/ssh_host_ed25519_key"
-      "L /etc/ssh/ssh_host_rsa_key - - - - /state/ssh/ssh_host_rsa_key"
-    ];
-
-    services = {
-      openssh = {
-        hostKeys = [
-          {
-            path = "/state/ssh/ssh_host_ed25519_key";
-            type = "ed25519";
-          }
-          {
-            path = "/state/ssh/ssh_host_rsa_key";
-            type = "rsa";
-            bits = 4096;
-          }
-        ];
-      };
-    };
-  };
+{
+  description = "Seattle Gateway Server.";
+  ssh-fingerprints = [
+    "1 1 36cbb85f83e84a4052777cf9b3cfb0f7947f3e4e"
+    "1 2 041c59238f599f7a3a4ec39151f5bc79fdcf917ec7ef2c400ed19a8d148fbeeb"
+    "4 1 07318d35f52203d337d4f457acc6d00ebf0e1aad"
+    "4 2 c58ef49cb6e150995ae0bd5dd502a0fc18289caf1438fb0bc9821455c8d1f41f"
+  ];
+  rp = "niten";
+  admin-email = "niten@fudo.org";
+  domain = "sea.fudo.org";
+  site = "seattle";
+  profile = "server";
+  ssh-pubkey =
+    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMqymGZ5dI6ChI1Qx1QfjBo/h0+xFwpRx/wQSDxWQprI";
 }
diff --git a/config/hosts/nostromo.nix b/config/hosts/nostromo.nix
index deabe7d..a5992d8 100644
--- a/config/hosts/nostromo.nix
+++ b/config/hosts/nostromo.nix
@@ -1,169 +1,17 @@
-{ config, lib, pkgs, ... }:
-
-let
-  primary-ip = "10.0.0.1";
-  dns-proxy-ip = "10.0.0.5";
-
-in {
-  fudo.local-network = let
-    hostname = config.instance.hostname;
-    site-name = config.fudo.hosts.${hostname}.site;
-    site = config.fudo.site.${site-name};
-
-  in {
-    enable = true;
-    dns-servers = site.dns-servers;
-    gateway = site.gateway;
-    dhcp-interfaces = [ "intif0" ];
-    dns-serve-ips = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ];
-    recursive-resolver = "${primary-ip} port 5353";
-    server-ip = primary-ip;
-  };
-
-  fudo.slynk.enable = true;
-
-  # systemd.network.networks.eno2 = {
-  #   extraConfig = {
-  #     IPv6AcceptRA = true;
-  #     IPv6PrefixDelegation = "dhcpv6";
-  #   };
-  # };
-
-  networking = {
-    # dhcpd.extraConfig = ''
-    #   interface eno2
-    #     ia_na 1
-    #     ia_pd 2 eno2/0
-    # '';
-
-    eno1.useDHCP = false;
-    eno2.useDHCP = false;
-    eno3.useDHCP = false;
-    eno4.useDHCP = false;
-    enp33s0f0.useDHCP = false;
-    enp33s0f1.useDHCP = false;
-    enp9s0f0.useDHCP = false;
-    enp9s0f1.useDHCP = false;
-
-    intif0 = {
-      useDHCP = false;
-      ipv4.addresses = [
-        {
-          address = primary-ip;
-          prefixLength = 22;
-        }
-        {
-          address = dns-proxy-ip;
-          prefixLength = 32;
-        }
-      ];
-    };
-
-    extif0 = { useDHCP = true; };
-
-    nat = {
-      enable = true;
-      externalInterface = "extif0";
-      internalInterfaces = [ "intif0" ];
-    };
-  };
-
-  fudo = {
-    client.dns = {
-      enable = true;
-      ipv4 = true;
-      ipv6 = true;
-      user = "fudo-client";
-      external-interface = "extif0";
-      password-file = "/srv/client/secure/client.passwd";
-    };
-
-    secure-dns-proxy = {
-      enable = true;
-      port = 3535;
-      upstream-dns =
-        [ "https://1.1.1.1/dns-query" "https://1.0.0.1/dns-query" ];
-      bootstrap-dns = "1.1.1.1";
-      listen-ips = [ dns-proxy-ip ];
-    };
-  };
-
-  virtualization = {
-    docker = {
-      enable = true;
-      autoPrune.enable = true;
-      enableOnBoot = true;
-    };
-
-    libvirtd = {
-      enable = true;
-      qemuPackage = pkgs.qemu_kvm;
-      onShutdown = "shutdown";
-    };
-  };
-
-  docker-containers = {
-    pihole = {
-      image = "pihole/pihole:4.3.2-1";
-      ports = [ "5353:53/tcp" "5353:53/udp" "3080:80/tcp" ];
-      environment = {
-        ServerIP = primary-ip;
-        VIRTUAL_HOST = "dns-hole.sea.fudo.org";
-        DNS1 = dns-proxy-ip;
-      };
-      volumes = [
-        "/srv/pihole/etc-pihole/:/etc/pihole/"
-        "/srv/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/"
-      ];
-    };
-  };
-
-  security.acme.certs = {
-    "sea-camera.fudo.link".email = "niten@fudo.org";
-    "sea-camera-od.fudo.link".email = "niten@fudo.org";
-  };
-
-  services = {
-    nginx = {
-      enable = true;
-      recommendedGzipSettings = true;
-      recommendedOptimisation = true;
-      recommendedTlsSettings = true;
-      recommendedProxySettings = true;
-
-      virtualHosts = {
-        "sea-camera.fudo.link" = {
-          enableACME = true;
-          forceSSL = true;
-          locations."/" = {
-            proxyPass = "http://panopticon.sea.fudo.org/";
-            extraConfig = ''
-              proxy_http_version 1.1;
-              proxy_set_header Upgrade $http_upgrade;
-              proxy_set_header Connection "Upgrade";
-            '';
-          };
-        };
-
-        # Supposed to be for object detection...
-        "sea-camera-od.fudo.link" = {
-          enableACME = true;
-          forceSSL = true;
-          locations."/" = {
-            proxyPass = "http://panopticon-od.sea.fudo.org/";
-            extraConfig = ''
-              proxy_http_version 1.1;
-              proxy_set_header Upgrade $http_upgrade;
-              proxy_set_header Connection "Upgrade";
-            '';
-          };
-        };
-
-        "pihole.sea.fudo.org" = {
-          serverAliases = [ "dns-hole.sea.fudo.org" "hole.sea.fudo.org" ];
-          locations."/" = { proxyPass = "http://127.0.0.1:3000"; };
-        };
-      };
-    };
-  };
+{
+  description = "sea.fudo.org gateway box and primary server.";
+  docker-server = true;
+  ssh-fingerprints = [
+    "1 1 075ee0ae86debffa6fd61436984b39e4699c93c6"
+    "1 2 17a555b21fe08841c8dfb0d598dc2da117b94bf5a94cbf2c6b391eafd3e2c15e"
+    "4 1 ce86eabbe6f015e6422d0f5ef9ae32cc7beb1f42"
+    "4 2 44a5741825d43e571f6f9eb91e8c102eea75a4632dd8a9c80668e091a5fdf7f5"
+  ];
+  rp = "niten";
+  admin-email = "niten@fudo.org";
+  domain = "sea.fudo.org";
+  site = "seattle";
+  profile = "server";
+  ssh-pubkey =
+    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHT8Uf6m8ZrSn4nmPyIO+JWLbgXJGX4jJTk0wfqDzzjb";
 }
diff --git a/config/hosts/plato.nix b/config/hosts/plato.nix
index 6db97c7..b85e492 100644
--- a/config/hosts/plato.nix
+++ b/config/hosts/plato.nix
@@ -1,50 +1,16 @@
-{ config, lib, pkgs, ... }:
-
-with lib; {
-  config = {
-    environment.etc = {
-      nixos.source = "/state/nixos";
-      adjtime.source = "/state/etc/adjtime";
-      NIXOS.source = "/state/etc/NIXOS";
-      machine-id.source = "/state/etc/machine-id";
-      "host-config.nix".source = "/state/etc/host-config.nix";
-    };
-
-    system.stateVersion = "20.09";
-
-    boot.initrd.postDeviceCommands = lib.mkAfter ''
-      ${pkgs.zfs}/bin/zfs rollback -r zroot/transient/root@blank
-    '';
-
-    security.sudo.extraConfig = ''
-      # rollback results in sudo lectures after each reboot
-      Defaults lecture = never
-    '';
-
-    systemd.tmpfiles.rules = [
-      "L /root/.gnupg - - - - /state/root/gnupg"
-      "L /root/.emacs.d - - - - /state/root/emacs.d"
-      "L /root/.ssh/id_rsa - - - - /state/root/ssh/id_rsa"
-      "L /root/.ssh/id_rsa.pub - - - - /state/root/ssh/id_rsa.pub"
-      "L /root/.ssh/known_hosts - - - - /state/root/ssh/known_hosts"
-      "L /etc/ssh/ssh_host_ed25519_key - - - - /state/ssh/ssh_host_ed25519_key"
-      "L /etc/ssh/ssh_host_rsa_key - - - - /state/ssh/ssh_host_rsa_key"
-    ];
-
-    services = {
-      openssh = {
-        hostKeys = [
-          {
-            path = "/state/ssh/ssh_host_ed25519_key";
-            type = "ed25519";
-          }
-          {
-            path = "/state/ssh/ssh_host_rsa_key";
-            type = "rsa";
-            bits = 4096;
-          }
-        ];
-      };
-    };
-  };
+{
+  description = "Niten's toy server.";
+  ssh-fingerprints = [
+    "4 1 9cc052ed00cbfd82c60530ebb3a35c25c0aeace9"
+    "4 2 5938044054e9fa6cf3ad8176ef8e81b86eede598c19388220d4b07587f6f1c3c"
+    "1 1 eebe1d4a24e0e2dbc46a7cb1107333c06e60d89e"
+    "1 2 a96609da442372bd73044d823b4b56bbaa597725c846b4326be76c323bb47ab3"
+  ];
+  rp = "niten";
+  admin-email = "niten@fudo.org";
+  domain = "sea.fudo.org";
+  site = "seattle";
+  profile = "server";
+  ssh-pubkey =
+    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGuClWAtkOMBOVFAFFdWosCT8NvuJBps46P4RV+Qqz4b";
 }
diff --git a/config/hosts/procul.nix b/config/hosts/procul.nix
new file mode 100644
index 0000000..c9547fe
--- /dev/null
+++ b/config/hosts/procul.nix
@@ -0,0 +1,4 @@
+{
+  description = "informis.land server.";
+  docker-server = true;
+}
diff --git a/config/hosts/pselby-work.nix b/config/hosts/pselby-work.nix
new file mode 100644
index 0000000..9797c0e
--- /dev/null
+++ b/config/hosts/pselby-work.nix
@@ -0,0 +1,3 @@
+{
+  description = "Google Lenovo work laptop.";
+}
diff --git a/config/hosts/spark.nix b/config/hosts/spark.nix
index e6b83d5..38fc00c 100644
--- a/config/hosts/spark.nix
+++ b/config/hosts/spark.nix
@@ -1,16 +1,14 @@
-{ config, lib, pkgs, ... }:
-
 {
-  # TODO: remove?
-  nixpkgs.config.permittedInsecurePackages = [
-    "openssh-with-gssapi-8.4p1" # CVE-2021-28041
+  description = "Niten's backup desktop.";
+  ssh-fingerprints = [
+    "1 1 d26812dee9b26a19a52c38d2b346442979093142"
+    "1 2 981db46fdd0ad1639651c700a527602425237c1d4999265372ed92e093a965b3"
+    "4 1 67fa0a36e51fd4a5ed2b71ff9817cb9a372d0a63"
+    "4 2 c17d46061d722e1e6c878341b8e3c0bf87ea6e0e1426c54a989107dfb604d81b"
   ];
-
-  fudo.slynk.enable = true;
-
-  networking = {
-    interfaces = {
-      extif0 = { useDHCP = true; };
-    };
-  };
+  rp = "niten";
+  admin-email = "niten@fudo.org";
+  enable-gui = true;
+  ssh-pubkey =
+    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO67/CNhiG9UynaflmZUUK7f3O/GwFpnXri/PxpgHcPa";
 }
diff --git a/config/hosts/upstairs-desktop.nix b/config/hosts/upstairs-desktop.nix
new file mode 100644
index 0000000..dcf14e8
--- /dev/null
+++ b/config/hosts/upstairs-desktop.nix
@@ -0,0 +1,13 @@
+{
+  description = "Upstairs desktop in Russell.";
+  ssh-fingerprints = [
+    "1 1 f927527d712391b57aef6d2e7c3f225a86b62bf4"
+    "1 2 17aece61156ba14c439aeae2e7b0f86daf97eea904241c35980f974ca1744c3d"
+    "3 1 70f5f613e66e53a74534d33cd7ebf248cfdc3024"
+    "3 2 774f1f00614751e51faa0add55183973893313d3a236d269adc3ab3c1f67c952"
+    "4 1 e81e07d1ae7526c457a46ab1f18af3c016b4f48e"
+    "4 2 e5af579cfb7f68b22492f5286b5249c5de74debf2a6cac78c070790f424566aa"
+  ];
+  rp = "niten";
+  admin-email = "niten@fudo.org";
+}
diff --git a/config/hosts/zbox.nix b/config/hosts/zbox.nix
index a90ce5b..9a66a72 100644
--- a/config/hosts/zbox.nix
+++ b/config/hosts/zbox.nix
@@ -1,19 +1,14 @@
-{ config, lib, pkgs, ... }:
-
 {
-  system.stateVersion = "20.09";
-  
-  # TODO: remove?
-  nixpkgs.config.permittedInsecurePackages = [
-    "openssh-with-gssapi-8.4p1" # CVE-2021-28041
+  description = "Niten's primary desktop.";
+  ssh-fingerprints = [
+    "1 1 3aff8c913615c81512be3a42fc83daeb90d94a3d"
+    "1 2 39c7500f08022963f3f2db4f3ebb7aad08c92d0cc937984ba86c4eba204ed493"
+    "4 1 862842d99f5afb33db4f073d2f3d1154c6417110"
+    "4 2 373536d3d59f2354b1bfc25c02120c86e9b3af574b6c1984210d9e9c1d5244e3"
   ];
-
-  fudo.slynk.enable = true;
-
-  networking = {
-    interfaces = {
-      eno1.useDHCP = false;
-      intif0 = { useDHCP = true; };
-    };
-  };
+  rp = "niten";
+  admin-email = "niten@fudo.org";
+  enable-gui = true;
+  ssh-pubkey =
+    "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKVhHfRf2086SAqOmu2dNbsJI9UUAQWop+1lrcJlNgl8";
 }
diff --git a/config/profiles/common-ui.nix b/config/profile-config/common-ui.nix
similarity index 100%
rename from config/profiles/common-ui.nix
rename to config/profile-config/common-ui.nix
diff --git a/config/profiles/common.nix b/config/profile-config/common.nix
similarity index 100%
rename from config/profiles/common.nix
rename to config/profile-config/common.nix
diff --git a/config/profiles/desktop.nix b/config/profile-config/desktop.nix
similarity index 100%
rename from config/profiles/desktop.nix
rename to config/profile-config/desktop.nix
diff --git a/config/profiles/laptop.nix b/config/profile-config/laptop.nix
similarity index 100%
rename from config/profiles/laptop.nix
rename to config/profile-config/laptop.nix
diff --git a/config/profiles/server.nix b/config/profile-config/server.nix
similarity index 100%
rename from config/profiles/server.nix
rename to config/profile-config/server.nix
diff --git a/config/sites/joes-datacenter-0.nix b/config/site-config/joes-datacenter-0.nix
similarity index 100%
rename from config/sites/joes-datacenter-0.nix
rename to config/site-config/joes-datacenter-0.nix
diff --git a/config/sites/portage.nix b/config/site-config/portage.nix
similarity index 100%
rename from config/sites/portage.nix
rename to config/site-config/portage.nix
diff --git a/config/sites/russell.nix b/config/site-config/russell.nix
similarity index 100%
rename from config/sites/russell.nix
rename to config/site-config/russell.nix
diff --git a/config/sites/seattle.nix b/config/site-config/seattle.nix
similarity index 100%
rename from config/sites/seattle.nix
rename to config/site-config/seattle.nix
diff --git a/configuration.nix b/configuration.nix
index d989c33..6222a20 100644
--- a/configuration.nix
+++ b/configuration.nix
@@ -8,9 +8,6 @@ in {
   imports = [
     (initialize {
       hostname = local.hostname;
-      profile = local.profile;
-      site = local.site;
-      domain = local.domain;
       home-manager-package = builtins.fetchGit {
         url = "https://github.com/nix-community/home-manager.git";
         ref = "release-20.09";
diff --git a/initialize.nix b/initialize.nix
index 8b3061b..3a0b051 100644
--- a/initialize.nix
+++ b/initialize.nix
@@ -1,27 +1,24 @@
-{ hostname, profile, domain, site, home-manager-package, pkgs, ... }:
+{ hostname, home-manager-package, pkgs, ... }:
 
-{
+let
+  host-config = import (./. + "/config/hosts/${hostname}.nix");
+  
+in {
   imports = [
     ./lib
     ./config
     ./packages
 
     (./. + "/config/hardware/${hostname}.nix")
-    (./. + "/config/hosts/${hostname}.nix")
-    (./. + "/config/profiles/${profile}.nix")
-    (./. + "/config/domains/${domain}.nix")
-    (./. + "/config/sites/${site}.nix")
+    (./. + "/config/host-config/${hostname}.nix")
+    (./. + "/config/profile-config/${host-config.profile}.nix")
+    (./. + "/config/domain-config/${host-config.domain}.nix")
+    (./. + "/config/site-config/${host-config.site}.nix")
 
     (import "${home-manager-package}/nixos")
   ];
 
   config = {
     instance = { hostname = hostname; };
-
-    fudo.hosts."${hostname}" = {
-      domain = domain;
-      site = site;
-      profile = profile;
-    };
   };
 }
diff --git a/lib/fudo/hosts.nix b/lib/fudo/hosts.nix
index efcea43..9094eaa 100644
--- a/lib/fudo/hosts.nix
+++ b/lib/fudo/hosts.nix
@@ -78,7 +78,7 @@ let
       ssh-fingerprints = mkOption {
         type = listOf str;
         description = ''
-          A list of DNS SSHFP records for this host.
+          A list of DNS SSHFP records for this host. Get with `ssh-keygen -r <hostname>`
         '';
         default = [ ];
       };

From 16fd1ff21f7d872600a698b96b70cb5d2defe274 Mon Sep 17 00:00:00 2001
From: Root <root@fudo.org>
Date: Fri, 9 Apr 2021 14:24:50 -0700
Subject: [PATCH 5/5] Changes for plato

---
 config/hardware/plato.nix          |   1 +
 config/host-config/plato.nix       |  23 +++-
 config/sites.nix                   |   1 +
 lib/fudo/networks/rus.selby.ca.nix |  86 ------------
 lib/fudo/networks/sea.fudo.org.nix | 214 -----------------------------
 lib/fudo/sites.nix                 |  51 +++++--
 6 files changed, 60 insertions(+), 316 deletions(-)
 delete mode 100644 lib/fudo/networks/rus.selby.ca.nix
 delete mode 100644 lib/fudo/networks/sea.fudo.org.nix

diff --git a/config/hardware/plato.nix b/config/hardware/plato.nix
index c068835..1fa1150 100644
--- a/config/hardware/plato.nix
+++ b/config/hardware/plato.nix
@@ -73,6 +73,7 @@ with lib;
     };
 
     interfaces = {
+      enp1s0.useDHCP = false;
       intif0 = {
         # output of: echo plato-intif0|md5sum|sed 's/^\(..\)\(..\)\(..\)\(..\)\(..\).*$/02:\1:\2:\3:\4:\5/'
         macAddress = "02:25:b7:67:c4:c2";
diff --git a/config/host-config/plato.nix b/config/host-config/plato.nix
index 6db97c7..ffc6d72 100644
--- a/config/host-config/plato.nix
+++ b/config/host-config/plato.nix
@@ -1,6 +1,8 @@
 { config, lib, pkgs, ... }:
 
-with lib; {
+with lib;
+let primary-ip = "10.0.0.21";
+in {
   config = {
     environment.etc = {
       nixos.source = "/state/nixos";
@@ -23,7 +25,7 @@ with lib; {
 
     systemd.tmpfiles.rules = [
       "L /root/.gnupg - - - - /state/root/gnupg"
-      "L /root/.emacs.d - - - - /state/root/emacs.d"
+      # "L /root/.emacs.d - - - - /state/root/emacs.d"
       "L /root/.ssh/id_rsa - - - - /state/root/ssh/id_rsa"
       "L /root/.ssh/id_rsa.pub - - - - /state/root/ssh/id_rsa.pub"
       "L /root/.ssh/known_hosts - - - - /state/root/ssh/known_hosts"
@@ -31,6 +33,23 @@ with lib; {
       "L /etc/ssh/ssh_host_rsa_key - - - - /state/ssh/ssh_host_rsa_key"
     ];
 
+    networking = {
+      defaultGateway = {
+        address = "10.0.0.1";
+        interface = "intif0";
+      };
+
+      interfaces = {
+        intif0 = {
+          useDHCP = false;
+          ipv4.addresses = [{
+            address = primary-ip;
+            prefixLength = 22;
+          }];
+        };
+      };
+    };
+
     services = {
       openssh = {
         hostKeys = [
diff --git a/config/sites.nix b/config/sites.nix
index 16289ff..212d7e5 100644
--- a/config/sites.nix
+++ b/config/sites.nix
@@ -9,6 +9,7 @@
       dynamic-network = "10.0.1.0/24";
       timezone = "America/Los_Angeles";
       gateway-host = "nostromo";
+      deploy-pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDMPjwpcktL0Rhjc/D3ZmzwkSRqSJX5TGjMXVstpg8nNqQQrj9DxPq7gV4a+1LxMtQGPUv4gYx7De1a5LMVk8u6qJJnaLlt3TB1e1SUCBxxeh5sWIY5BMx8Q0/aRTkyTchyczX6FX0LXM7FP6yvxZVZSn2WHRp7REr8G1PUAwuIGy2a4bKOUSh5Uj4riXFXnROW2mp1vUfe5oH4X5HP3ACCXWRVUFdqDt1ldcrqqi+7/8x2G1eOHJcQ7B5FdL3uuq0nBrUzFQTt6KCHy0C2Jc3DFwOS1+ZdGKZpao+/arh/fH+LQfMUePx/AQOkYrJwvuRwbxg8XmlZ89u2gyDuqapzjBmsu+wyd5pF2QglyTRZW9Ijy1NTuzduPm6wgqN0Q09evFJvM9ZjShcIY3xTcCGDxpwTeYgMVXMF79sV9u+JwCSBpaIyteIJ7M/J/NWmaKoUF6Ia9mNts889Ba9TKzQFek19KYetOB2hfXV+7bvXrH+OBppzpdrztJFavBceQTs=";
       # FIXME: good idea?
       # network-mounts = {
       #   "/mnt/documents" = {
diff --git a/lib/fudo/networks/rus.selby.ca.nix b/lib/fudo/networks/rus.selby.ca.nix
deleted file mode 100644
index 3d5d744..0000000
--- a/lib/fudo/networks/rus.selby.ca.nix
+++ /dev/null
@@ -1,86 +0,0 @@
-{ config, lib, ... }:
-
-{
-  default-host = "10.0.0.1";
-
-  mx = [ "mail.fudo.org" ];
-
-  hosts = {
-    clunk = {
-      ipv4-address = "10.0.0.1";
-      mac-address = "02:44:d1:eb:c3:6b";
-    };
-
-    dns-proxy = {
-      ipv4-address = "10.0.0.2";
-      # This is just a second IP on clunk, for the pihole
-    };
-
-    google-wifi = {
-      ipv4-address = "10.0.0.11";
-      mac-address = "70:3a:cb:c0:3b:09";
-    };
-
-    pselby-work = {
-      ipv4-address = "10.0.0.151";
-      mac-address = "00:50:b6:aa:bd:b3";
-    };
-
-    downstairs-desktop = {
-      ipv4-address = "10.0.0.100";
-      mac-address = "90:b1:1c:8e:29:cf";
-    };
-
-    upstairs-desktop = {
-      ipv4-address = "10.0.0.101";
-      mac-address = "80:e8:2c:22:65:c2";
-    };
-  };
-
-  aliases = {
-    dns-hole = "clunk";
-    gateway = "clunk";
-    upstairs = "upstairs-desktop";
-    downstairs = "downstairs-desktop";
-  };
-
-  srv-records = {
-    tcp = {
-      domain = [{
-        port = 53;
-        host = "clunk.${local-domain}";
-      }];
-      kerberos = [{
-        port = 88;
-        host = "france.fudo.org";
-      }];
-      kerberos-adm = [{
-        port = 88;
-        host = "france.fudo.org";
-      }];
-      ssh = [{
-        port = 22;
-        host = "clunk.${local-domain}";
-      }];
-    };
-
-    udp = {
-      domain = [{
-        port = 53;
-        host = "clunk.${local-domain}";
-      }];
-      kerberos = [{
-        port = 88;
-        host = "france.fudo.org";
-      }];
-      kerboros-master = [{
-        port = 88;
-        host = "france.fudo.org";
-      }];
-      kpasswd = [{
-        port = 464;
-        host = "france.fudo.org";
-      }];
-    };
-  };
-}
diff --git a/lib/fudo/networks/sea.fudo.org.nix b/lib/fudo/networks/sea.fudo.org.nix
deleted file mode 100644
index 68e017b..0000000
--- a/lib/fudo/networks/sea.fudo.org.nix
+++ /dev/null
@@ -1,214 +0,0 @@
-{ config, lib, ... }:
-
-{
-  default-host = "10.0.0.1";
-
-  mx = [ "mail.fudo.org" ];
-
-  aliases = {
-    kadmin = "nostromo";
-    kdc = "nostromo";
-    photo = "doraemon";
-    music = "doraemon";
-    panopticon = "lambda";
-    panopticon-od = "lambda";
-    ipfs = "nostromo";
-    hole = "nostromo";
-    pihole = "nostromo";
-    dns-hole = "nostromo";
-    mon-1 = "srv-1";
-  };
-
-  srv-records = {
-    tcp = {
-      domain = [{
-        port = 53;
-        host = "nostromo.sea.fudo.org";
-      }];
-      kerberos = [{
-        port = 88;
-        host = "france.fudo.org";
-      }];
-      kerberos-adm = [{
-        port = 88;
-        host = "france.fudo.org";
-      }];
-      ssh = [{
-        port = 22;
-        host = "nostromo.sea.fudo.org";
-      }];
-      ldap = [{
-        port = 389;
-        host = "france.fudo.org";
-      }];
-    };
-
-    udp = {
-      domain = [{
-        port = 53;
-        host = "nostromo.sea.fudo.org";
-      }];
-      kerberos = [{
-        port = 88;
-        host = "france.fudo.org";
-      }];
-      kerboros-master = [{
-        port = 88;
-        host = "france.fudo.org";
-      }];
-      kpasswd = [{
-        port = 464;
-        host = "france.fudo.org";
-      }];
-    };
-  };
-
-  hosts = {
-    nostromo = {
-      ip-address = "10.0.0.1";
-      mac-address = "46:54:76:06:f1:10";
-    };
-    lm = {
-      ip-address = "10.0.0.2";
-      mac-address = "00:23:7d:e6:d9:ea";
-    };
-    lambda = {
-      ip-address = "10.0.0.3";
-      mac-address = "02:50:f6:52:9f:9d";
-    };
-    switch-master = {
-      ip-address = "10.0.0.5";
-      mac-address = "00:14:1C:B6:BB:40";
-    };
-    google-wifi = {
-      ip-address = "10.0.0.7";
-      mac-address = "7C:D9:5C:9F:6F:E9";
-    };
-    cam-entrance = {
-      ip-address = "10.0.0.31";
-      mac-address = "9c:8e:cd:0e:99:7b";
-    };
-    cam-driveway = {
-      ip-address = "10.0.0.32";
-      mac-address = "9c:8e:cd:0d:3b:09";
-    };
-    cam-deck = {
-      ip-address = "10.0.0.33";
-      mac-address = "9c:8e:cd:0e:98:c8";
-    };
-    cargo = {
-      ip-address = "10.0.0.50";
-      mac-address = "00:11:32:75:d8:b7";
-    };
-    whitedwarf = {
-      ip-address = "10.0.0.51";
-      mac-address = "00:11:32:12:14:1d";
-    };
-    doraemon = {
-      ip-address = "10.0.0.52";
-      mac-address = "00:11:32:0a:06:c5";
-    };
-    android = {
-      ip-address = "10.0.0.81";
-      mac-address = "00:16:3e:43:39:fc";
-    };
-    retro-wired = {
-      ip-address = "10.0.0.82";
-      mac-address = "dc:a6:32:6b:57:43";
-    };
-    retro = {
-      ip-address = "10.0.0.83";
-      mac-address = "dc:a6:32:6b:57:45";
-    };
-    monolith = {
-      ip-address = "10.0.0.100";
-      mac-address = "6c:62:6d:c8:b0:d8";
-    };
-    taipan = {
-      ip-address = "10.0.0.107";
-      mac-address = "52:54:00:34:c4:78";
-    };
-    spark = {
-      ip-address = "10.0.0.108";
-      mac-address = "78:24:af:04:f7:dd";
-    };
-    hyperion = {
-      ip-address = "10.0.0.109";
-      mac-address = "52:54:00:33:46:de";
-    };
-    zbox = {
-      ip-address = "10.0.0.110";
-      mac-address = "02:dd:80:52:83:9b";
-    };
-    ubiquiti-wifi = {
-      ip-address = "10.0.0.126";
-      mac-address = "04:18:d6:20:48:fb";
-    };
-    generator-wireless = {
-      ip-address = "10.0.0.130";
-      mac-address = "B8:27:EB:A6:32:26";
-    };
-    brother-wireless = {
-      ip-address = "10.0.0.160";
-      mac-address = "c0:38:96:64:49:65";
-    };
-    nest = {
-      ip-address = "10.0.0.176";
-      mac-address = "18:b4:30:16:7c:5a";
-    };
-    xixi-phone = {
-      ip-address = "10.0.0.193";
-      mac-address = "48:43:7c:75:89:42";
-    };
-    ipad = {
-      ip-address = "10.0.0.202";
-      mac-address = "9c:35:eb:48:6e:71";
-    };
-    cam-front = {
-      ip-address = "10.0.0.203";
-      mac-address = "c4:d6:55:3e:b4:c3";
-    };
-    family-tv = {
-      ip-address = "10.0.0.205";
-      mac-address = "84:a4:66:3a:b1:f8";
-    };
-    babycam = {
-      ip-address = "10.0.0.206";
-      mac-address = "08:ea:40:59:5f:9e";
-    };
-    workphone = {
-      ip-address = "10.0.0.211";
-      mac-address = "a8:8e:24:5c:12:67";
-    };
-    chromecast-2 = {
-      ip-address = "10.0.0.215";
-      mac-address = "a4:77:33:59:a2:ba";
-    };
-    front-light = {
-      ip-address = "10.0.0.221";
-      mac-address = "94:10:3e:48:94:ed";
-    };
-
-    # Ceph network
-    srv-1 = {
-      ip-address = "10.0.10.1";
-      mac-address = "02:65:d7:00:7d:1b";
-    };
-    node-1 = {
-      ip-address = "10.0.10.101";
-      mac-address = "00:1e:06:36:81:cf";
-    };
-    node-2 = {
-      ip-address = "10.0.10.102";
-      mac-address = "00:1e:06:36:ec:3e";
-    };
-    node-3 = {
-      ip-address = "10.0.10.103";
-      mac-address = "00:1e:06:36:ec:4b";
-    };
-    node-4 = {
-      ip-address = "10.0.10.104";
-      mac-address = "00:1e:06:36:dd:8c";
-    };
-  };
-}
diff --git a/lib/fudo/sites.nix b/lib/fudo/sites.nix
index 03599be..f3dcbdc 100644
--- a/lib/fudo/sites.nix
+++ b/lib/fudo/sites.nix
@@ -95,6 +95,12 @@ let
         description = "Location of Dropbear ECDSA key.";
         default = "/etc/dropbear/host_ecdsa_key";
       };
+
+      dropbear-deploy-port = mkOption {
+        type = port;
+        description = "Port to be used for the deploy SSH server.";
+        default = 2112;
+      };
     };
   };
 
@@ -107,16 +113,30 @@ in {
 
   config = mkIf (site-cfg.deploy-pubkey != null) {
     environment.etc."dropbear/authorized_keys" = {
-      text = "root@deploy ${site-cfg.deploy-pubkey}";
+      text = "${site-cfg.deploy-pubkey} root@deploy";
       mode = "0400";
     };
 
-    systemd.services = let dropbear-port = 2112;
-    in {
+    networking.firewall.allowedTCPPorts = [ site-cfg.dropbear-deploy-port ];
 
-      dropbear-init = {
-        wantedBy = [ "multi-user.target" ];
-        script = ''
+    systemd = {
+      sockets = {
+        dropbear-deploy = {
+          wantedBy = [ "sockets.target" ];
+          socketConfig = {
+            ListenStream = "0.0.0.0:${toString site-cfg.dropbear-deploy-port}";
+            Accept = true;
+          };
+          unitConfig = {
+            restartIfChanged = true;
+          };
+        };
+      };
+      
+      services = {
+        dropbear-deploy-init = {
+          wantedBy = [ "multi-user.target" ];
+          script = ''
           if [ ! -d /etc/dropbear ]; then
             mkdir /etc/dropbear
             chmod 700 /etc/dropbear
@@ -132,15 +152,18 @@ in {
             ${pkgs.coreutils}/bin/chmod 0400 ${site-cfg.dropbear-ecdsa-key-path}
           fi
         '';
-      };
+        };
 
-      dropbear = {
-        requires = [ "dropbear-init.service" ];
-        wantedBy = [ "multi-user.target" ];
-        after = [ "network.target" ];
-        serviceConfig = {
-          type = "simple";
-          ExecStart = "${pkgs.dropbear} -F -m -s -j -k -p ${dropbear-port}";
+        "dropbear-deploy@" = {
+          description = "Per-connection service for deployment, using dropbear.";
+          requires = [ "dropbear-deploy-init.service" ];
+          after = [ "network.target" ];
+          serviceConfig = {
+            Type = "simple";
+            ExecStart = "${pkgs.dropbear}/bin/dropbear -F -i -m -s -j -k -r ${site-cfg.dropbear-rsa-key-path} -r ${site-cfg.dropbear-ecdsa-key-path}";
+            ExecReload = "${pkgs.utillinux}/bin/kill -HUP $MAINPID";
+            StandardInput = "socket";
+          };
         };
       };
     };