about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--modules/tailscale-initrd.nix99
-rw-r--r--nixos/.sops.yaml6
-rw-r--r--nixos/default.nix13
-rw-r--r--nixos/kanata/configuration.nix112
-rw-r--r--nixos/kanata/hardware-configuration.nix56
-rw-r--r--nixos/kanata/secrets/secrets.yaml32
7 files changed, 320 insertions, 0 deletions
diff --git a/README.md b/README.md
index 1fbab0d..bbbb07e 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,8 @@
 
 `haruka` - Laptop (Thinkpad X1C11)
 
+`kanata` - Server
+
 ## TODO
 
 - cleanup `home/communication` module
diff --git a/modules/tailscale-initrd.nix b/modules/tailscale-initrd.nix
new file mode 100644
index 0000000..4b7610e
--- /dev/null
+++ b/modules/tailscale-initrd.nix
@@ -0,0 +1,99 @@
+# To set this up, first get tailscale working in an isolated linux shell:
+#  1. sudo systemctl stop tailscaled.service
+#  2. tailscaled -port 9993 -state tailscale-luks-setup.state -tun userspace-networking -socket ./tailscaled.sock
+#  3. tailscale -socket ./tailscaled.sock up -hostname HOSTNAME-luks
+#  4. tailscale -socket ./tailscaled.sock down
+#  5. ctrl-c out of tailscaled
+#  6 sudo systemctl start tailscaled.service
+#
+# Then add the .state file to your machine secrets and pass its path as tailscaleStatePath.
+
+{ config, lib, pkgs, ... }: {
+  options = {
+    modules.tailscale-initrd = with lib; {
+      enable = mkOption {
+        description = "Turn on unlock via tailscale";
+        default = false;
+      };
+
+      tailscaleStatePath = mkOption {
+        description = "Pre-initialized tailscale state file as a secret. Make sure to set it to not require re-authentication, otherwise the machine may not boot up after a few weeks.";
+      };
+    };
+  };
+
+  config =
+    let
+      cfg = config.modules.tailscale-initrd;
+      # TODO: This uses old-style non-nftables iptables; ideally, we wouldn't have to opt out of that.
+      # Enabling nftables compat means having to shuffle the list of
+      # modules down in availableKernelModules; that's a bunch of work
+      # (deploying to a linux machine & rebooting to see what doesn't
+      # work this time), so I'm a bit too lazy for that now.
+      iptables-static = (pkgs.iptables.override { nftablesCompat = false; }).overrideAttrs (old: {
+        dontDisableStatic = true;
+        configureFlags = (lib.remove "--enable-shared" old.configureFlags) ++ [
+          "--enable-static"
+          "--disable-shared"
+        ];
+      });
+    in
+    lib.mkIf cfg.enable {
+      boot.initrd = {
+        secrets = {
+          "/var/lib/tailscale/tailscaled.state" = cfg.tailscaleStatePath;
+          "/etc/ssl/certs/ca-certificates.crt" = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
+          "/etc/ssl/certs/ca-bundle.crt" = "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt";
+        };
+        network = {
+          enable = true;
+          flushBeforeStage2 = true;
+          postCommands = ''
+            # Bring up tailscaled and dial in
+            echo 'nameserver 8.8.8.8' > /etc/resolv.conf
+            mkdir /dev/net
+            mknod /dev/net/tun c 10 200
+            .tailscaled-wrapped 2>/dev/null &
+            sleep 5
+            .tailscale-wrapped up
+            .tailscale-wrapped status
+
+            echo "echo 'Use cryptsetup-askpass to unlock!'" >> /root/.profile
+          '';
+        };
+        availableKernelModules = [
+          "ip6_tables"
+          "ip6table_filter"
+          "ip6table_nat"
+          "ip6table_raw"
+          "ip_tables"
+          "iptable_filter"
+          "iptable_nat"
+          "iptable_raw"
+          "nf_conntrack"
+          "nf_nat"
+          "tun"
+          "xt_comment"
+          "xt_conntrack"
+          "xt_mark"
+          "xt_MASQUERADE"
+          "xt_LOG"
+          "xt_tcpudp"
+        ];
+        extraUtilsCommands = ''
+          copy_bin_and_libs ${pkgs.tailscale}/bin/.tailscaled-wrapped
+          copy_bin_and_libs ${pkgs.tailscale}/bin/.tailscale-wrapped
+          copy_bin_and_libs ${pkgs.iproute}/bin/ip
+          copy_bin_and_libs ${iptables-static}/bin/iptables
+          copy_bin_and_libs ${iptables-static}/bin/xtables-legacy-multi
+
+          copy_bin_and_libs ${pkgs.strace}/bin/strace
+        '';
+        postMountCommands = ''
+          # tear down tailscale
+          pkill .tailscaled-wrapped
+          .tailscaled-wrapped --cleanup
+        '';
+      };
+    };
+}
diff --git a/nixos/.sops.yaml b/nixos/.sops.yaml
index 9815b58..23bf30c 100644
--- a/nixos/.sops.yaml
+++ b/nixos/.sops.yaml
@@ -4,6 +4,7 @@ keys:
   - &host_alpha age100jkyvgl8hqkapw3s4s4uu8jjgfkjn8kyl769x8u4x6tddk6rezshtf6gr
   - &host_kompakt age180yj8dn9jhjzj9c0y6qr5fa76g0ls3p772dvn60nu67wveqv8pvsahvur6
   - &host_haruka age1hn509x2uuk0nrvfkaexwrengdtngh8uwx6fxldfgn8f4hhhsqdwsgnprr7
