{ config, lib, pkgs, ... }: let cfg = config.local.services.byedpi; exe = lib.getExe cfg.package; cliArgs = lib.cli.toGNUCommandLineShell { } { inherit (cfg.settings) ip port; inherit (cfg.settings) ttl split disorder oob disoob fake tlsrec md5sig; buf-size = cfg.settings.bufferSize; debug = cfg.settings.debugLevel; max-conn = cfg.settings.connectionLimit; tfo = cfg.settings.tcpFastOpen.enable; no-udp = !cfg.settings.udp.enable; no-domain = !cfg.settings.domain.enable; }; strOrNum = with lib.types; either str number; splitType = with lib.types; nullOr (either strOrNum (listOf strOrNum)); mkSplitOption = description: lib.mkOption { inherit description; type = splitType; default = null; }; in { options.local.services.byedpi = with lib; { enable = mkEnableOption "byedpi"; package = mkPackageOption pkgs "byedpi" { }; openFirewall = mkEnableOption "Whether to open the required firewall ports in the firewall."; settings = { ip = mkOption { type = types.str; description = "Listening IP"; default = "0.0.0.0"; }; port = mkOption { type = types.number; description = "Listening port"; default = 1080; }; bufferSize = mkOption { type = types.number; description = "Buffer size"; default = 16384; }; debugLevel = mkOption { type = types.number; # 0, 1, 2 default = 0; }; connectionLimit = mkOption { type = types.number; description = "Connection count limit"; default = 512; }; domain.enable = mkEnableOption "Enable domain resolving" // { default = true; }; udp.enable = mkEnableOption "Enable UDP association" // { default = true; }; tcpFastOpen.enable = mkEnableOption "Enable TCP Fast Open"; ttl = mkOption { type = types.number; default = 8; }; split = mkSplitOption "Split packet at n"; disorder = mkSplitOption "Split and send reverse order"; oob = mkSplitOption "Split and send as OOB data"; disoob = mkSplitOption "Split and send reverse order as OOB data"; fake = mkSplitOption "Split and send fake packet"; tlsrec = mkSplitOption "Make TLS record at position"; md5sig = mkEnableOption "Add MD5 Signature option for fake packets"; }; }; config = lib.mkIf cfg.enable { users.groups.byedpi = { }; users.users.byedpi = { isSystemUser = true; group = "byedpi"; }; networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.settings.port ]; systemd.services.byedpi = { description = "Byedpi (Bypass DPI)"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; path = [ cfg.package ]; serviceConfig = { Type = "simple"; User = "byedpi"; Group = "byedpi"; ExecStart = "${exe} ${cliArgs}"; }; }; }; }