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