at 24.11-pre 4.8 kB view raw
1{ config, lib, pkgs, ... }: 2let 3 4 cfg = config.programs.proxychains; 5 6 configFile = '' 7 ${cfg.chain.type}_chain 8 ${lib.optionalString (cfg.chain.type == "random") 9 "chain_len = ${builtins.toString cfg.chain.length}"} 10 ${lib.optionalString cfg.proxyDNS "proxy_dns"} 11 ${lib.optionalString cfg.quietMode "quiet_mode"} 12 remote_dns_subnet ${builtins.toString cfg.remoteDNSSubnet} 13 tcp_read_time_out ${builtins.toString cfg.tcpReadTimeOut} 14 tcp_connect_time_out ${builtins.toString cfg.tcpConnectTimeOut} 15 localnet ${cfg.localnet} 16 [ProxyList] 17 ${builtins.concatStringsSep "\n" 18 (lib.mapAttrsToList (k: v: "${v.type} ${v.host} ${builtins.toString v.port}") 19 (lib.filterAttrs (k: v: v.enable) cfg.proxies))} 20 ''; 21 22 proxyOptions = { 23 options = { 24 enable = lib.mkEnableOption "this proxy"; 25 26 type = lib.mkOption { 27 type = lib.types.enum [ "http" "socks4" "socks5" ]; 28 description = "Proxy type."; 29 }; 30 31 host = lib.mkOption { 32 type = lib.types.str; 33 description = "Proxy host or IP address."; 34 }; 35 36 port = lib.mkOption { 37 type = lib.types.port; 38 description = "Proxy port"; 39 }; 40 }; 41 }; 42 43in { 44 45 ###### interface 46 47 options = { 48 49 programs.proxychains = { 50 51 enable = lib.mkEnableOption "proxychains configuration"; 52 53 package = lib.mkPackageOption pkgs "proxychains" { 54 example = "proxychains-ng"; 55 }; 56 57 chain = { 58 type = lib.mkOption { 59 type = lib.types.enum [ "dynamic" "strict" "random" ]; 60 default = "strict"; 61 description = '' 62 `dynamic` - Each connection will be done via chained proxies 63 all proxies chained in the order as they appear in the list 64 at least one proxy must be online to play in chain 65 (dead proxies are skipped) 66 otherwise `EINTR` is returned to the app. 67 68 `strict` - Each connection will be done via chained proxies 69 all proxies chained in the order as they appear in the list 70 all proxies must be online to play in chain 71 otherwise `EINTR` is returned to the app. 72 73 `random` - Each connection will be done via random proxy 74 (or proxy chain, see {option}`programs.proxychains.chain.length`) from the list. 75 ''; 76 }; 77 length = lib.mkOption { 78 type = lib.types.nullOr lib.types.int; 79 default = null; 80 description = '' 81 Chain length for random chain. 82 ''; 83 }; 84 }; 85 86 proxyDNS = lib.mkOption { 87 type = lib.types.bool; 88 default = true; 89 description = "Proxy DNS requests - no leak for DNS data."; 90 }; 91 92 quietMode = lib.mkEnableOption "Quiet mode (no output from the library)"; 93 94 remoteDNSSubnet = lib.mkOption { 95 type = lib.types.enum [ 10 127 224 ]; 96 default = 224; 97 description = '' 98 Set the class A subnet number to use for the internal remote DNS mapping, uses the reserved 224.x.x.x range by default. 99 ''; 100 }; 101 102 tcpReadTimeOut = lib.mkOption { 103 type = lib.types.int; 104 default = 15000; 105 description = "Connection read time-out in milliseconds."; 106 }; 107 108 tcpConnectTimeOut = lib.mkOption { 109 type = lib.types.int; 110 default = 8000; 111 description = "Connection time-out in milliseconds."; 112 }; 113 114 localnet = lib.mkOption { 115 type = lib.types.str; 116 default = "127.0.0.0/255.0.0.0"; 117 description = "By default enable localnet for loopback address ranges."; 118 }; 119 120 proxies = lib.mkOption { 121 type = lib.types.attrsOf (lib.types.submodule proxyOptions); 122 description = '' 123 Proxies to be used by proxychains. 124 ''; 125 126 example = lib.literalExpression '' 127 { myproxy = 128 { type = "socks4"; 129 host = "127.0.0.1"; 130 port = 1337; 131 }; 132 } 133 ''; 134 }; 135 136 }; 137 138 }; 139 140 ###### implementation 141 142 meta.maintainers = with lib.maintainers; [ sorki ]; 143 144 config = lib.mkIf cfg.enable { 145 146 assertions = lib.singleton { 147 assertion = cfg.chain.type != "random" && cfg.chain.length == null; 148 message = '' 149 Option `programs.proxychains.chain.length` 150 only makes sense with `programs.proxychains.chain.type` = "random". 151 ''; 152 }; 153 154 programs.proxychains.proxies = lib.mkIf config.services.tor.client.enable 155 { 156 torproxy = lib.mkDefault { 157 enable = true; 158 type = "socks4"; 159 host = "127.0.0.1"; 160 port = 9050; 161 }; 162 }; 163 164 environment.etc."proxychains.conf".text = configFile; 165 environment.systemPackages = [ cfg.package ]; 166 }; 167 168}