Merge #361424: refactor lib.packagesFromDirectoryRecursive (v2)
[NixPkgs.git] / nixos / modules / services / networking / dae.nix
blob328db5850dcc3cace3dc9adb8010ff05e1aed2d0
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
8 let
9   cfg = config.services.dae;
10   assets = cfg.assets;
11   genAssetsDrv =
12     paths:
13     pkgs.symlinkJoin {
14       name = "dae-assets";
15       inherit paths;
16     };
19   meta.maintainers = with lib.maintainers; [
20     pokon548
21     oluceps
22   ];
24   options = {
25     services.dae = with lib; {
26       enable = mkEnableOption "dae, a Linux high-performance transparent proxy solution based on eBPF";
28       package = mkPackageOption pkgs "dae" { };
30       assets = mkOption {
31         type = with types; (listOf path);
32         default = with pkgs; [
33           v2ray-geoip
34           v2ray-domain-list-community
35         ];
36         defaultText = literalExpression "with pkgs; [ v2ray-geoip v2ray-domain-list-community ]";
37         description = ''
38           Assets required to run dae.
39         '';
40       };
42       assetsPath = mkOption {
43         type = types.str;
44         default = "${genAssetsDrv assets}/share/v2ray";
45         defaultText = literalExpression ''
46           (symlinkJoin {
47               name = "dae-assets";
48               paths = assets;
49           })/share/v2ray
50         '';
51         description = ''
52           The path which contains geolocation database.
53           This option will override `assets`.
54         '';
55       };
57       openFirewall = mkOption {
58         type =
59           with types;
60           submodule {
61             options = {
62               enable = mkEnableOption "opening {option}`port` in the firewall";
63               port = mkOption {
64                 type = types.port;
65                 description = ''
66                   Port to be opened. Consist with field `tproxy_port` in config file.
67                 '';
68               };
69             };
70           };
71         default = {
72           enable = true;
73           port = 12345;
74         };
75         defaultText = literalExpression ''
76           {
77             enable = true;
78             port = 12345;
79           }
80         '';
81         description = ''
82           Open the firewall port.
83         '';
84       };
86       configFile = mkOption {
87         type = with types; (nullOr path);
88         default = null;
89         example = "/path/to/your/config.dae";
90         description = ''
91           The path of dae config file, end with `.dae`.
92         '';
93       };
95       config = mkOption {
96         type = with types; (nullOr str);
97         default = null;
98         description = ''
99           WARNING: This option will expose store your config unencrypted world-readable in the nix store.
100           Config text for dae.
102           See <https://github.com/daeuniverse/dae/blob/main/example.dae>.
103         '';
104       };
106       disableTxChecksumIpGeneric = mkEnableOption "" // {
107         description = "See <https://github.com/daeuniverse/dae/issues/43>";
108       };
110     };
111   };
113   config =
114     lib.mkIf cfg.enable
116       {
117         environment.systemPackages = [ cfg.package ];
118         systemd.packages = [ cfg.package ];
120         networking = lib.mkIf cfg.openFirewall.enable {
121           firewall =
122             let
123               portToOpen = cfg.openFirewall.port;
124             in
125             {
126               allowedTCPPorts = [ portToOpen ];
127               allowedUDPPorts = [ portToOpen ];
128             };
129         };
131         systemd.services.dae =
132           let
133             daeBin = lib.getExe cfg.package;
135             configPath =
136               if cfg.configFile != null then cfg.configFile else pkgs.writeText "config.dae" cfg.config;
138             TxChecksumIpGenericWorkaround =
139               with lib;
140               (getExe pkgs.writeShellApplication {
141                 name = "disable-tx-checksum-ip-generic";
142                 text = with pkgs; ''
143                   iface=$(${iproute2}/bin/ip route | ${lib.getExe gawk} '/default/ {print $5}')
144                   ${lib.getExe ethtool} -K "$iface" tx-checksum-ip-generic off
145                 '';
146               });
147           in
148           {
149             wantedBy = [ "multi-user.target" ];
150             serviceConfig = {
151               LoadCredential = [ "config.dae:${configPath}" ];
152               ExecStartPre = [
153                 ""
154                 "${daeBin} validate -c \${CREDENTIALS_DIRECTORY}/config.dae"
155               ] ++ (with lib; optional cfg.disableTxChecksumIpGeneric TxChecksumIpGenericWorkaround);
156               ExecStart = [
157                 ""
158                 "${daeBin} run --disable-timestamp -c \${CREDENTIALS_DIRECTORY}/config.dae"
159               ];
160               Environment = "DAE_LOCATION_ASSET=${cfg.assetsPath}";
161             };
162           };
164         assertions = [
165           {
166             assertion = lib.pathExists (toString (genAssetsDrv cfg.assets) + "/share/v2ray");
167             message = ''
168               Packages in `assets` has no preset paths included.
169               Please set `assetsPath` instead.
170             '';
171           }
173           {
174             assertion = !((config.services.dae.config != null) && (config.services.dae.configFile != null));
175             message = ''
176               Option `config` and `configFile` could not be set
177               at the same time.
178             '';
179           }
181           {
182             assertion = !((config.services.dae.config == null) && (config.services.dae.configFile == null));
183             message = ''
184               Either `config` or `configFile` should be set.
185             '';
186           }
187         ];
188       };