From ebd199184d7273753e9ee51553927cd22a9ffd61 Mon Sep 17 00:00:00 2001 From: Richard Marko Date: Tue, 28 Apr 2020 18:32:22 +0200 Subject: [PATCH] nixos/proxychains: init --- nixos/modules/module-list.nix | 1 + nixos/modules/programs/proxychains.nix | 165 +++++++++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 nixos/modules/programs/proxychains.nix diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index c54bc6098d3..d70d95f61c4 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -143,6 +143,7 @@ ./programs/npm.nix ./programs/oblogout.nix ./programs/plotinus.nix + ./programs/proxychains.nix ./programs/qt5ct.nix ./programs/screen.nix ./programs/sedutil.nix diff --git a/nixos/modules/programs/proxychains.nix b/nixos/modules/programs/proxychains.nix new file mode 100644 index 00000000000..7743f79c1c0 --- /dev/null +++ b/nixos/modules/programs/proxychains.nix @@ -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 = '' + dynamic - 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 EINTR is returned to the app. + + strict - 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 EINTR is returned to the app. + + random - Each connection will be done via random proxy + (or proxy chain, see ) 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 ]; + }; + +}