From e3f1fd6c676f6473c4266a24739f364045de4f63 Mon Sep 17 00:00:00 2001
From: jz8132543 <i@dora.im>
Date: Tue, 5 Mar 2024 16:53:59 +0800
Subject: [PATCH] test: NAT

---
 home-manager/modules/tippy/ssh.nix            |  4 +-
 nixos/hosts/isk/default.nix                   | 27 +--------
 .../base/environment/domains/default.nix      | 10 ++++
 .../base/environment/isNAT/default.nix        | 59 +++++++++++++++----
 nixos/modules/base/network.nix                |  3 +-
 nixos/modules/base/tailscale.nix              |  5 +-
 nixos/modules/services/derp.nix               |  8 +--
 nixos/modules/services/headscale.nix          |  2 +-
 nixos/modules/services/hydra.nix              |  2 +-
 nixos/modules/services/traefik.nix            | 18 ++++--
 10 files changed, 87 insertions(+), 51 deletions(-)
 create mode 100644 nixos/modules/base/environment/domains/default.nix

diff --git a/home-manager/modules/tippy/ssh.nix b/home-manager/modules/tippy/ssh.nix
index af156991..2a719547 100644
--- a/home-manager/modules/tippy/ssh.nix
+++ b/home-manager/modules/tippy/ssh.nix
@@ -19,7 +19,7 @@ with lib.strings; {
         "StrictHostKeyChecking" = "no";
         "LogLevel" = "ERROR";
         "CanonicalizeHostname" = "yes";
-        "CanonicalDomains" = concatStringsSep " " ([osConfig.networking.domain] ++ osConfig.networking.search);
+        "CanonicalDomains" = concatStringsSep " " ([osConfig.networking.domain] ++ osConfig.environment.domains);
         "CanonicalizeMaxDots" = "0";
         # fix kde connection for android
         "HostKeyAlgorithms " = "+ssh-rsa";
@@ -42,7 +42,7 @@ with lib.strings; {
           forwardX11 = true;
         };
         "canonical" = {
-          match = concatStrings ["canonical final Host " (concatMapStringsSep "," (x: concatStrings ["*." x]) ([osConfig.networking.domain] ++ osConfig.networking.search))];
+          match = concatStrings ["canonical final Host " (concatMapStringsSep "," (x: concatStrings ["*." x]) ([osConfig.networking.domain] ++ osConfig.environment.domains))];
           port = osConfig.ports.ssh;
         };
       };
diff --git a/nixos/hosts/isk/default.nix b/nixos/hosts/isk/default.nix
index 22e27d47..4801aeea 100644
--- a/nixos/hosts/isk/default.nix
+++ b/nixos/hosts/isk/default.nix
@@ -17,32 +17,9 @@
     ];
   services.qemuGuest.enable = true;
 
-  # environment.isNAT = true;
+  environment.isNAT = true;
   environment.isCN = true;
 
   ports.derp-stun = lib.mkForce 3440;
-  services.traefik.staticConfigOptions.entryPoints.https.address = lib.mkForce ":8443";
-  networking.firewall = {
-    enable = lib.mkForce false;
-    # extraCommands = ''
-    #   iptables -t nat -A PREROUTING -p tcp --dport 8443 -j REDIRECT --to-port 443
-    #   iptables -t nat -A PREROUTING -p udp --dport 8443 -j REDIRECT --to-port 443
-    #   iptables -t nat -A OUTPUT -p tcp --dport 8443 -j REDIRECT --to-port 443
-    #   iptables -t nat -A OUTPUT -p udp --dport 8443 -j REDIRECT --to-port 443
-    # '';
-    allowedUDPPortRanges = [
-      {
-        from = 0;
-        to = 65535;
-      }
-    ];
-    allowedTCPPortRanges = [
-      {
-        from = 0;
-        to = 65535;
-      }
-    ];
-    allowedTCPPorts = [8443];
-    allowedUDPPorts = [8443];
-  };
+  # services.traefik.staticConfigOptions.entryPoints.https.address = lib.mkForce ":8443";
 }