+  - &host_kanata age1p34akfj7gynfkwppk2dc80u5dsfynzllrvz5qwemuxrqhdp8t9xsqejy0l
 creation_rules:
   - path_regex: alpha/secrets/[^/]+\.yaml$
     key_groups:
@@ -20,3 +21,8 @@ creation_rules:
       - age:
         - *sefidel
         - *host_kompakt
+  - path_regex: kanata/secrets/[^/]+\.yaml$
+    key_groups:
+    - age:
+      - *sefidel
+      - *host_kanata
diff --git a/nixos/default.nix b/nixos/default.nix
index 49ffb27..486c9a9 100644
--- a/nixos/default.nix
+++ b/nixos/default.nix
@@ -29,4 +29,17 @@
       inputs.impermanence.nixosModules.impermanence
     ];
   };
+
+  kanata = self.lib.mkSystem {
+    name = "kanata";
+    nixpkgs = unstable;
+    extraModules = [
+      ../modules/security.nix
+      ../modules/cachix
+      ../modules/trayscale.nix
+      ../modules/tailscale-initrd.nix
+      inputs.sops-nix.nixosModules.sops
+      inputs.impermanence.nixosModules.impermanence
+    ];
+  };
 }
diff --git a/nixos/kanata/configuration.nix b/nixos/kanata/configuration.nix
new file mode 100644
index 0000000..b7933c0
--- /dev/null
+++ b/nixos/kanata/configuration.nix
@@ -0,0 +1,112 @@
+{ config, lib, input, pkgs, ... }:
+
+let
+  sefidelKeys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILN14b5Fu+StHeMXq4ClyLG4G+/vCAfS7adxceEFria/ openpgp:0x1D5BCD11" ];
+  maintainerKeys = [ ] ++ sefidelKeys;
+in
+{
+  imports = [ ];
+
+  deployment = {
+    targetHost = "kanata.bee-polaris.ts.net";
+    targetUser = "root";
+  };
+
+  boot.loader.systemd-boot.enable = true;
+  boot.loader.efi.canTouchEfiVariables = true;
+
+  boot.supportedFilesystems = [ "zfs" ];
+  networking.hostId = "31cc5527";
+
+  networking.hostName = "kanata";
+
+  # Erase your darlings
+  boot.initrd.postDeviceCommands = lib.mkAfter ''
+    zfs rollback -r rpool/local/root@blank
+  '';
+
+  boot.kernelModules = [ "r8169" ];
+  boot.initrd.kernelModules = [ "r8169" ];
+
+  boot.initrd.network.enable = true;
+  boot.initrd.network.ssh = {
+    enable = true;
+
+    # Using the same port as the actual SSH daemon will cause the clients to
+    # throw errors related to host key mismatch.
+    port = 2222;
+
+    hostKeys = [
+      # XXX: This has to be manually generated during NixOS install.
+      # The files are then copied to initrd secrets during activation.
+      "/persist/initrd/ssh_host_rsa_key"
+      "/persist/initrd/ssh_host_ed25519_key"
+    ];
+
+    authorizedKeys = maintainerKeys;
+  };
+
+  boot.initrd.network.postCommands = ''
+    cat <<EOF > /root/.profile
+    if pgrep -x "zfs" > /dev/null
+    then
+      zfs load-key -a
+      killall zfs
+    else
+      echo "ZFS is not running -- this could be a sign of failure."
+    fi
+    EOF
+  '';
+
+  modules.tailscale-initrd = {
+    enable = true;
+    # XXX: This has to be manually generatd during NixOS install.
+    # The files are then copied to initrd secrets during activation.
+    tailscaleStatePath = "/persist/initrd/tailscale-initrd.state";
+  };
+
+  services.openssh.enable = true;
+  users.users.root.openssh.authorizedKeys.keys = maintainerKeys;
+
+  fileSystems."/persist".neededForBoot = true;
+
+  services.openssh.hostKeys = [
+    {
+      path = "/persist/ssh/ssh_host_ed25519_key";
+      type = "ed25519";
+    }
+    {
+      path = "/persist/ssh/ssh_host_rsa_key";
+      type = "rsa";
+      bits = 4096;
+    }
+  ];
+
+  services.tailscale = {
+    enable = true;
+    useRoutingFeatures = "both";
+  };
+
+  environment.persistence."/persist".directories = [ "/var/lib/tailscale" ];
+
+  sops.defaultSopsFile = ./secrets/secrets.yaml;
+
+  # This option defines the first version of NixOS you have installed on this particular machine,
+  # and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
+  #
+  # Most users should NEVER change this value after the initial install, for any reason,
+  # even if you've upgraded your system to a new NixOS release.
+  #
+  # This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
+  # so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
+  # to actually do that.
+  #
+  # This value being lower than the current NixOS release does NOT mean your system is
+  # out of date, out of support, or vulnerable.
+  #
+  # Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
+  # and migrated your data accordingly.
+  #
+  # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
+  system.stateVersion = "24.05"; # Did you read the comment?
+}
diff --git a/nixos/kanata/hardware-configuration.nix b/nixos/kanata/hardware-configuration.nix
new file mode 100644
index 0000000..b81b08d
--- /dev/null
+++ b/nixos/kanata/hardware-configuration.nix
@@ -0,0 +1,56 @@
+# Do not modify this file!  It was generated by ‘nixos-generate-config’
+# and may be overwritten by future invocations.  Please make changes
+# to /etc/nixos/configuration.nix instead.
+{ config, lib, pkgs, modulesPath, ... }:
+
+{
+  imports =
+    [ (modulesPath + "/installer/scan/not-detected.nix")
+    ];
+
+  boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "mpt3sas" "usbhid" "usb_storage" "sd_mod" ];
+  boot.initrd.kernelModules = [ ];
+  boot.kernelModules = [ "kvm-amd" ];
+  boot.extraModulePackages = [ ];
+
+  fileSystems."/" =
+    { device = "rpool/local/root";
+      fsType = "zfs";
+    };
+
+  fileSystems."/boot" =
+    { device = "/dev/disk/by-uuid/7141-F8DA";
+      fsType = "vfat";
+    };
+
+  fileSystems."/nix" =
+    { device = "rpool/local/nix";
+      fsType = "zfs";
+    };
+
+  fileSystems."/home" =
+    { device = "rpool/safe/home";
+      fsType = "zfs";
+    };
+
+  fileSystems."/persist" =
+    { device = "rpool/safe/persist";
+      fsType = "zfs";
+    };
+
+  swapDevices =
+    [ { device = "/dev/disk/by-uuid/c092b7a3-813c-4be7-9730-45d9426f524c"; }
+    ];
+
+  # Enables DHCP on each ethernet and wireless interface. In case of scripted networking
+  # (the default) this is the recommended approach. When using systemd-networkd it's
+  # still possible to use this option, but it's recommended to use it in conjunction
+  # with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
+  # TODO FIXME(sefidel): uncomment
+  # networking.useDHCP = lib.mkDefault true;
+  networking.useDHCP = lib.mkForce true;
+  # networking.interfaces.enp4s0.useDHCP = lib.mkDefault true;
+
+  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
+  hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
+}
diff --git a/nixos/kanata/secrets/secrets.yaml b/nixos/kanata/secrets/secrets.yaml
new file mode 100644
index 0000000..b88ffd7
--- /dev/null
+++ b/nixos/kanata/secrets/secrets.yaml
@@ -0,0 +1,32 @@
+initrd-ssh-host-rsa-key: ENC[AES256_GCM,data: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,iv:lA2dygMQoZ3tja54IA6HcKOSZfTnC7VDytqP26CWRcM=,tag:KTa+qQx+s/q7j90ruRK+pg==,type:str]
+initrd-ssh-host-ed25519-key: ENC[AES256_GCM,data:eD8UZZ6FnqT5tP+y1xDrtjKjl/DQLXEQs/a4snHoHKHbyNmHXM8aO5o5QuPP6F9MMi0KvrnMHXJs+OqnA+/ZpXD3LJ/k13xIijktWPcpY97X6790ZmkIjE797LiV5YRuwuMQOQVsipISjVmlRWY1UpO4VO8n/TvMJV+SbJUgI3sfK1H5/xG0DlwdPJ1Wb8UVEK/3RPo75Z0tJ7OX7gNwPAh2pEz7XKHjIFdnNwjPgFOCO958ozSZPPMJElUjaffAMyiNBJPdPjV0TYxSD+G5/CVs3pWOEHD2FaF2Gx+BMHT8VRKIGW1cQOQjOBwePx5kQesPl9AkavpP6QOsbktY3+c9Dt4+G4XKsZ0ZpvlCRKf60u39z/K5DvM4CiNzu+nm+hfFcCXEHleFKq2BPB13tMJ3IaEtqA8TJ/8NqkP9zlnRuf/5sxSktUxAri9uIv8s++xNNSsIu+9BYK41t8Snso0uT3AN1emAsLGBMBQLpGzrC6l8WvfntAU7D9HTB0EA6xQCm7Pj+SIU6cxyVkUY,iv:GWEDQtmutLsL9RVQGoXv/uwg9gHKr/QA2/I9g52obqM=,tag:Rs6uaU9hwaoSP7oifJwkbA==,type:str]
+initrd-ts-state: ENC[AES256_GCM,data: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,iv:sGA4zACuGYJ3P/auaHXOttP8TGyVgf++Ppk6jiekUbw=,tag:/+XtiRJIjTA7MM5sYdPlSg==,type:str]
+sops:
+    kms: []
+    gcp_kms: []
+    azure_kv: []
+    hc_vault: []
+    age:
+        - recipient: age1jt8xg0lvzj5q4f7fn7nw670qsszm3kv3caa654eh62azra4x44zss4fad8
+          enc: |
+            -----BEGIN AGE ENCRYPTED FILE-----
+            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIdEh3bFhBUDBCRnRVeENB
+            a01ZdUltSEcxdDQ0YkRKdEovdlVXRlBBb1dNCnh6dG5kNEVHSWhEczNnZVZEUGxu
+            S3JwTmlDWStIYVJ6bEluUXpVRWFNVG8KLS0tIHVQbWlzVERVbHZGQ0F5ZGhrZjIx
+            eTQxK0wvQXplcjV3NGFFUXlDSThWVkkKJCI60m4eplTotQlMbrB7C6pSHJg46pMn
+            hdguKASypsXKiVVrBfGv5dY2ThWH5WeMH8v7c88nDak0PnpFB1N9Uw==
+            -----END AGE ENCRYPTED FILE-----
+        - recipient: age1p34akfj7gynfkwppk2dc80u5dsfynzllrvz5qwemuxrqhdp8t9xsqejy0l
+          enc: |
+            -----BEGIN AGE ENCRYPTED FILE-----
+            YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqa3E0eE1MWkloWUZGSmdM
+            VjAyMGh5Qkp3dkcwRVVDY1ZoWUZ3QktzOVhVCkFJMkFkMVhaWmlyZmFMSG1yNnBw
+            UFJqbU82OVVXVm5UNXZzN21KTWFzY1kKLS0tIGRPRjdGbWNGRnlIWVBjZDdIRXNh
+            YkRGS2ZBbm1keWpUQUFOWDRtTWZVa0EKc+lKEP0L/yoFLx6p1zbWfifPWc7Y9Qqh
+            qccODSyHqzwdriHLxXuw9SCnF+SeA721te6+pDVhJj8vqv2UqHiATw==
+            -----END AGE ENCRYPTED FILE-----
+    lastmodified: "2024-01-22T15:59:14Z"
+    mac: ENC[AES256_GCM,data:lvTdQhmlvLfycaE9a8c4Pw79yV7a7ic7z4BgTMSKuh95cC6/NdL4yqjhG5U5wX4PAl4v3Qx/GsfqtVcMUxyzT0ZWdWTpnLh6yBwYx413IwHziQg0di6YB9FOfcOMRfEqkc+tTV146A8aeTigxUI4biS3+NHOPjDPrUulAgr1s88=,iv:HguUOQhq3F+wnKkVKxeBCoBtxToGK1LWNG2ARYjKh+M=,tag:7On9A+A3LfGF+SQedEfOJg==,type:str]
+    pgp: []
+    unencrypted_suffix: _unencrypted
+    version: 3.8.1