Commit a8b437d

HPCesia <me@hpcesia.com>
2025-10-05 10:49:36
refactor: migrate networking and ssh config
1 parent 3c36fe4
home/base/tui/ssh.nix
@@ -1,21 +0,0 @@
-{...}: {
-  programs.ssh = {
-    enable = true;
-    enableDefaultConfig = false;
-
-    matchBlocks = {
-      "*".addKeysToAgent = "yes";
-      "github.com" = {
-        # "Using SSH over the HTTPS port for GitHub"
-        # "(port 22 is banned by some proxies / firewalls)"
-        hostname = "ssh.github.com";
-        port = 443;
-        user = "git";
-
-        # Specifies that ssh should only use the identity file explicitly configured above
-        # required to prevent sending default identity files first.
-        identitiesOnly = true;
-      };
-    };
-  };
-}
hosts/general.nix
@@ -12,7 +12,7 @@
         enable = "networkd";
         iface = "eth0";
         useDHCP = false;
-        nameservers = ["172.16.36.100"] ++ myvars.defaultNameservers;
+        nameservers = myvars.defaultNameservers;
         search = ["local"];
         ipv4 = {secretName = "pardofelis-ipv4";};
         ipv6 = {secretName = "pardofelis-ipv6";};
modules/core/networking/nameserver.nix
@@ -0,0 +1,12 @@
+{
+  flake.modules.nixos.core = _: {
+    networking.nameservers = [
+      # IPv4
+      "119.29.29.29" # DNSPod
+      "223.5.5.5" # AliDNS
+      # IPv6
+      "2400:3200::1" # Alidns
+      "2606:4700:4700::1111" # Cloudflare
+    ];
+  };
+}
modules/core/networking/timeserver.nix
@@ -0,0 +1,9 @@
+{
+  flake.modules.nixos.core = _: {
+    # Use an NTP server located in the mainland of China to synchronize the system time
+    networking.timeServers = [
+      "ntp.aliyun.com" # Aliyun NTP Server
+      "ntp.tencent.com" # Tencent NTP Server
+    ];
+  };
+}
modules/core/ssh.nix
@@ -0,0 +1,21 @@
+topArgs: {
+  flake.modules.nixos.core = {config, ...}: {
+    services.openssh = let
+      currentHostMeta = topArgs.config.flake.meta.host.hosts.${config.networking.hostName};
+    in {
+      enable = currentHostMeta.deploy; # Enable ssh server only for deployable hosts
+      ports = currentHostMeta.sshPorts;
+      settings = {
+        PermitRootLogin = "prohibit-password";
+        PasswordAuthentication = false;
+      };
+      openFirewall = true;
+      hostKeys = [
+        {
+          path = "/etc/ssh/ssh_host_ed25519_key";
+          type = "ed25519";
+        }
+      ];
+    };
+  };
+}
modules/dev/ssh.nix
@@ -0,0 +1,23 @@
+{
+  flake.modules.homeManager.dev = _: {
+    programs.ssh = {
+      enable = true;
+      enableDefaultConfig = false;
+
+      matchBlocks = {
+        "*".addKeysToAgent = "yes";
+        "github.com" = {
+          # "Using SSH over the HTTPS port for GitHub"
+          # "(port 22 is banned by some proxies / firewalls)"
+          hostname = "ssh.github.com";
+          port = 443;
+          user = "git";
+
+          # Specifies that ssh should only use the identity file explicitly configured above
+          # required to prevent sending default identity files first.
+          identitiesOnly = true;
+        };
+      };
+    };
+  };
+}
modules/flake/meta.nix
@@ -26,9 +26,14 @@
           type = types.str;
           description = "Public host key of the host.";
         };
+        sshPorts = mkOption {
+          type = types.listOf types.port;
+          default = [22];
+          description = "SSH ports of the host.";
+        };
         deploy = lib.mkEnableOption {
           default = false;
-          description = "Whether to deploy the host using deploy-rs.";
+          description = "Whether to deploy this host using deploy-rs.";
         };
       };
     };
