9 cfg = config.services._3proxy;
10 optionalList = list: if list == [ ] then "*" else lib.concatMapStringsSep "," toString list;
13 options.services._3proxy = {
14 enable = lib.mkEnableOption "3proxy";
15 confFile = lib.mkOption {
16 type = lib.types.path;
17 example = "/var/lib/3proxy/3proxy.conf";
19 Ignore all other 3proxy options and load configuration from this file.
22 usersFile = lib.mkOption {
23 type = lib.types.nullOr lib.types.path;
25 example = "/var/lib/3proxy/3proxy.passwd";
27 Load users and passwords from this file.
29 Example users file with plain-text passwords:
36 Example users file with md5-crypted passwords:
39 test1:CR:$1$tFkisVd2$1GA8JXkRmTXdLDytM/i3a1
40 test2:CR:$1$rkpibm5J$Aq1.9VtYAn0JrqZ8M.1ME.
43 You can generate md5-crypted passwords via https://unix4lyfe.org/crypt/
44 Note that htpasswd tool generates incompatible md5-crypted passwords.
45 Consult [documentation](https://github.com/z3APA3A/3proxy/wiki/How-To-%28incomplete%29#USERS) for more information.
48 services = lib.mkOption {
49 type = lib.types.listOf (
53 type = lib.types.enum [
65 Service type. The following values are valid:
67 - `"proxy"`: HTTP/HTTPS proxy (default port 3128).
68 - `"socks"`: SOCKS 4/4.5/5 proxy (default port 1080).
69 - `"pop3p"`: POP3 proxy (default port 110).
70 - `"ftppr"`: FTP proxy (default port 21).
71 - `"admin"`: Web interface (default port 80).
72 - `"dnspr"`: Caching DNS proxy (default port 53).
73 - `"tcppm"`: TCP portmapper.
74 - `"udppm"`: UDP portmapper.
77 bindAddress = lib.mkOption {
80 example = "127.0.0.1";
82 Address used for service.
85 bindPort = lib.mkOption {
86 type = lib.types.nullOr lib.types.int;
90 Override default port used for service.
93 maxConnections = lib.mkOption {
98 Maximum number of simulationeous connections to this service.
101 auth = lib.mkOption {
102 type = lib.types.listOf (
114 Authentication type. The following values are valid:
116 - `"none"`: disables both authentication and authorization. You can not use ACLs.
117 - `"iponly"`: specifies no authentication. ACLs authorization is used.
118 - `"strong"`: authentication by username/password. If user is not registered their access is denied regardless of ACLs.
120 Double authentication is possible, e.g.
124 auth = [ "iponly" "strong" ];
128 targets = [ "192.168.0.0/16" ];
132 users = [ "user1" "user2" ];
137 In this example strong username authentication is not required to access 192.168.0.0/16.
141 type = lib.types.listOf (
142 lib.types.submodule {
144 rule = lib.mkOption {
145 type = lib.types.enum [
151 ACL rule. The following values are valid:
153 - `"allow"`: connections allowed.
154 - `"deny"`: connections not allowed.
157 users = lib.mkOption {
158 type = lib.types.listOf lib.types.str;
166 List of users, use empty list for any.
169 sources = lib.mkOption {
170 type = lib.types.listOf lib.types.str;
177 List of source IP range, use empty list for any.
180 targets = lib.mkOption {
181 type = lib.types.listOf lib.types.str;
188 List of target IP ranges, use empty list for any.
189 May also contain host names instead of addresses.
190 It's possible to use wildmask in the beginning and in the the end of hostname, e.g. `*badsite.com` or `*badcontent*`.
191 Hostname is only checked if hostname presents in request.
194 targetPorts = lib.mkOption {
195 type = lib.types.listOf lib.types.int;
202 List of target ports, use empty list for any.
209 example = lib.literalExpression ''
217 sources = [ "192.168.1.0/24" ];
225 Use this option to limit user access to resources.
228 extraArguments = lib.mkOption {
229 type = lib.types.nullOr lib.types.str;
233 Extra arguments for service.
234 Consult "Options" section in [documentation](https://github.com/z3APA3A/3proxy/wiki/3proxy.cfg) for available arguments.
237 extraConfig = lib.mkOption {
238 type = lib.types.nullOr lib.types.lines;
241 Extra configuration for service. Use this to configure things like bandwidth limiter or ACL-based redirection.
242 Consult [documentation](https://github.com/z3APA3A/3proxy/wiki/3proxy.cfg) for available options.
249 example = lib.literalExpression ''
253 bindAddress = "192.168.1.24";
259 bindAddress = "10.10.1.20";
265 bindAddress = "172.17.0.1";
272 Use this option to define 3proxy services.
275 denyPrivate = lib.mkOption {
276 type = lib.types.bool;
279 Whether to deny access to private IP ranges including loopback.
282 privateRanges = lib.mkOption {
283 type = lib.types.listOf lib.types.str;
296 What IP ranges to deny access when denyPrivate is set tu true.
299 resolution = lib.mkOption {
300 type = lib.types.submodule {
302 nserver = lib.mkOption {
303 type = lib.types.listOf lib.types.str;
307 "192.168.1.3:5353/tcp"
310 List of nameservers to use.
312 Up to 5 nservers may be specified. If no nserver is configured,
313 default system name resolution functions are used.
316 nscache = lib.mkOption {
317 type = lib.types.int;
319 description = "Set name cache size for IPv4.";
321 nscache6 = lib.mkOption {
322 type = lib.types.int;
324 description = "Set name cache size for IPv6.";
326 nsrecord = lib.mkOption {
327 type = lib.types.attrsOf lib.types.str;
329 example = lib.literalExpression ''
331 "files.local" = "192.168.1.12";
332 "site.local" = "192.168.1.43";
335 description = "Adds static nsrecords.";
341 Use this option to configure name resolution and DNS caching.
344 extraConfig = lib.mkOption {
345 type = lib.types.nullOr lib.types.lines;
348 Extra configuration, appended to the 3proxy configuration file.
349 Consult [documentation](https://github.com/z3APA3A/3proxy/wiki/3proxy.cfg) for available options.
354 config = lib.mkIf cfg.enable {
355 services._3proxy.confFile = lib.mkDefault (
356 pkgs.writeText "3proxy.conf" ''
360 ${lib.concatMapStringsSep "\n" (x: "nserver " + x) cfg.resolution.nserver}
362 nscache ${toString cfg.resolution.nscache}
363 nscache6 ${toString cfg.resolution.nscache6}
365 ${lib.concatMapStringsSep "\n" (x: "nsrecord " + x) (
366 lib.mapAttrsToList (name: value: "${name} ${value}") cfg.resolution.nsrecord
369 ${lib.optionalString (cfg.usersFile != null) ''users $"${cfg.usersFile}"''}
371 ${lib.concatMapStringsSep "\n" (service: ''
372 auth ${lib.concatStringsSep " " service.auth}
374 ${lib.optionalString (cfg.denyPrivate) "deny * * ${optionalList cfg.privateRanges}"}
376 ${lib.concatMapStringsSep "\n" (
379 lib.concatMapStringsSep " " optionalList [
388 maxconn ${toString service.maxConnections}
390 ${lib.optionalString (service.extraConfig != null) service.extraConfig}
392 ${service.type} -i${toString service.bindAddress} ${
393 lib.optionalString (service.bindPort != null) "-p${toString service.bindPort}"
394 } ${lib.optionalString (service.extraArguments != null) service.extraArguments}
398 ${lib.optionalString (cfg.extraConfig != null) cfg.extraConfig}
401 systemd.services."3proxy" = {
402 description = "Tiny free proxy server";
403 documentation = [ "https://github.com/z3APA3A/3proxy/wiki" ];
404 after = [ "network.target" ];
405 wantedBy = [ "multi-user.target" ];
408 StateDirectory = "3proxy";
409 ExecStart = "${pkg}/bin/3proxy ${cfg.confFile}";
410 Restart = "on-failure";
415 meta.maintainers = with lib.maintainers; [ misuzu ];