at master 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 ] 156 ++ (with lib; optional cfg.disableTxChecksumIpGeneric TxChecksumIpGenericWorkaround); 157 ExecStart = [ 158 "" 159 "${daeBin} run --disable-timestamp -c \${CREDENTIALS_DIRECTORY}/config.dae" 160 ]; 161 Environment = "DAE_LOCATION_ASSET=${cfg.assetsPath}"; 162 }; 163 }; 164 165 assertions = [ 166 { 167 assertion = lib.pathExists (toString (genAssetsDrv cfg.assets) + "/share/v2ray"); 168 message = '' 169 Packages in `assets` has no preset paths included. 170 Please set `assetsPath` instead. 171 ''; 172 } 173 174 { 175 assertion = !((config.services.dae.config != null) && (config.services.dae.configFile != null)); 176 message = '' 177 Option `config` and `configFile` could not be set 178 at the same time. 179 ''; 180 } 181 182 { 183 assertion = !((config.services.dae.config == null) && (config.services.dae.configFile == null)); 184 message = '' 185 Either `config` or `configFile` should be set. 186 ''; 187 } 188 ]; 189 }; 190}