modules/hosts/chaser-kevin/default.nix
@@ -15,6 +15,7 @@
         desktop
         user-root
         user-hpcesia
+        ssh-host-pardofelis
       ])
       ++ (
         map
modules/hosts/chaser-kevin/networking.nix
@@ -0,0 +1,7 @@
+{
+  flake.modules.nixos."hosts/kevin" = _: {
+    networking = {
+      networkmanager.enable = true;
+    };
+  };
+}
modules/hosts/chaser-pardofelis/networking/default.nix
@@ -0,0 +1,80 @@
+{lib, ...} @ topArgs: {
+  flake.modules.nixos."hosts/pardofelis" = {config, ...}: let
+    iface = "eth0";
+  in {
+    networking = {
+      useNetworkd = true;
+      useDHCP = false;
+      search = ["local"];
+    };
+
+    systemd.network.networks."10-${iface}" = {
+      matchConfig.Name = iface;
+      dns = ["172.16.36.100"] ++ config.networking.nameservers;
+      linkConfig.RequiredForOnline = "routable";
+    };
+
+    environment.etc."systemd/network/10-${iface}.network.d/99-address.conf" = {
+      source = config.vaultix.templates.networkd-address.path;
+      user = "root";
+      group = "systemd-network";
+      mode = "0440";
+    };
+    environment.etc."systemd/network/10-${iface}.network.d/99-route.conf" = {
+      source = config.vaultix.templates.networkd-route.path;
+      user = "root";
+      group = "systemd-network";
+      mode = "0440";
+    };
+
+    vaultix.templates.networkd-address = {
+      content = ''
+        [Network]
+        Address=${config.vaultix.placeholder.hosts-pardofelis-ipv4}/24
+        Address=${config.vaultix.placeholder.hosts-pardofelis-ipv6}/64
+      '';
+      owner = "root";
+      group = "systemd-network";
+      mode = "0440";
+    };
+    vaultix.templates.networkd-route = {
+      content = ''
+        [Route]
+        Gateway=${config.vaultix.placeholder.hosts-pardofelis-gateway}
+        Destination=0.0.0.0/0
+        [Route]
+        Gateway=${config.vaultix.placeholder.hosts-pardofelis-gateway6}
+        Destination=::/0
+      '';
+      owner = "root";
+      group = "systemd-network";
+      mode = "0440";
+    };
+
+    vaultix.secrets.hosts-pardofelis-ipv4.file = ./ipv4.age;
+    vaultix.secrets.hosts-pardofelis-ipv6.file = ./ipv6.age;
+    vaultix.secrets.hosts-pardofelis-gateway.file = ./gateway.age;
+    vaultix.secrets.hosts-pardofelis-gateway6.file = ./gateway6.age;
+  };
+
+  flake.modules.nixos.ssh-host-pardofelis = {config, ...}: {
+    programs.ssh.extraConfig = ''
+      Host pardofelis
+        Port ${toString (lib.elemAt (topArgs.config.flake.meta.host.hosts.pardofelis.sshPorts) 0)}
+        Include ${config.vaultix.templates."ssh-host-pardofelis".path}
+    '';
+
+    users.groups.nix-secrets-ssh-hosts = {};
+
+    vaultix.templates.ssh-host-pardofelis = {
+      content = ''
+        HostName ${config.vaultix.placeholder.hosts-pardofelis-ipv4}
+      '';
+      owner = "root";
+      group = "nix-secrets-ssh-hosts";
+      mode = "0440";
+    };
+
+    vaultix.secrets.hosts-pardofelis-ipv4.file = ./ipv4.age;
+  };
+}
modules/hosts/chaser-pardofelis/networking/gateway.age
@@ -0,0 +1,9 @@
+age-encryption.org/v1
+-> X25519 1LEJ3b9+wwcff4D79LMtsKrD+bBxpoTXlY7HVJ7AhR4
+E6VaeACNscpcsU0qUXPYq07BOKoxLc4ahMA5rqjhNrQ
+-> G7,@-grease 6
+MBCM675L9qRm9cGVOlvlzLHDDI3jscVrefZl6AkjTkRkarAdjYVBGG0/vC4QfsM2
+
+--- KMuWlAgay5ooibe/IykyH7nvB8Xbj3ZjUXCLiNKMijA
+ϊ�r�ڝ���p�q�V��r����t�	��(�.�T�}�ȼ�
 EC
+�
\ No newline at end of file
modules/hosts/chaser-pardofelis/networking/gateway6.age
Binary file
modules/hosts/chaser-pardofelis/networking/ipv4.age
Binary file
modules/hosts/chaser-pardofelis/networking/ipv6.age
@@ -0,0 +1,7 @@
+age-encryption.org/v1
+-> X25519 mb8GatjG/0DfFJ8g6XoWj/UdKNugGMLOIyPWIqSTFz0
+EiC6OQY4xkoQda4a7Gv+hg5frKdQGzMOE9wp9BtA9ZE
+-> I[EQ-grease FHNPc.fh *]p/= C=6s4xU NQiYr
+Luc
+--- I6bVLsXJOb8Feii7pNUix+QS6+C87CnvaFSbmeOQUYA
+a�S�bTe��9�*a?9jF�[�T�q��`���]?w��ן����;ÛZ�1�y��
\ No newline at end of file
modules/hosts/chaser-pardofelis/default.nix
@@ -7,6 +7,7 @@
     system = "x86_64-linux";
     hostPubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEuT/WkeA7btTeATmWJ2O9f/A6FI0Gl/1KjPGfHbWD5C root@pardofelis";
     deploy = true;
+    sshPorts = [23930];
   };
   flake.modules.nixos."hosts/pardofelis" = {
     imports =
modules/users/hpcesia.nix
@@ -9,11 +9,14 @@
         "users"
         "networkmanager"
         "wheel"
+        "nix-secrets-ssh-hosts"
       ];
       openssh.authorizedKeys.keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIyxd+nyK9cnULmzXIMhE1/rIB3VMsJ6SuWV4Ha8oE0F hpcesia@kevin"];
     };
 
     users.groups.hpcesia = {};
+
+    users.groups.nix-secrets-ssh-hosts = {};
   };
 
   flake.modules.homeManager.user-hpcesia = _: {
os-modules/base/users.nix
@@ -1,67 +0,0 @@
-{
-  lib,
-  config,
-  ...
-}: let
-  hosts = config.modules.my-hosts;
-  managedHosts =
-    lib.filterAttrs (
-      name: host:
-        !builtins.isNull host.hostPublicKey
-        && (!builtins.isNull host.network.ipv4 || !builtins.isNull host.network.ipv6)
-    )
-    hosts;
-  secretIpHosts =
-    lib.filterAttrs (
-      name: host:
-        isSecret host.network.ipv4 || isSecret host.network.ipv6
-    )
-    managedHosts;
-
-  isSecret = v: lib.isAttrs v && v ? "secretName";
-  isPlain = v: lib.isString v;
-in {
-  programs.mosh.enable = true; # Alternative of SSH for high latency connections
-  programs.ssh.knownHosts =
-    lib.mapAttrs'
-    (name: host: lib.nameValuePair name {publicKey = host.hostPublicKey;})
-    managedHosts;
-
-  programs.ssh.extraConfig = ''
-    ${lib.concatStringsSep "\n" (
-      lib.mapAttrsToList (
-        name: host: let
-          cfg = host.network;
-        in ''
-          Host ${name}
-            ${lib.optionalString (isPlain cfg.ipv4) "HostName ${cfg.ipv4}"}
-            ${lib.optionalString (isPlain cfg.ipv6) "HostName ${cfg.ipv6}"}
-            ${
-            lib.optionalString (isSecret cfg.ipv4 || isSecret cfg.ipv6)
-            "Include ${config.sops.templates."ssh-config-${name}".path}"
-          }
-            Port ${toString (lib.elemAt host.sshPorts 0)}
-        ''
-      )
-      managedHosts
-    )}
-  '';
-
-  sops.templates =
-    lib.mapAttrs'
-    (name: host:
-      lib.nameValuePair "ssh-config-${name}" {
-        content = ''
-          ${lib.optionalString (isSecret host.network.ipv4) ''
-            HostName ${config.sops.placeholder.${host.network.ipv4.secretName}}
-          ''}
-          ${lib.optionalString (isSecret host.network.ipv6) ''
-            HostName ${config.sops.placeholder.${host.network.ipv6.secretName}}
-          ''}
-        '';
-        owner = "root";
-        group = "ssh-secrets-users";
-        mode = "0440";
-      })
-    secretIpHosts;
-}
os-modules/nixos/base/networking.nix
@@ -1,148 +0,0 @@
-{
-  config,
-  lib,
-  ...
-}: let
-  hostName = config.modules.currentHost;
-in
-  lib.mkMerge [
-    {
-      # Use an NTP server located in the mainland of China to synchronize the system time
-      networking.timeServers = [
-        "ntp.aliyun.com" # Aliyun NTP Server
-        "ntp.tencent.com" # Tencent NTP Server
-      ];
-    }
-
-    (let
-      cfg = config.modules.my-hosts.${hostName}.network;
-    in
-      lib.mkIf cfg.useDHCP {
-        assertions = map (x: {
-          assertion = cfg.${x} == null;
-          message = "my-host.network.useDHCP is confilt with my-host.network.${x}";
-        }) ["ipv4" "ipv6"];
-      })
-
-    (let
-      cfg = config.modules.my-hosts.${hostName}.network;
-    in
-      lib.mkIf
-      (cfg.enable == "networkmanager")
-      {
-        assertions = map (x: {
-          assertion = !(cfg.${x} ? "secretName");
-          message = "my-host.network.${x} should not be a secret when using networkmanager.";
-        }) ["ipv4" "ipv6" "defaultGateway" "defaultGateway6"];
-        networking = with cfg; {
-          networkmanager.enable = true;
-          useDHCP = lib.mkDefault useDHCP;
-          inherit hostName search defaultGateway defaultGateway6 nameservers;
-          interfaces.${cfg.iface} = lib.mkIf (!builtins.isNull cfg.ipv4 && !builtins.isNull cfg.ipv6) {
-            ipv4.addresses = lib.optional (!builtins.isNull cfg.ipv4) {
-              address = cfg.ipv4;
-              prefixLength = cfg.prefixLength4;
-            };
-            ipv6.addresses = lib.optional (!builtins.isNull cfg.ipv6) {
-              address = cfg.ipv6;
-              prefixLength = cfg.prefixLength6;
-            };
-          };
-        };
-      })
-    (let
-      cfg = config.modules.my-hosts.${hostName}.network;
-      isSecret = v: lib.isAttrs v && v ? "secretName";
-      isInEval = x: (!builtins.isNull x && !isSecret x);
-    in
-      lib.mkIf
-      (cfg.enable == "networkd")
-      {
-        networking.useNetworkd = true;
-        networking.hostName = hostName;
-        systemd.network.networks."10-${cfg.iface}" = {
-          matchConfig.Name = [cfg.iface];
-          networkConfig = {
-            Address =
-              (lib.optionals (isInEval cfg.ipv4)
-                ["${cfg.ipv4}/${toString cfg.prefixLength4}"])
-              ++ (lib.optionals (isInEval cfg.ipv6)
-                ["${cfg.ipv6}/${toString cfg.prefixLength6}"]);
-            DNS = cfg.nameservers;
-          };
-          routes =
-            (lib.optional (isInEval cfg.defaultGateway)
-              {
-                Destination = "0.0.0.0/0";
-                Gateway = cfg.defaultGateway;
-              })
-            ++ (lib.optional (isInEval cfg.defaultGateway6) {
-              Destination = "::/0";
-              Gateway = cfg.defaultGateway6;
-            });
-          linkConfig.RequiredForOnline = "routable";
-        };
-
-        environment.etc."systemd/network/10-${cfg.iface}.network.d/99-address.conf" =
-          lib.mkIf
-          (isSecret cfg.ipv4 || isSecret cfg.ipv6)
-          {
-            source = config.sops.templates.networkd-address.path;
-            user = "root";
-            group = "systemd-network";
-            mode = "0440";
-          };
-        environment.etc."systemd/network/10-${cfg.iface}.network.d/99-route.conf" =
-          lib.mkIf
-          (isSecret cfg.defaultGateway || isSecret cfg.defaultGateway6)
-          {
-            source = config.sops.templates.networkd-route.path;
-            user = "root";
-            group = "systemd-network";
-            mode = "0440";
-          };
-
-        sops.templates.networkd-address = {
-          content =
-            lib.mkIf
-            (isSecret cfg.ipv4 || isSecret cfg.ipv6)
-            ''
-              [Network]
-              ${
-                lib.optionalString (isSecret cfg.ipv4)
-                "Address=${config.sops.placeholder.${cfg.ipv4.secretName}}/${toString cfg.prefixLength4}"
-              }
-              ${
-                lib.optionalString (isSecret cfg.ipv6)
-                "Address=${config.sops.placeholder.${cfg.ipv6.secretName}}/${toString cfg.prefixLength6}"
-              }
-            '';
-          owner = "root";
-          group = "systemd-network";
-          mode = "0440";
-        };
-        sops.templates.networkd-route = {
-          content =
-            lib.mkIf
-            (isSecret cfg.defaultGateway || isSecret cfg.defaultGateway6)
-            "${
-              lib.optionalString (isSecret cfg.defaultGateway)
-              ''
-                [Route]
-                Gateway=${config.sops.placeholder.${cfg.defaultGateway.secretName}}
-                Destination=0.0.0.0/0
-              ''
-            }\n${
-              lib.optionalString (isSecret cfg.defaultGateway6)
-              ''
-                [Route]
-                Gateway=${config.sops.placeholder.${cfg.defaultGateway6.secretName}}
-                Destination=::/0
-              ''
-            }";
-          owner = "root";
-          group = "systemd-network";
-          mode = "0440";
-        };
-      })
-  ]
os-modules/nixos/base/ssh.nix
@@ -7,23 +7,6 @@
 in {
   # Or disable the firewall altogether.
   networking.firewall.enable = lib.mkDefault false;
-  # Enable the OpenSSH daemon.
-  services.openssh = {
-    enable = true;
-    ports = config.modules.my-hosts.${hostName}.sshPorts;
-    settings = {
-      # root user is used for remote deployment.
-      PermitRootLogin = "prohibit-password";
-      PasswordAuthentication = false; # disable password login
-    };
-    openFirewall = true;
-    hostKeys = [
-      {
-        path = "/etc/ssh/ssh_host_ed25519_key";
-        type = "ed25519";
-      }
-    ];
-  };
 
   # Add terminfo database of all known terminals to the system profile.
   # https://github.com/NixOS/nixpkgs/blob/nixos-25.05/nixos/modules/config/terminfo.nix
secrets/cache/kevin/6683c1a321e7612c254025f8f8af7255958987598cdeee329c18bdb22d024fdc
@@ -0,0 +1,9 @@
+age-encryption.org/v1
+-> ssh-ed25519 WM7kiQ Xd7VhIeKlJVaibPwnekpkSih1ETjH2LL5xPtu04sgFE
+8s4rQJdhmjAK6U/IBVZwsQqZtFXpq45jeJ4WOzSQZnE
+-> c3U0Vw-grease
+KsNWbfv3ZTeo1jm41pJD9O/kjEviCUy45eRWGIM7giuOELNyfSOZrqZzzWp0bnM+
+/k/yHb5fN1YJz2vMm8SiJ9N69UDOCuWnUAY3vN9irgIiS+xaO0b8QbgkeycVAtM
+--- Y8fvYgB2JB6STPk8HjRbUTp1OGwHJjcN5IQef9Sc/4Q
+�b5�����z1���'-�Wdo(I�֖�F�
+��=�
:�A}�Gy
\ No newline at end of file
secrets/cache/pardofelis/6cdeb7890b647f109379f9b7da54b325e0e5307a5140a3f2f88605819a19270c
@@ -0,0 +1,7 @@
+age-encryption.org/v1
+-> ssh-ed25519 B1HLiw t0+2orBO8+PeQ7LeMBqjJ1yyokiU7SE1V/eTB35h5wM
+fe0XFl7bF+2ZjAGkwFP8aeR4A/vkXZqlQwuafRMRzFk
+-> AMIUn-grease
+yqTpphu6Z5SK5hT/d37+
+--- SLf/ut4XS19xYVw/gkON6AMyLX0bqtMpo/fzTrRTpFk
+�1߮zYm�1
��E�O=(Ug1fö��+}��}�'�T�v���
\ No newline at end of file
secrets/cache/pardofelis/9c321b43af5b1c8b263cc6b1fe831c24c43cad5bfd8b40edd9b515d39a20fc08
@@ -0,0 +1,8 @@
+age-encryption.org/v1
+-> ssh-ed25519 B1HLiw nFY7lwoxhCxdP4MgKo8iB35oQZQBrzLaAMeJClYfsFI
+vYFHDcjRAvH0SQaWOb94tS/MznYsVHpZSXhnQAJJbLU
+-> (M>ni9-grease xJYhtO xZ^qYCqZ
+OjOqkl6okORKF+yx6TPO9BtYfm+T
+--- 2k4QjiW1nM99y2Asp3/DHBos8G20P+LRRniKzU4HNhM
+@���?a�T�;8v#�0�^bP
+]�o7�������b�7���hp
\ No newline at end of file
secrets/cache/pardofelis/a79d6dff2f138ca16f4d47555ab3ac674f03a7e3eaafd94c3187e6dc9fc0fca8
Binary file
secrets/cache/pardofelis/e20e58b4d77c090ffcf1b127000982b16d71469b729532488ea2e914bc906d2c
@@ -0,0 +1,10 @@
+age-encryption.org/v1
+-> ssh-ed25519 B1HLiw KOhXXodQJmHMO/edAPYf/nOrkUNXSZJatJIwEkGLGwU
+dVSburRet4zCGah9qopvV5C+jklo2tdfHkXGpLKyW/M
+-> &n[^{-grease du3B =0o*Juw
+lcScFEGuO6G+60DH4cYnStqI5BtPlj8oBre3ezlC3+wYygD/j95Nq0VQV0YnnbaP
+
+--- 2EtL4YGYTPOL+NKICC3kcZWS9v7nST73KwVp3q5ZPYI
+�
+,����[�⤎�+�@���/Ag�����"9�#
݅�6����:3
+:���
\ No newline at end of file
vars/default.nix
@@ -3,12 +3,6 @@
   userfullname = "HPCesia";
   useremail = "me@hpcesia.com";
   defaultNameservers = [
-    # IPv4
-    "119.29.29.29" # DNSPod
-    "223.5.5.5" # AliDNS
-    # IPv6
-    "2400:3200::1" # Alidns
-    "2606:4700:4700::1111" # Cloudflare
   ];
   # generated by `mkpasswd -m scrypt`
   initialHashedPassword = "$7$CU..../....xQnray7Ah6GYybfmtsxmF.$k0F/eaOC2.9gXwXp0jgMrFM.fnMtFqYi3GZFaaJGsl3";