diff --git a/nixos/modules/services/networking/dae.nix b/nixos/modules/services/networking/dae.nix index 231c555b33030..42ed3c7f8d4aa 100644 --- a/nixos/modules/services/networking/dae.nix +++ b/nixos/modules/services/networking/dae.nix @@ -1,41 +1,161 @@ -{ config, pkgs, lib, ... }: +{ config, lib, pkgs, ... }: + let cfg = config.services.dae; + assets = cfg.assets; + genAssetsDrv = paths: pkgs.symlinkJoin { + name = "dae-assets"; + inherit paths; + }; in { - meta.maintainers = with lib.maintainers; [ pokon548 ]; + meta.maintainers = with lib.maintainers; [ pokon548 oluceps ]; options = { - services.dae = { - enable = lib.options.mkEnableOption (lib.mdDoc "the dae service"); - package = lib.mkPackageOptionMD pkgs "dae" { }; + services.dae = with lib;{ + enable = mkEnableOption + (mdDoc "A Linux high-performance transparent proxy solution based on eBPF"); + + package = mkPackageOptionMD pkgs "dae" { }; + + assets = mkOption { + type = with types;(listOf path); + default = with pkgs; [ v2ray-geoip v2ray-domain-list-community ]; + defaultText = literalExpression "with pkgs; [ v2ray-geoip v2ray-domain-list-community ]"; + description = mdDoc '' + Assets required to run dae. + ''; + }; + + assetsPath = mkOption { + type = types.str; + default = "${genAssetsDrv assets}/share/v2ray"; + defaultText = literalExpression '' + (symlinkJoin { + name = "dae-assets"; + paths = assets; + })/share/v2ray + ''; + description = mdDoc '' + The path which contains geolocation database. + This option will override `assets`. + ''; + }; + + openFirewall = mkOption { + type = with types; submodule { + options = { + enable = mkEnableOption "enable"; + port = mkOption { + type = types.int; + description = '' + Port to be opened. Consist with field `tproxy_port` in config file. + ''; + }; + }; + }; + default = { + enable = true; + port = 12345; + }; + defaultText = literalExpression '' + { + enable = true; + port = 12345; + } + ''; + description = mdDoc '' + Open the firewall port. + ''; + }; + + configFile = mkOption { + type = types.path; + default = "/etc/dae/config.dae"; + example = "/path/to/your/config.dae"; + description = mdDoc '' + The path of dae config file, end with `.dae`. + ''; + }; + + config = mkOption { + type = types.str; + default = '' + global{} + routing{} + ''; + description = mdDoc '' + Config text for dae. + + See . + ''; + }; + + disableTxChecksumIpGeneric = + mkEnableOption (mdDoc "See "); + }; }; - config = lib.mkIf config.services.dae.enable { - networking.firewall.allowedTCPPorts = [ 12345 ]; - networking.firewall.allowedUDPPorts = [ 12345 ]; + config = lib.mkIf cfg.enable + + { + environment.systemPackages = [ cfg.package ]; + systemd.packages = [ cfg.package ]; - systemd.services.dae = { - unitConfig = { - Description = "dae Service"; - Documentation = "https://github.com/daeuniverse/dae"; - After = [ "network-online.target" "systemd-sysctl.service" ]; - Wants = [ "network-online.target" ]; + environment.etc."dae/config.dae" = { + mode = "0400"; + source = pkgs.writeText "config.dae" cfg.config; }; - serviceConfig = { - User = "root"; - ExecStartPre = "${lib.getExe cfg.package} validate -c /etc/dae/config.dae"; - ExecStart = "${lib.getExe cfg.package} run --disable-timestamp -c /etc/dae/config.dae"; - ExecReload = "${lib.getExe cfg.package} reload $MAINPID"; - LimitNPROC = 512; - LimitNOFILE = 1048576; - Restart = "on-abnormal"; - Type = "notify"; + networking = lib.mkIf cfg.openFirewall.enable { + firewall = + let portToOpen = cfg.openFirewall.port; + in + { + allowedTCPPorts = [ portToOpen ]; + allowedUDPPorts = [ portToOpen ]; + }; }; - wantedBy = [ "multi-user.target" ]; + systemd.services.dae = + let + daeBin = lib.getExe cfg.package; + TxChecksumIpGenericWorkaround = with lib;(getExe pkgs.writeShellApplication { + name = "disable-tx-checksum-ip-generic"; + text = with pkgs; '' + iface=$(${iproute2}/bin/ip route | ${lib.getExe gawk} '/default/ {print $5}') + ${lib.getExe ethtool} -K "$iface" tx-checksum-ip-generic off + ''; + }); + in + { + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStartPre = [ "" "${daeBin} validate -c ${cfg.configFile}" ] + ++ (with lib; optional cfg.disableTxChecksumIpGeneric TxChecksumIpGenericWorkaround); + ExecStart = [ "" "${daeBin} run --disable-timestamp -c ${cfg.configFile}" ]; + Environment = "DAE_LOCATION_ASSET=${cfg.assetsPath}"; + }; + }; + + assertions = [ + { + assertion = lib.pathExists (toString (genAssetsDrv cfg.assets) + "/share/v2ray"); + message = '' + Packages in `assets` has no preset paths included. + Please set `assetsPath` instead. + ''; + } + + { + assertion = !((config.services.dae.config != "global{}\nrouting{}\n") + && (config.services.dae.configFile != "/etc/dae/config.dae")); + message = '' + Option `config` and `configFile` could not be set + at the same time. + ''; + } + ]; }; - }; } diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index c1e124bda5c7a..40fdf0b9df8bf 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -210,6 +210,7 @@ in { custom-ca = handleTest ./custom-ca.nix {}; croc = handleTest ./croc.nix {}; darling = handleTest ./darling.nix {}; + dae = handleTest ./dae.nix {}; dconf = handleTest ./dconf.nix {}; deepin = handleTest ./deepin.nix {}; deluge = handleTest ./deluge.nix {}; diff --git a/nixos/tests/dae.nix b/nixos/tests/dae.nix new file mode 100644 index 0000000000000..b8c8ebce74574 --- /dev/null +++ b/nixos/tests/dae.nix @@ -0,0 +1,29 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: { + + name = "dae"; + + meta = { + maintainers = with lib.maintainers; [ oluceps ]; + }; + + nodes.machine = { pkgs, ... }: { + environment.systemPackages = [ pkgs.curl ]; + services.nginx = { + enable = true; + statusPage = true; + }; + services.dae = { + enable = true; + }; + }; + + testScript = '' + machine.wait_for_unit("nginx.service") + machine.wait_for_unit("dae.service") + + machine.wait_for_open_port(80) + + machine.succeed("curl --fail --max-time 10 http://localhost") + ''; + +}) diff --git a/pkgs/tools/networking/dae/default.nix b/pkgs/tools/networking/dae/default.nix index 666340d1fbe2f..cc95bb4dc826b 100644 --- a/pkgs/tools/networking/dae/default.nix +++ b/pkgs/tools/networking/dae/default.nix @@ -1,29 +1,25 @@ { lib , clang , fetchFromGitHub -, symlinkJoin , buildGoModule -, makeWrapper -, v2ray-geoip -, v2ray-domain-list-community }: buildGoModule rec { pname = "dae"; - version = "0.2.4"; + version = "0.3.0"; src = fetchFromGitHub { owner = "daeuniverse"; repo = "dae"; rev = "v${version}"; - hash = "sha256-MVmx37q5nbgaUehPJ2C2UjVyx48/U/vA3NeBx6Zcmg8="; + hash = "sha256-WiJqhXYehuUCLEuVbsQkmTntuH1srtePtZgYBSTbxiw="; fetchSubmodules = true; }; - vendorHash = "sha256-oeMAekLWRJzmkmge4LmrVSFRzHZ/dStX+CvLtuYOsog="; + vendorHash = "sha256-fb4PEMhV8+5zaRJyl+nYi2BHcOUDUVAwxce2xaRt5JA="; proxyVendor = true; - nativeBuildInputs = [ clang makeWrapper ]; + nativeBuildInputs = [ clang ]; ldflags = [ "-s" @@ -33,7 +29,7 @@ buildGoModule rec { ]; preBuild = '' - make CFLAGS="-D__REMOVE_BPF_PRINTK -fno-stack-protector" \ + make CFLAGS="-D__REMOVE_BPF_PRINTK -fno-stack-protector -Wno-unused-command-line-argument" \ NOSTRIP=y \ ebpf ''; @@ -41,15 +37,8 @@ buildGoModule rec { # network required doCheck = false; - assetsDrv = symlinkJoin { - name = "dae-assets"; - paths = [ v2ray-geoip v2ray-domain-list-community ]; - }; - postInstall = '' install -Dm444 install/dae.service $out/lib/systemd/system/dae.service - wrapProgram $out/bin/dae \ - --suffix DAE_LOCATION_ASSET : $assetsDrv/share/v2ray substituteInPlace $out/lib/systemd/system/dae.service \ --replace /usr/bin/dae $out/bin/dae '';