diff options
author | Michael Raskin <7c6f434c@mail.ru> | 2019-12-19 15:42:15 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-19 15:42:15 +0000 |
commit | 6210c155738d9428de24c18f0d6bd85a41918d93 (patch) | |
tree | 044237fef05a0d68298b336b764ed2ad7e25567b | |
parent | c3b0e1268a3786b0ec00f1bd6accca5b1d57d550 (diff) | |
parent | 823d6698bb1802e673bd0f02a97d8ac0606c1b4f (diff) | |
download | nixpkgs-6210c155738d9428de24c18f0d6bd85a41918d93.tar nixpkgs-6210c155738d9428de24c18f0d6bd85a41918d93.tar.gz nixpkgs-6210c155738d9428de24c18f0d6bd85a41918d93.tar.bz2 nixpkgs-6210c155738d9428de24c18f0d6bd85a41918d93.tar.lz nixpkgs-6210c155738d9428de24c18f0d6bd85a41918d93.tar.xz nixpkgs-6210c155738d9428de24c18f0d6bd85a41918d93.tar.zst nixpkgs-6210c155738d9428de24c18f0d6bd85a41918d93.zip |
Merge pull request #67507 from misuzu/package-3proxy
3proxy: init at 0.8.13
-rw-r--r-- | maintainers/maintainer-list.nix | 6 | ||||
-rw-r--r-- | nixos/modules/module-list.nix | 1 | ||||
-rw-r--r-- | nixos/modules/services/networking/3proxy.nix | 423 | ||||
-rw-r--r-- | nixos/tests/3proxy.nix | 162 | ||||
-rw-r--r-- | nixos/tests/all-tests.nix | 1 | ||||
-rw-r--r-- | pkgs/applications/networking/3proxy/default.nix | 26 | ||||
-rw-r--r-- | pkgs/top-level/all-packages.nix | 2 |
7 files changed, 621 insertions, 0 deletions
diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index 08db4549733..1362931f706 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -7732,6 +7732,12 @@ githubId = 1986844; name = "Daniel Wheeler"; }; + misuzu = { + email = "bakalolka@gmail.com"; + github = "misuzu"; + githubId = 248143; + name = "misuzu"; + }; zokrezyl = { email = "zokrezyl@gmail.com"; github = "zokrezyl"; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 3300848220a..c4acc15a58a 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -557,6 +557,7 @@ ./services/network-filesystems/yandex-disk.nix ./services/network-filesystems/xtreemfs.nix ./services/network-filesystems/ceph.nix + ./services/networking/3proxy.nix ./services/networking/amuled.nix ./services/networking/aria2.nix ./services/networking/asterisk.nix diff --git a/nixos/modules/services/networking/3proxy.nix b/nixos/modules/services/networking/3proxy.nix new file mode 100644 index 00000000000..d922e2f41c6 --- /dev/null +++ b/nixos/modules/services/networking/3proxy.nix @@ -0,0 +1,423 @@ +{ config, lib, pkgs, ... }: +with lib; +let + pkg = pkgs._3proxy; + cfg = config.services._3proxy; + optionalList = list: if list == [ ] then "*" else concatMapStringsSep "," toString list; +in { + options.services._3proxy = { + enable = mkEnableOption "3proxy"; + confFile = mkOption { + type = types.path; + example = "/var/lib/3proxy/3proxy.conf"; + description = '' + Ignore all other 3proxy options and load configuration from this file. + ''; + }; + usersFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/var/lib/3proxy/3proxy.passwd"; + description = '' + Load users and passwords from this file. + + Example users file with plain-text passwords: + + <para> + test1:CL:password1 + test2:CL:password2 + </para> + + Example users file with md5-crypted passwords: + + <para> + test1:CR:$1$tFkisVd2$1GA8JXkRmTXdLDytM/i3a1 + test2:CR:$1$rkpibm5J$Aq1.9VtYAn0JrqZ8M.1ME. + </para> + + You can generate md5-crypted passwords via https://unix4lyfe.org/crypt/ + Note that htpasswd tool generates incompatible md5-crypted passwords. + Consult <link xlink:href="https://github.com/z3APA3A/3proxy/wiki/How-To-(incomplete)#USERS">documentation</link> for more information. + ''; + }; + services = mkOption { + type = types.listOf (types.submodule { + options = { + type = mkOption { + type = types.enum [ + "proxy" + "socks" + "pop3p" + "ftppr" + "admin" + "dnspr" + "tcppm" + "udppm" + ]; + example = "proxy"; + description = '' + Service type. The following values are valid: + + <itemizedlist> + <listitem><para> + <literal>"proxy"</literal>: HTTP/HTTPS proxy (default port 3128). + </para></listitem> + <listitem><para> + <literal>"socks"</literal>: SOCKS 4/4.5/5 proxy (default port 1080). + </para></listitem> + <listitem><para> + <literal>"pop3p"</literal>: POP3 proxy (default port 110). + </para></listitem> + <listitem><para> + <literal>"ftppr"</literal>: FTP proxy (default port 21). + </para></listitem> + <listitem><para> + <literal>"admin"</literal>: Web interface (default port 80). + </para></listitem> + <listitem><para> + <literal>"dnspr"</literal>: Caching DNS proxy (default port 53). + </para></listitem> + <listitem><para> + <literal>"tcppm"</literal>: TCP portmapper. + </para></listitem> + <listitem><para> + <literal>"udppm"</literal>: UDP portmapper. + </para></listitem> + </itemizedlist> + ''; + }; + bindAddress = mkOption { + type = types.str; + default = "[::]"; + example = "127.0.0.1"; + description = '' + Address used for service. + ''; + }; + bindPort = mkOption { + type = types.nullOr types.int; + default = null; + example = 3128; + description = '' + Override default port used for service. + ''; + }; + maxConnections = mkOption { + type = types.int; + default = 100; + example = 1000; + description = '' + Maximum number of simulationeous connections to this service. + ''; + }; + auth = mkOption { + type = types.listOf (types.enum [ "none" "iponly" "strong" ]); + example = [ "iponly" "strong" ]; + description = '' + Authentication type. The following values are valid: + + <itemizedlist> + <listitem><para> + <literal>"none"</literal>: disables both authentication and authorization. You can not use ACLs. + </para></listitem> + <listitem><para> + <literal>"iponly"</literal>: specifies no authentication. ACLs authorization is used. + </para></listitem> + <listitem><para> + <literal>"strong"</literal>: authentication by username/password. If user is not registered his access is denied regardless of ACLs. + </para></listitem> + </itemizedlist> + + Double authentication is possible, e.g. + <para> + { + auth = [ "iponly" "strong" ]; + acl = [ + { + rule = "allow"; + targets = [ "192.168.0.0/16" ]; + } + { + rule = "allow" + users = [ "user1" "user2" ]; + } + ]; + } + </para> + In this example strong username authentication is not required to access 192.168.0.0/16. + ''; + }; + acl = mkOption { + type = types.listOf (types.submodule { + options = { + rule = mkOption { + type = types.enum [ "allow" "deny" ]; + example = "allow"; + description = '' + ACL rule. The following values are valid: + + <itemizedlist> + <listitem><para> + <literal>"allow"</literal>: connections allowed. + </para></listitem> + <listitem><para> + <literal>"deny"</literal>: connections not allowed. + </para></listitem> + </itemizedlist> + ''; + }; + users = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "user1" "user2" "user3" ]; + description = '' + List of users, use empty list for any. + ''; + }; + sources = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "127.0.0.1" "192.168.1.0/24" ]; + description = '' + List of source IP range, use empty list for any. + ''; + }; + targets = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "127.0.0.1" "192.168.1.0/24" ]; + description = '' + List of target IP ranges, use empty list for any. + May also contain host names instead of addresses. + It's possible to use wildmask in the begginning and in the the end of hostname, e.g. *badsite.com or *badcontent*. + Hostname is only checked if hostname presents in request. + ''; + }; + targetPorts = mkOption { + type = types.listOf types.int; + default = [ ]; + example = [ 80 443 ]; + description = '' + List of target ports, use empty list for any. + ''; + }; + }; + }); + default = [ ]; + example = literalExample '' + [ + { + rule = "allow"; + users = [ "user1" ]; + } + { + rule = "allow"; + sources = [ "192.168.1.0/24" ]; + } + { + rule = "deny"; + } + ] + ''; + description = '' + Use this option to limit user access to resources. + ''; + }; + extraArguments = mkOption { + type = types.nullOr types.str; + default = null; + example = "-46"; + description = '' + Extra arguments for service. + Consult "Options" section in <link xlink:href="https://github.com/z3APA3A/3proxy/wiki/3proxy.cfg">documentation</link> for available arguments. + ''; + }; + extraConfig = mkOption { + type = types.nullOr types.lines; + default = null; + description = '' + Extra configuration for service. Use this to configure things like bandwidth limiter or ACL-based redirection. + Consult <link xlink:href="https://github.com/z3APA3A/3proxy/wiki/3proxy.cfg">documentation</link> for available options. + ''; + }; + }; + }); + default = [ ]; + example = literalExample '' + [ + { + type = "proxy"; + bindAddress = "192.168.1.24"; + bindPort = 3128; + auth = [ "none" ]; + } + { + type = "proxy"; + bindAddress = "10.10.1.20"; + bindPort = 3128; + auth = [ "iponly" ]; + } + { + type = "socks"; + bindAddress = "172.17.0.1"; + bindPort = 1080; + auth = [ "strong" ]; + } + ] + ''; + description = '' + Use this option to define 3proxy services. + ''; + }; + denyPrivate = mkOption { + type = types.bool; + default = true; + description = '' + Whether to deny access to private IP ranges including loopback. + ''; + }; + privateRanges = mkOption { + type = types.listOf types.str; + default = [ + "0.0.0.0/8" + "127.0.0.0/8" + "10.0.0.0/8" + "100.64.0.0/10" + "172.16.0.0/12" + "192.168.0.0/16" + "::" + "::1" + "fc00::/7" + ]; + example = [ + "0.0.0.0/8" + "127.0.0.0/8" + "10.0.0.0/8" + "100.64.0.0/10" + "172.16.0.0/12" + "192.168.0.0/16" + "::" + "::1" + "fc00::/7" + ]; + description = '' + What IP ranges to deny access when denyPrivate is set tu true. + ''; + }; + resolution = mkOption { + type = types.submodule { + options = { + nserver = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "127.0.0.53" "192.168.1.3:5353/tcp" ]; + description = '' + List of nameservers to use. + + Up to 5 nservers may be specified. If no nserver is configured, + default system name resolution functions are used. + ''; + }; + nscache = mkOption { + type = types.int; + default = 65535; + example = 65535; + description = "Set name cache size for IPv4."; + }; + nscache6 = mkOption { + type = types.int; + default = 65535; + example = 65535; + description = "Set name cache size for IPv6."; + }; + nsrecord = mkOption { + type = types.attrsOf types.str; + default = { }; + example = { + "files.local" = "192.168.1.12"; + "site.local" = "192.168.1.43"; + }; + description = "Adds static nsrecords."; + }; + }; + }; + default = { }; + description = '' + Use this option to configure name resolution and DNS caching. + ''; + }; + extraConfig = mkOption { + type = types.nullOr types.lines; + default = null; + description = '' + Extra configuration, appended to the 3proxy configuration file. + Consult <link xlink:href="https://github.com/z3APA3A/3proxy/wiki/3proxy.cfg">documentation</link> for available options. + ''; + }; + }; + + config = mkIf cfg.enable { + services._3proxy.confFile = mkDefault (pkgs.writeText "3proxy.conf" '' + # log to stdout + log + + ${concatMapStringsSep "\n" (x: "nserver " + x) cfg.resolution.nserver} + + nscache ${toString cfg.resolution.nscache} + nscache6 ${toString cfg.resolution.nscache6} + + ${concatMapStringsSep "\n" (x: "nsrecord " + x) + (mapAttrsToList (name: value: "${name} ${value}") + cfg.resolution.nsrecord)} + + ${optionalString (cfg.usersFile != null) + ''users $"${cfg.usersFile}"'' + } + + ${concatMapStringsSep "\n" (service: '' + auth ${concatStringsSep " " service.auth} + + ${optionalString (cfg.denyPrivate) + "deny * * ${optionalList cfg.privateRanges}"} + + ${concatMapStringsSep "\n" (acl: + "${acl.rule} ${ + concatMapStringsSep " " optionalList [ + acl.users + acl.sources + acl.targets + acl.targetPorts + ] + }") service.acl} + + maxconn ${toString service.maxConnections} + + ${optionalString (service.extraConfig != null) service.extraConfig} + + ${service.type} -i${toString service.bindAddress} ${ + optionalString (service.bindPort != null) + "-p${toString service.bindPort}" + } ${ + optionalString (service.extraArguments != null) service.extraArguments + } + + flush + '') cfg.services} + ${optionalString (cfg.extraConfig != null) cfg.extraConfig} + ''); + systemd.services."3proxy" = { + description = "Tiny free proxy server"; + documentation = [ "https://github.com/z3APA3A/3proxy/wiki" ]; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + DynamicUser = true; + StateDirectory = "3proxy"; + ExecStart = "${pkg}/bin/3proxy ${cfg.confFile}"; + Restart = "on-failure"; + }; + }; + }; + + meta.maintainers = with maintainers; [ misuzu ]; +} diff --git a/nixos/tests/3proxy.nix b/nixos/tests/3proxy.nix new file mode 100644 index 00000000000..b8e1dac0e89 --- /dev/null +++ b/nixos/tests/3proxy.nix @@ -0,0 +1,162 @@ +import ./make-test.nix ({ pkgs, ...} : { + name = "3proxy"; + meta = with pkgs.stdenv.lib.maintainers; { + maintainers = [ misuzu ]; + }; + + nodes = { + peer0 = { lib, ... }: { + networking.useDHCP = false; + networking.interfaces.eth1 = { + ipv4.addresses = [ + { + address = "192.168.0.1"; + prefixLength = 24; + } + { + address = "216.58.211.111"; + prefixLength = 24; + } + ]; + }; + }; + + peer1 = { lib, ... }: { + networking.useDHCP = false; + networking.interfaces.eth1 = { + ipv4.addresses = [ + { + address = "192.168.0.2"; + prefixLength = 24; + } + { + address = "216.58.211.112"; + prefixLength = 24; + } + ]; + }; + # test that binding to [::] is working when ipv6 is disabled + networking.enableIPv6 = false; + services._3proxy = { + enable = true; + services = [ + { + type = "admin"; + bindPort = 9999; + auth = [ "none" ]; + } + { + type = "proxy"; + bindPort = 3128; + auth = [ "none" ]; + } + ]; + }; + networking.firewall.allowedTCPPorts = [ 3128 9999 ]; + }; + + peer2 = { lib, ... }: { + networking.useDHCP = false; + networking.interfaces.eth1 = { + ipv4.addresses = [ + { + address = "192.168.0.3"; + prefixLength = 24; + } + { + address = "216.58.211.113"; + prefixLength = 24; + } + ]; + }; + services._3proxy = { + enable = true; + services = [ + { + type = "admin"; + bindPort = 9999; + auth = [ "none" ]; + } + { + type = "proxy"; + bindPort = 3128; + auth = [ "iponly" ]; + acl = [ + { + rule = "allow"; + } + ]; + } + ]; + }; + networking.firewall.allowedTCPPorts = [ 3128 9999 ]; + }; + + peer3 = { lib, ... }: { + networking.useDHCP = false; + networking.interfaces.eth1 = { + ipv4.addresses = [ + { + address = "192.168.0.4"; + prefixLength = 24; + } + { + address = "216.58.211.114"; + prefixLength = 24; + } + ]; + }; + services._3proxy = { + enable = true; + usersFile = pkgs.writeText "3proxy.passwd" '' + admin:CR:$1$.GUV4Wvk$WnEVQtaqutD9.beO5ar1W/ + ''; + services = [ + { + type = "admin"; + bindPort = 9999; + auth = [ "none" ]; + } + { + type = "proxy"; + bindPort = 3128; + auth = [ "strong" ]; + acl = [ + { + rule = "allow"; + } + ]; + } + ]; + }; + networking.firewall.allowedTCPPorts = [ 3128 9999 ]; + }; + }; + + testScript = '' + startAll; + + $peer1->waitForUnit("3proxy.service"); + + # test none auth + $peer0->succeed("${pkgs.wget}/bin/wget -e use_proxy=yes -e http_proxy=http://192.168.0.2:3128 -S -O /dev/null http://216.58.211.112:9999"); + $peer0->succeed("${pkgs.wget}/bin/wget -e use_proxy=yes -e http_proxy=http://192.168.0.2:3128 -S -O /dev/null http://192.168.0.2:9999"); + $peer0->succeed("${pkgs.wget}/bin/wget -e use_proxy=yes -e http_proxy=http://192.168.0.2:3128 -S -O /dev/null http://127.0.0.1:9999"); + + $peer2->waitForUnit("3proxy.service"); + + # test iponly auth + $peer0->succeed("${pkgs.wget}/bin/wget -e use_proxy=yes -e http_proxy=http://192.168.0.3:3128 -S -O /dev/null http://216.58.211.113:9999"); + $peer0->fail("${pkgs.wget}/bin/wget -e use_proxy=yes -e http_proxy=http://192.168.0.3:3128 -S -O /dev/null http://192.168.0.3:9999"); + $peer0->fail("${pkgs.wget}/bin/wget -e use_proxy=yes -e http_proxy=http://192.168.0.3:3128 -S -O /dev/null http://127.0.0.1:9999"); + + $peer3->waitForUnit("3proxy.service"); + + # test strong auth + $peer0->succeed("${pkgs.wget}/bin/wget -e use_proxy=yes -e http_proxy=http://admin:bigsecret\@192.168.0.4:3128 -S -O /dev/null http://216.58.211.114:9999"); + $peer0->fail("${pkgs.wget}/bin/wget -e use_proxy=yes -e http_proxy=http://admin:bigsecret\@192.168.0.4:3128 -S -O /dev/null http://192.168.0.4:9999"); + $peer0->fail("${pkgs.wget}/bin/wget -e use_proxy=yes -e http_proxy=http://192.168.0.4:3128 -S -O /dev/null http://216.58.211.114:9999"); + $peer0->fail("${pkgs.wget}/bin/wget -e use_proxy=yes -e http_proxy=http://192.168.0.4:3128 -S -O /dev/null http://192.168.0.4:9999"); + $peer0->fail("${pkgs.wget}/bin/wget -e use_proxy=yes -e http_proxy=http://192.168.0.4:3128 -S -O /dev/null http://127.0.0.1:9999"); + ''; +}) diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 9c6778f9dda..6413895c4c5 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -21,6 +21,7 @@ let else {}; in { + _3proxy = handleTest ./3proxy.nix {}; acme = handleTestOn ["x86_64-linux"] ./acme.nix {}; atd = handleTest ./atd.nix {}; automysqlbackup = handleTest ./automysqlbackup.nix {}; diff --git a/pkgs/applications/networking/3proxy/default.nix b/pkgs/applications/networking/3proxy/default.nix new file mode 100644 index 00000000000..a1e54b50228 --- /dev/null +++ b/pkgs/applications/networking/3proxy/default.nix @@ -0,0 +1,26 @@ +{ stdenv, fetchFromGitHub, coreutils }: + +stdenv.mkDerivation rec { + pname = "3proxy"; + version = "0.8.13"; + src = fetchFromGitHub { + owner = "z3APA3A"; + repo = pname; + rev = version; + sha256 = "1k5rqldiyakhwhplazlhswkgy3psdkpxhn85605ncwaqx49qy8vk"; + }; + makeFlags = [ + "INSTALL=${coreutils}/bin/install" + "prefix=$(out)" + ]; + preConfigure = '' + ln -s Makefile.Linux Makefile + ''; + meta = with stdenv.lib; { + description = "Tiny free proxy server"; + homepage = "https://github.com/z3APA3A/3proxy"; + license = licenses.gpl2; + platforms = platforms.linux; + maintainers = [ maintainers.misuzu ]; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 6b9a6c44e61..801c86d0d84 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -25617,6 +25617,8 @@ in kodelife = callPackage ../applications/graphics/kodelife {}; + _3proxy = callPackage ../applications/networking/3proxy {}; + pigeon = callPackage ../development/tools/pigeon {}; verifpal = callPackage ../tools/security/verifpal {}; |