parent
51428e8d38
commit
ebd199184d
@ -0,0 +1,165 @@ |
||||
{ config, lib, pkgs, ... }: |
||||
with lib; |
||||
let |
||||
|
||||
cfg = config.programs.proxychains; |
||||
|
||||
configFile = '' |
||||
${cfg.chain.type}_chain |
||||
${optionalString (cfg.chain.type == "random") |
||||
"chain_len = ${builtins.toString cfg.chain.length}"} |
||||
${optionalString cfg.proxyDNS "proxy_dns"} |
||||
${optionalString cfg.quietMode "quiet_mode"} |
||||
remote_dns_subnet ${builtins.toString cfg.remoteDNSSubnet} |
||||
tcp_read_time_out ${builtins.toString cfg.tcpReadTimeOut} |
||||
tcp_connect_time_out ${builtins.toString cfg.tcpConnectTimeOut} |
||||
localnet ${cfg.localnet} |
||||
[ProxyList] |
||||
${builtins.concatStringsSep "\n" |
||||
(lib.mapAttrsToList (k: v: "${v.type} ${v.host} ${builtins.toString v.port}") |
||||
(lib.filterAttrs (k: v: v.enable) cfg.proxies))} |
||||
''; |
||||
|
||||
proxyOptions = { |
||||
options = { |
||||
enable = mkEnableOption "this proxy"; |
||||
|
||||
type = mkOption { |
||||
type = types.enum [ "http" "socks4" "socks5" ]; |
||||
description = "Proxy type."; |
||||
}; |
||||
|
||||
host = mkOption { |
||||
type = types.str; |
||||
description = "Proxy host or IP address."; |
||||
}; |
||||
|
||||
port = mkOption { |
||||
type = types.port; |
||||
description = "Proxy port"; |
||||
}; |
||||
}; |
||||
}; |
||||
|
||||
in { |
||||
|
||||
###### interface |
||||
|
||||
options = { |
||||
|
||||
programs.proxychains = { |
||||
|
||||
enable = mkEnableOption "installing proxychains configuration"; |
||||
|
||||
chain = { |
||||
type = mkOption { |
||||
type = types.enum [ "dynamic" "strict" "random" ]; |
||||
default = "strict"; |
||||
description = '' |
||||
<literal>dynamic</literal> - Each connection will be done via chained proxies |
||||
all proxies chained in the order as they appear in the list |
||||
at least one proxy must be online to play in chain |
||||
(dead proxies are skipped) |
||||
otherwise <literal>EINTR</literal> is returned to the app. |
||||
|
||||
<literal>strict</literal> - Each connection will be done via chained proxies |
||||
all proxies chained in the order as they appear in the list |
||||
all proxies must be online to play in chain |
||||
otherwise <literal>EINTR</literal> is returned to the app. |
||||
|
||||
<literal>random</literal> - Each connection will be done via random proxy |
||||
(or proxy chain, see <option>programs.proxychains.chain.length</option>) from the list. |
||||
''; |
||||
}; |
||||
length = mkOption { |
||||
type = types.nullOr types.int; |
||||
default = null; |
||||
description = '' |
||||
Chain length for random chain. |
||||
''; |
||||
}; |
||||
}; |
||||
|
||||
proxyDNS = mkOption { |
||||
type = types.bool; |
||||
default = true; |
||||
description = "Proxy DNS requests - no leak for DNS data."; |
||||
}; |
||||
|
||||
quietMode = mkEnableOption "Quiet mode (no output from the library)."; |
||||
|
||||
remoteDNSSubnet = mkOption { |
||||
type = types.enum [ 10 127 224 ]; |
||||
default = 224; |
||||
description = '' |
||||
Set the class A subnet number to use for the internal remote DNS mapping, uses the reserved 224.x.x.x range by default. |
||||
''; |
||||
}; |
||||
|
||||
tcpReadTimeOut = mkOption { |
||||
type = types.int; |
||||
default = 15000; |
||||
description = "Connection read time-out in milliseconds."; |
||||
}; |
||||
|
||||
tcpConnectTimeOut = mkOption { |
||||
type = types.int; |
||||
default = 8000; |
||||
description = "Connection time-out in milliseconds."; |
||||
}; |
||||
|
||||
localnet = mkOption { |
||||
type = types.str; |
||||
default = "127.0.0.0/255.0.0.0"; |
||||
description = "By default enable localnet for loopback address ranges."; |
||||
}; |
||||
|
||||
proxies = mkOption { |
||||
type = types.attrsOf (types.submodule proxyOptions); |
||||
description = '' |
||||
Proxies to be used by proxychains. |
||||
''; |
||||
|
||||
example = literalExample '' |
||||
{ myproxy = |
||||
{ type = "socks4"; |
||||
host = "127.0.0.1"; |
||||
port = 1337; |
||||
}; |
||||
} |
||||
''; |
||||
}; |
||||
|
||||
}; |
||||
|
||||
}; |
||||
|
||||
###### implementation |
||||
|
||||
meta.maintainers = with maintainers; [ sorki ]; |
||||
|
||||
config = mkIf cfg.enable { |
||||
|
||||
assertions = singleton { |
||||
assertion = cfg.chain.type != "random" && cfg.chain.length == null; |
||||
message = '' |
||||
Option `programs.proxychains.chain.length` |
||||
only makes sense with `programs.proxychains.chain.type` = "random". |
||||
''; |
||||
}; |
||||
|
||||
programs.proxychains.proxies = mkIf config.services.tor.client.enable |
||||
{ |
||||
torproxy = mkDefault { |
||||
enable = true; |
||||
type = "socks4"; |
||||
host = "127.0.0.1"; |
||||
port = 9050; |
||||
}; |
||||
}; |
||||
|
||||
environment.etc."proxychains.conf".text = configFile; |
||||
environment.systemPackages = [ pkgs.proxychains ]; |
||||
}; |
||||
|
||||
} |
Loading…
Reference in new issue