at 25.11-pre 5.3 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 cfg = config.services.dae; 10 assets = cfg.assets; 11 genAssetsDrv = 12 paths: 13 pkgs.symlinkJoin { 14 name = "dae-assets"; 15 inherit paths; 16 }; 17in 18{ 19 meta.maintainers = with lib.maintainers; [ 20 pokon548 21 oluceps 22 ]; 23 24 options = { 25 services.dae = with lib; { 26 enable = mkEnableOption "dae, a Linux high-performance transparent proxy solution based on eBPF"; 27 28 package = mkPackageOption pkgs "dae" { }; 29 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 }; 41 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 }; 56 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 }; 85 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 }; 94 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. 101 102 See <https://github.com/daeuniverse/dae/blob/main/example.dae>. 103 ''; 104 }; 105 106 disableTxChecksumIpGeneric = mkEnableOption "" // { 107 description = "See <https://github.com/daeuniverse/dae/issues/43>"; 108 }; 109 110 }; 111 }; 112 113 config = 114 lib.mkIf cfg.enable 115 116 { 117 environment.systemPackages = [ cfg.package ]; 118 systemd.packages = [ cfg.package ]; 119 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 }; 130 131 systemd.services.dae = 132 let 133 daeBin = lib.getExe cfg.package; 134 135 configPath = 136 if cfg.configFile != null then cfg.configFile else pkgs.writeText "config.dae" cfg.config; 137 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 }; 163 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 } 172 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 } 180 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 }; 189}