diff --git a/config/Dpi.nix b/config/Dpi.nix index 8f3f53d9..90105b41 100644 --- a/config/Dpi.nix +++ b/config/Dpi.nix @@ -5,45 +5,61 @@ pkgsMaster, ... }: let - cfg = config.module.dpi; + cfg = config.module.dpi.bypass; in { disabledModules = [ "services/networking/zapret.nix" ]; - imports = [ "${inputs.nixpkgsMaster}/nixos/modules/services/networking/zapret.nix" ]; + # imports = [ "${inputs.nixpkgsMaster}/nixos/modules/services/networking/zapret.nix" ]; - config = lib.mkIf cfg.bypass.enable { - services.zapret = { - inherit (cfg.bypass) params; - enable = true; - package = pkgsMaster.zapret; - httpMode = "full"; - httpSupport = true; - udpSupport = true; - udpPorts = [ - "50000:50099" - ]; - whitelist = [ - "youtube.com" - "googlevideo.com" - "ytimg.com" - "youtu.be" - "rutracker.org" - "rutracker.cc" - "rutrk.org" - "t-ru.org" - "medium.com" - "dis.gd" - "discord.co" - "discord.com" - "discord.dev" - "discord.gg" - "discord.gift" - "discord.media" - "discord.new" - "discordapp.com" - "discordapp.net" - "discordcdn.com" - "discordstatus.com" - ]; + config = lib.mkIf cfg.enable (lib.mkMerge [ + systemd.services.zapret = { + description = "DPI bypass service"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = { + ExecStart = "${cfg.package}/bin/nfqws --pidfile=/run/nfqws.pid ${params} ${whitelist} ${blacklist} --qnum=${qnum}"; + Type = "simple"; + PIDFile = "/run/nfqws.pid"; + Restart = "always"; + RuntimeMaxSec = "1h"; # This service loves to crash silently or cause network slowdowns. It also restarts instantly. Restarting it at least hourly provided the best experience. + + # Hardening. + DevicePolicy = "closed"; + KeyringMode = "private"; + PrivateTmp = true; + PrivateMounts = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = "strict"; + ProtectProc = "invisible"; + RemoveIPC = true; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + }; }; - }; + + # Route system traffic via service for specified ports. + (lib.mkIf cfg.configureFirewall { + networking.firewall.extraCommands = + let + httpParams = lib.optionalString ( + cfg.httpMode == "first" + ) "-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6"; + + udpPorts = lib.concatStringsSep "," cfg.udpPorts; + in + '' + iptables -t mangle -I POSTROUTING -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:6 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num ${qnum} --queue-bypass + '' + + lib.optionalString (cfg.httpSupport) '' + iptables -t mangle -I POSTROUTING -p tcp --dport 80 ${httpParams} -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num ${qnum} --queue-bypass + '' + + lib.optionalString (cfg.udpSupport) '' + iptables -t mangle -A POSTROUTING -p udp -m multiport --dports ${udpPorts} -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num ${qnum} --queue-bypass + ''; + }) + ];); } diff --git a/host/x86_64-linux/home/default.nix b/host/x86_64-linux/home/default.nix index 14403153..e7ee8e94 100644 --- a/host/x86_64-linux/home/default.nix +++ b/host/x86_64-linux/home/default.nix @@ -27,10 +27,21 @@ "--dpi-desync-ttl=1" "--dpi-desync-autottl=2" - "--dpi-desync-ttl6=1" - "--dpi-desync-autottl6=2" + # "--dpi-desync-ttl6=1" + # "--dpi-desync-autottl6=2" - "--dpi-desync-any-protocol" + # "--dpi-desync-any-protocol" + ]; + whitelist = [ + "youtube.com" + "googlevideo.com" + "ytimg.com" + "youtu.be" + "rutracker.org" + "rutracker.cc" + "rutrk.org" + "t-ru.org" + "medium.com" ]; }; amd = { diff --git a/option/Dpi.nix b/option/Dpi.nix index b0974dd7..d67edbfa 100644 --- a/option/Dpi.nix +++ b/option/Dpi.nix @@ -1,12 +1,49 @@ { lib, + pkgsMaster, ... }: { options.module.dpi.bypass = { - enable = lib.mkEnableOption "the DPI bypass."; + enable = lib.mkEnableOption "the Zapret DPI bypass service."; + package = lib.mkPackageOption pkgsMaster "zapret" { }; params = lib.mkOption { default = [ ]; - type = with lib.types; listOf str; + type = with lib.types; listOf str; + }; + whitelist = lib.mkOption { + default = [ ]; + type = with lib.types; listOf str; + }; + blacklist = lib.mkOption { + default = [ ]; + type = with lib.types; listOf str; + }; + qnum = lib.mkOption { + default = 200; + type = lib.types.int; + }; + configureFirewall = lib.mkOption { + default = true; + type = lib.types.bool; + }; + httpSupport = lib.mkOption { + default = true; + type = lib.types.bool; + }; + httpMode = lib.mkOption { + default = "first"; + type = lib.types.enum [ + "first" + "full" + ]; + }; + udpSupport = lib.mkOption { + default = false; + type = lib.types.bool; + }; + udpPorts = lib.mkOption { + default = [ ]; + type = with lib.types; listOf str; }; }; }