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