diff --git a/machines/dolomite/common.nix b/machines/dolomite/common.nix index c50c1a9..3840592 100644 --- a/machines/dolomite/common.nix +++ b/machines/dolomite/common.nix @@ -3,6 +3,7 @@ config = { sops = { age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; + defaultSopsFile = ./secrets/secrets.yaml; secrets = { wg_private_key = { owner = "root"; @@ -12,14 +13,6 @@ owner = "root"; sopsFile = ./secrets + "/${config.networking.hostName}.yaml"; }; - "sing-box/password" = { - owner = "root"; - sopsFile = ./secrets/secrets.yaml; - }; - "sing-box/uuid" = { - owner = "root"; - sopsFile = ./secrets/secrets.yaml; - }; }; }; swapDevices = [ @@ -32,6 +25,7 @@ custom.prometheus.exporters = { enable = true; node.enable = true; + blackbox.enable = true; }; custom.monitoring = { @@ -44,6 +38,11 @@ auth.enable = true; proxyServer = { enable = true; + users = [ + "wyj" + "yhb" + "xin" + ]; }; }; }; diff --git a/machines/dolomite/secrets/secrets.yaml b/machines/dolomite/secrets/secrets.yaml index 53a7131..e0df929 100644 --- a/machines/dolomite/secrets/secrets.yaml +++ b/machines/dolomite/secrets/secrets.yaml @@ -1,6 +1,14 @@ sing-box: - password: ENC[AES256_GCM,data:qCc1v8nAL0oYisRinMDXGrBQA+r6XNoa,iv:eTxtad4kEdE28XqnrZEek8BtXNY1rNgLvGLxlMzRtl4=,tag:s/shWAkYE4DSnScpTY8ulQ==,type:str] - uuid: ENC[AES256_GCM,data:lEpz15sLOVrGDzQwTJyS+tFJY0bMeO265bxocWAjB6qrvxYx,iv:lhk5jl/udUH3AZEuk5ffuvin/qhRUaOZ/3nk1Jaw+DI=,tag:4mKFIVKT+D47njfDsxe9iA==,type:str] + users: + wyj: + password: ENC[AES256_GCM,data:yp+T3eci9RiuZzdmRSq5nTjHaz8e/Rri,iv:hIPc+7YHUnaIdU9O8GGx3r7l3oBA6prQb+KBQV0G+8k=,tag:2GNiBP4PQy+KGHgLupKGSg==,type:str] + uuid: ENC[AES256_GCM,data:Qrgil6G7pjQAQzCCOlstDi27EqqmSuBMhs+RTl9++wrPrIgJ,iv:u+3Z17uX4I6li2qd9UP3y+WaKn7aKfbb3J6H1Pyc1QY=,tag:hSa4AB383/B58XMmZ8LIfQ==,type:str] + yhb: + password: ENC[AES256_GCM,data:TwRct68TePpcZcnpWIQpFaF23WGMre8=,iv:YU4mQNm0rt2u4ItJwQ8nZPEmJi0+lmEIPG2Kxh/nI58=,tag:ukZem38O/b42dEKM3CYa+w==,type:str] + uuid: ENC[AES256_GCM,data:6hVhEqWPLVrn8rCS4x/eapd+iL7JRaXtOGCj9uuPlkGjBTMK,iv:VZ27KWCY6/K5GoNwRNmaRWzqfV7+8iFjtias1vKeGfA=,tag:8mhmZPooxHaGNYdznuFhMQ==,type:str] + xin: + password: ENC[AES256_GCM,data:SRiPFO+Uwy/PT41SIg7eI68wk4AX6so=,iv:aXwP5wa1IrlnvFo/ZL+DYFFHDdWw2Z83de3ApHUTsXo=,tag:sxXoy1FnDxZBQCDeNxphzQ==,type:str] + uuid: ENC[AES256_GCM,data:7xK53SO4x0tOIEIYl6kmmAvnpdsR/tYQoG1t/ytsnO4QqWY3,iv:i694Fnu7g1OA3IGzSaoSGA5/eMPo+I/1TZbYuaQrgNA=,tag:4cUlioJn/IvsvZclgboOSA==,type:str] sops: kms: [] gcp_kms: [] @@ -43,8 +51,8 @@ sops: K1F1SzI2NFNIKzlreVBXSjAxaUxQd28KFaf1uu7OlqIe0TirJFgS3iPjhXPyfNDE m2XUjzdXp+chJCzVOFvpYStqz+e08ADEc+jp3YsTLcxyqvXhQdyL/Q== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-12-02T05:26:17Z" - mac: ENC[AES256_GCM,data:K94zFWPWGUisLCqDjSLs17QxHXPH4tPU/98Sb4lCnt7IRAIn14x/T+BnInY/DK+DOVLLtzSfuN0kgzzGjSzwJx5Vq1G3MkhngRQQRT9dvODTCMAw6lPt98Ofw1CEEsFQnpYo9zIUlCGKg2YPKFLqE7OjkPxqw7VYvgzr5dDw58s=,iv:3xcJfNX5v/e9HgZt3UrHs2/C5ivaBV1rXKIBs9hKKFg=,tag:RQPQQ1cmZiOpQjUwqnzZQA==,type:str] + lastmodified: "2024-12-06T04:35:52Z" + mac: ENC[AES256_GCM,data:DAg4UTwNv+rs6hye2z5UUtA1a4yZbFaAWjLoKAXf87tKgBCZzK8C1q6gLyTQOqp07ptYQd5Q951kfE1a/35SFJsubREzJmu6haxznRgq7pO5HDGqgtjYEHsngsWZh3bUSX/aG2dLISdD81VY68nLzTO0r4h/SL6DNG36RzJgL8E=,iv:V0WhENNt/Szi5VWVD2t5AsWP1tOZUGjFjMNYPDq59XI=,tag:ThRstdzVNtSs6E7qlvKPOw==,type:str] pgp: [] unencrypted_suffix: _unencrypted version: 3.9.1 diff --git a/modules/nixos/common-settings/proxy-server.nix b/modules/nixos/common-settings/proxy-server.nix index b54774a..f82f91f 100644 --- a/modules/nixos/common-settings/proxy-server.nix +++ b/modules/nixos/common-settings/proxy-server.nix @@ -21,106 +21,100 @@ let config.security.acme.certs.${config.deployment.targetHost}.directory + "/cert.pem"; }; - mkSingConfig = - { uuid, password, ... }: - { - log = { - level = "warn"; - }; - inbounds = - [ - { - tag = "sg0"; - type = "trojan"; - listen = "::"; - listen_port = cfg.trojan.port; - tcp_multi_path = true; - tcp_fast_open = true; - users = [ - { - name = "proxy"; - password = { - _secret = password; - }; - } - ]; - tls = singTls; - } - ] - ++ lib.forEach (lib.range 6311 6314) (port: { - tag = "sg" + toString (port - 6310); - type = "tuic"; + mkSingConfig = users: { + log = { + level = "warn"; + }; + inbounds = + [ + { + tag = "sg0"; + type = "trojan"; listen = "::"; - listen_port = port; - congestion_control = "bbr"; - users = [ + listen_port = cfg.trojan.port; + tcp_multi_path = true; + tcp_fast_open = true; + users = map (user: { + name = user.name; + password = { + _secret = user.passwordFile; + }; + }) users; + tls = singTls; + } + ] + ++ lib.forEach (lib.range 6311 6314) (port: { + tag = "sg" + toString (port - 6310); + type = "tuic"; + listen = "::"; + listen_port = port; + congestion_control = "bbr"; + users = map (user: { + name = user.name; + uuid = { + _secret = user.uuidFile; + }; + password = { + _secret = user.passwordFile; + }; + }) users; + tls = singTls; + }); + outbounds = + # warp outbound goes first to make it default outbound + (lib.optionals (cfg.warp.onTuic or cfg.warp.onTrojan) [ + { + type = "wireguard"; + tag = "wg-out"; + private_key = { + _secret = config.sops.secrets.wg_private_key.path; + }; + local_address = [ + "172.16.0.2/32" + { _secret = config.sops.secrets.wg_ipv6_local_addr.path; } + ]; + peers = [ { - name = "proxy"; - uuid = { - _secret = uuid; - }; - password = { - _secret = password; - }; + public_key = "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo="; + allowed_ips = [ + "0.0.0.0/0" + "::/0" + ]; + server = "162.159.192.1"; + server_port = 500; } ]; - tls = singTls; - }); - outbounds = - # warp outbound goes first to make it default outbound - (lib.optionals (cfg.warp.onTuic or cfg.warp.onTrojan) [ - { - type = "wireguard"; - tag = "wg-out"; - private_key = { - _secret = config.sops.secrets.wg_private_key.path; - }; - local_address = [ - "172.16.0.2/32" - { _secret = config.sops.secrets.wg_ipv6_local_addr.path; } - ]; - peers = [ - { - public_key = "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo="; - allowed_ips = [ - "0.0.0.0/0" - "::/0" - ]; - server = "162.159.192.1"; - server_port = 500; - } - ]; - } - ]) - ++ [ + } + ]) + ++ [ + { + type = "direct"; + tag = "direct"; + } + ]; + route = { + rules = + [ { - type = "direct"; - tag = "direct"; + inbound = "sg4"; + outbound = "direct"; } - ]; - route = { - rules = - [ - { - inbound = "sg4"; - outbound = "direct"; - } - ] - ++ (lib.optionals (!cfg.warp.onTuic) ( - lib.forEach (lib.range 1 3) (i: { - inbound = "sg${toString i}"; - outbound = "direct"; - }) - )) - ++ (lib.optionals (!cfg.warp.onTrojan) [ - { - inbound = "sg0"; - outbound = "direct"; - } - ]); - }; + ] + ++ (lib.optionals (!cfg.warp.onTuic) ( + lib.forEach (lib.range 1 3) (i: { + inbound = "sg${toString i}"; + outbound = "direct"; + }) + )) + ++ (lib.optionals (!cfg.warp.onTrojan) [ + { + inbound = "sg0"; + outbound = "direct"; + } + ]); }; + }; in { options.commonSettings.proxyServer = { @@ -137,40 +131,61 @@ in onTrojan = mkEnableOption "forward to warp in trojan"; onTuic = mkEnableOption "forward to warp in first two port of tuic"; }; - }; - config = mkIf cfg.enable { - boot.kernel.sysctl = { - "net.core.default_qdisc" = "fq"; - "net.ipv4.tcp_congestion_control" = "bbr"; - }; - - networking.firewall.trustedInterfaces = [ "tun0" ]; - - security.acme = { - acceptTerms = true; - certs.${config.deployment.targetHost} = { - email = "me@namely.icu"; - # Avoid port conflict - listenHTTP = if config.services.caddy.enable then ":30310" else ":80"; - }; - }; - services.caddy.virtualHosts."http://${config.deployment.targetHost}:80".extraConfig = '' - reverse_proxy 127.0.0.1:30310 - ''; - - networking.firewall.allowedTCPPorts = [ - 80 - cfg.trojan.port - ]; - networking.firewall.allowedUDPPorts = [ ] ++ (lib.range 6311 6314); - - services.sing-box = { - enable = true; - settings = mkSingConfig { - uuid = config.sops.secrets."sing-box/uuid".path; - password = config.sops.secrets."sing-box/password".path; - }; + users = mkOption { + type = lib.types.listOf lib.types.str; }; }; + + config = mkIf cfg.enable ( + { + boot.kernel.sysctl = { + "net.core.default_qdisc" = "fq"; + "net.ipv4.tcp_congestion_control" = "bbr"; + }; + + networking.firewall.trustedInterfaces = [ "tun0" ]; + + security.acme = { + acceptTerms = true; + certs.${config.deployment.targetHost} = { + email = "me@namely.icu"; + # Avoid port conflict + listenHTTP = if config.services.caddy.enable then ":30310" else ":80"; + }; + }; + services.caddy.virtualHosts."http://${config.deployment.targetHost}:80".extraConfig = '' + reverse_proxy 127.0.0.1:30310 + ''; + + networking.firewall.allowedTCPPorts = [ + 80 + cfg.trojan.port + ]; + networking.firewall.allowedUDPPorts = [ ] ++ (lib.range 6311 6314); + + services.sing-box = { + enable = true; + settings = ( + mkSingConfig ( + map (n: { + name = n; + uuidFile = config.sops.secrets."sing-box/users/${n}/uuid".path; + passwordFile = config.sops.secrets."sing-box/users/${n}/password".path; + }) cfg.users + ) + ); + }; + } + // { + sops.secrets = ( + builtins.foldl' (a: b: a // b) { } ( + map (u: { + "sing-box/users/${u}/uuid" = { }; + "sing-box/users/${u}/password" = { }; + }) cfg.users + ) + ); + } + ); }