diff --git a/nixos/modules/base/environment/domains/default.nix b/nixos/modules/base/environment/domains/default.nix
new file mode 100644
index 00000000..62a127ae
--- /dev/null
+++ b/nixos/modules/base/environment/domains/default.nix
@@ -0,0 +1,10 @@
+{lib, ...}:
+with lib; {
+  options.environment.domains = lib.mkOption {
+    type = types.listOf types.str;
+    default = ["ts.dora.im" "users.dora.im"];
+    description = ''
+      tailscale search domains.
+    '';
+  };
+}
diff --git a/nixos/modules/base/environment/isNAT/default.nix b/nixos/modules/base/environment/isNAT/default.nix
index 66cc36f1..59b2e42f 100644
--- a/nixos/modules/base/environment/isNAT/default.nix
+++ b/nixos/modules/base/environment/isNAT/default.nix
@@ -1,10 +1,49 @@
-{lib, ...}:
-with lib; {
-  options.environment.isNAT = lib.mkOption {
-    type = types.bool;
-    default = false;
-    description = ''
-      Whether to enable NAT mode.
-    '';
-  };
-}
+{
+  lib,
+  config,
+  ...
+}: let
+  cfg = config.services.traefik.dynamicConfigOptions.http.routers;
+in
+  with lib; {
+    options.environment = {
+      isNAT = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable NAT mode.
+        '';
+      };
+      AltHTTPS = mkOption {
+        type = types.int;
+        default = 8443;
+        description = ''
+          The port of https alt
+        '';
+      };
+      AltHTTP = mkOption {
+        type = types.int;
+        default = 8080;
+        description = ''
+          The port of http alt
+        '';
+      };
+    };
+    # Traefik
+    options = {
+      services.traefik.dynamicConfigOptions.http.routers = mkOption {
+        type = types.attrsOf types.submodule {
+          options.entryPoints = mkOption {
+            type = types.listOf types.str;
+            default = ["https-alt"];
+          };
+        };
+      };
+      # lib.concatMapAttrs (name: _: {
+      #   ${name}.entryPoints = ["https" "https-alt"];
+      # })
+      # // config.services.traefik.dynamicConfigOptions.http.routers;
+      networking.firewall.allowedTCPPorts = with config.environment; [AltHTTPS AltHTTP];
+      networking.firewall.allowedUDPPorts = with config.environment; [AltHTTPS];
+    };
+  }
diff --git a/nixos/modules/base/network.nix b/nixos/modules/base/network.nix
index 400a0c50..c29d8438 100644
--- a/nixos/modules/base/network.nix
+++ b/nixos/modules/base/network.nix
@@ -4,7 +4,8 @@
     firewall.enable = true;
     nameservers = lib.mkDefault ["1.1.1.1" "1.0.0.1"];
     domain = "dora.im";
-    search = ["ts.dora.im" "users.dora.im"];
+    search = ["dora.im"];
+    # search = ["ts.dora.im" "users.dora.im"];
     dhcpcd.extraConfig = "nohook resolv.conf";
     networkmanager.dns = lib.mkDefault "none";
   };
diff --git a/nixos/modules/base/tailscale.nix b/nixos/modules/base/tailscale.nix
index dd1aac37..571a561a 100644
--- a/nixos/modules/base/tailscale.nix
+++ b/nixos/modules/base/tailscale.nix
@@ -1,7 +1,6 @@
 {
   config,
   pkgs,
-  lib,
   ...
 }: let
   interfaceName = "tailscale0";
@@ -9,12 +8,12 @@ in {
   services.tailscale = {
     enable = true;
     openFirewall = true;
-    # useRoutingFeatures = "both";
+    useRoutingFeatures = "both";
   };
   networking = {
     networkmanager.unmanaged = [interfaceName];
     firewall = {
-      checkReversePath = false;
+      # checkReversePath = false;
       trustedInterfaces = ["tailscale0"];
       allowedUDPPorts = [
         config.services.tailscale.port
diff --git a/nixos/modules/services/derp.nix b/nixos/modules/services/derp.nix
index ae7d893b..b94b041d 100644
--- a/nixos/modules/services/derp.nix
+++ b/nixos/modules/services/derp.nix
@@ -10,10 +10,10 @@
     serviceConfig = {
       Restart = "always";
       DynamicUser = true;
-      ExecStart =
-        if !config.environment.isNAT
-        then "${pkgs.tailscale}/bin/derper -a ':${toString config.ports.derp}' -stun-port ${toString config.ports.derp-stun} --hostname='${config.networking.fqdn}' -c /tmp/derper.conf -verify-clients -dev"
-        else "${pkgs.tailscale}/bin/derper -a ':${toString config.ports.derp}' -stun-port ${toString config.ports.derp-stun} -http-port='-1' --hostname='${config.networking.fqdn}' -c /tmp/derper.conf -certdir '$CREDENTIALS_DIRECTORY' -certmode manual -verify-clients -dev";
+      ExecStart = "${pkgs.tailscale}/bin/derper -a ':${toString config.ports.derp}' -stun-port ${toString config.ports.derp-stun} --hostname='${config.networking.fqdn}' -c /tmp/derper.conf -verify-clients -dev";
+      # if !config.environment.isNAT
+      # then "${pkgs.tailscale}/bin/derper -a ':${toString config.ports.derp}' -stun-port ${toString config.ports.derp-stun} --hostname='${config.networking.fqdn}' -c /tmp/derper.conf -verify-clients -dev"
+      # else "${pkgs.tailscale}/bin/derper -a ':${toString config.ports.derp}' -stun-port ${toString config.ports.derp-stun} -http-port='-1' --hostname='${config.networking.fqdn}' -c /tmp/derper.conf -certdir '$CREDENTIALS_DIRECTORY' -certmode manual -verify-clients -dev";
       LoadCredential = [
         "${config.networking.fqdn}.crt:${config.security.acme.certs."main".directory}/full.pem"
         "${config.networking.fqdn}.key:${config.security.acme.certs."main".directory}/key.pem"
diff --git a/nixos/modules/services/headscale.nix b/nixos/modules/services/headscale.nix
index 335a72ab..c23cb5ea 100644
--- a/nixos/modules/services/headscale.nix
+++ b/nixos/modules/services/headscale.nix
@@ -16,7 +16,7 @@
           override_local_dns = true;
           base_domain = "dora.im";
           magic_dns = true;
-          domains = config.networking.search;
+          domains = config.environment.domains;
           nameservers = [
             "1.1.1.1"
             "9.9.9.9"
diff --git a/nixos/modules/services/hydra.nix b/nixos/modules/services/hydra.nix
index 293fdf83..a02eb878 100644
--- a/nixos/modules/services/hydra.nix
+++ b/nixos/modules/services/hydra.nix
@@ -145,7 +145,7 @@ in {
           CanonicalizeHostname yes
           LogLevel ERROR
           StrictHostKeyChecking no
-          Match canonical final Host ${concatMapStringsSep "," (x: concatStrings ["*." x]) osConfig.networking.search}
+          Match canonical final Host ${concatMapStringsSep "," (x: concatStrings ["*." x]) osConfig.environment.domains}
             Port 1022
             HashKnownHosts no
             UserKnownHostsFile /dev/null
diff --git a/nixos/modules/services/traefik.nix b/nixos/modules/services/traefik.nix
index 777f0721..67e2fd84 100644
--- a/nixos/modules/services/traefik.nix
+++ b/nixos/modules/services/traefik.nix
@@ -26,10 +26,20 @@
           address = ":443";
           forwardedHeaders.insecure = true;
           proxyProtocol.insecure = true;
-          http.tls =
-            if config.environment.isNAT
-            then true
-            else {certResolver = "zerossl";};
+          http.tls = "zerossl";
+          # if config.environment.isNAT
+          # then true
+          # else {certResolver = "zerossl";};
+          http3 = {};
+        };
+        https-alt = {
+          address = ":${toString config.environment.altHTTPS}";
+          forwardedHeaders.insecure = true;
+          proxyProtocol.insecure = true;
+          http.tls = "zerossl";
+          # if config.environment.isNAT
+          # then true
+          # else {certResolver = "zerossl";};
           http3 = {};
         };
       };