| 
									
										
										
										
											2015-01-14 22:08:19 +01:00
										 |  |  | { config, lib, pkgs, ... }: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | with lib; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cfg = config.services.nylon; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   homeDir = "/var/lib/nylon"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-30 20:31:03 +01:00
										 |  |  |   configFile = cfg: pkgs.writeText "nylon-${cfg.name}.conf" ''
 | 
					
						
							| 
									
										
										
										
											2015-01-14 22:08:19 +01:00
										 |  |  |     [General] | 
					
						
							|  |  |  |     No-Simultaneous-Conn=${toString cfg.nrConnections} | 
					
						
							|  |  |  |     Log=${if cfg.logging then "1" else "0"} | 
					
						
							|  |  |  |     Verbose=${if cfg.verbosity then "1" else "0"} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [Server] | 
					
						
							|  |  |  |     Binding-Interface=${cfg.acceptInterface} | 
					
						
							|  |  |  |     Connecting-Interface=${cfg.bindInterface} | 
					
						
							|  |  |  |     Port=${toString cfg.port} | 
					
						
							|  |  |  |     Allow-IP=${concatStringsSep " " cfg.allowedIPRanges} | 
					
						
							|  |  |  |     Deny-IP=${concatStringsSep " " cfg.deniedIPRanges} | 
					
						
							|  |  |  |   '';
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 20:56:59 +00:00
										 |  |  |   nylonOpts = { name, ... }: { | 
					
						
							| 
									
										
										
										
											2015-01-14 22:08:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-30 20:31:03 +01:00
										 |  |  |     options = { | 
					
						
							| 
									
										
										
										
											2015-01-14 22:08:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       enable = mkOption { | 
					
						
							|  |  |  |         type = types.bool; | 
					
						
							|  |  |  |         default = false; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |           Enables nylon as a running service upon activation. | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-30 20:31:03 +01:00
										 |  |  |       name = mkOption { | 
					
						
							|  |  |  |         type = types.str; | 
					
						
							|  |  |  |         default = ""; | 
					
						
							|  |  |  |         description = "The name of this nylon instance."; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 22:08:19 +01:00
										 |  |  |       nrConnections = mkOption { | 
					
						
							|  |  |  |         type = types.int; | 
					
						
							|  |  |  |         default = 10; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |           The number of allowed simultaneous connections to the daemon, default 10. | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       logging = mkOption { | 
					
						
							|  |  |  |         type = types.bool; | 
					
						
							|  |  |  |         default = false; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |           Enable logging, default is no logging. | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       verbosity = mkOption { | 
					
						
							|  |  |  |         type = types.bool; | 
					
						
							|  |  |  |         default = false; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |           Enable verbose output, default is to not be verbose. | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       acceptInterface = mkOption { | 
					
						
							|  |  |  |         type = types.string; | 
					
						
							|  |  |  |         default = "lo"; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |           Tell nylon which interface to listen for client requests on, default is "lo". | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       bindInterface = mkOption { | 
					
						
							|  |  |  |         type = types.string; | 
					
						
							|  |  |  |         default = "enp3s0f0"; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |           Tell nylon which interface to use as an uplink, default is "enp3s0f0". | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       port = mkOption { | 
					
						
							|  |  |  |         type = types.int; | 
					
						
							|  |  |  |         default = 1080; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |           What port to listen for client requests, default is 1080. | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       allowedIPRanges = mkOption { | 
					
						
							|  |  |  |         type = with types; listOf string; | 
					
						
							|  |  |  |         default = [ "192.168.0.0/16" "127.0.0.1/8" "172.16.0.1/12" "10.0.0.0/8" ]; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |            Allowed client IP ranges are evaluated first, defaults to ARIN IPv4 private ranges: | 
					
						
							|  |  |  |              [ "192.168.0.0/16" "127.0.0.0/8" "172.16.0.0/12" "10.0.0.0/8" ] | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       deniedIPRanges = mkOption { | 
					
						
							|  |  |  |         type = with types; listOf string; | 
					
						
							|  |  |  |         default = [ "0.0.0.0/0" ]; | 
					
						
							|  |  |  |         description = ''
 | 
					
						
							|  |  |  |           Denied client IP ranges, these gets evaluated after the allowed IP ranges, defaults to all IPv4 addresses: | 
					
						
							|  |  |  |             [ "0.0.0.0/0" ] | 
					
						
							|  |  |  |           To block all other access than the allowed. | 
					
						
							|  |  |  |         '';
 | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2017-01-30 20:31:03 +01:00
										 |  |  |     config = { name = mkDefault name; }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   mkNamedNylon = cfg: { | 
					
						
							|  |  |  |     "nylon-${cfg.name}" = { | 
					
						
							|  |  |  |       description = "Nylon, a lightweight SOCKS proxy server"; | 
					
						
							|  |  |  |       after = [ "network.target" ]; | 
					
						
							|  |  |  |       wantedBy = [ "multi-user.target" ]; | 
					
						
							|  |  |  |       serviceConfig = | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         User = "nylon"; | 
					
						
							|  |  |  |         Group = "nylon"; | 
					
						
							|  |  |  |         WorkingDirectory = homeDir; | 
					
						
							|  |  |  |         ExecStart = "${pkgs.nylon}/bin/nylon -f -c ${configFile cfg}"; | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   anyNylons = collect (p: p ? enable) cfg; | 
					
						
							|  |  |  |   enabledNylons = filter (p: p.enable == true) anyNylons; | 
					
						
							|  |  |  |   nylonUnits = map (nylon: mkNamedNylon nylon) enabledNylons; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | in | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ###### interface | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   options = { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     services.nylon = mkOption { | 
					
						
							|  |  |  |       default = {}; | 
					
						
							|  |  |  |       description = "Collection of named nylon instances"; | 
					
						
							|  |  |  |       type = with types; loaOf (submodule nylonOpts); | 
					
						
							|  |  |  |       internal = true; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 22:08:19 +01:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ###### implementation | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-30 20:31:03 +01:00
										 |  |  |   config = mkIf (length(enabledNylons) > 0) { | 
					
						
							| 
									
										
										
										
											2015-01-14 22:08:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-30 01:58:35 +02:00
										 |  |  |     users.users.nylon = { | 
					
						
							| 
									
										
										
										
											2015-01-14 22:08:19 +01:00
										 |  |  |       group = "nylon"; | 
					
						
							|  |  |  |       description = "Nylon SOCKS Proxy"; | 
					
						
							|  |  |  |       home = homeDir; | 
					
						
							|  |  |  |       createHome = true; | 
					
						
							|  |  |  |       uid = config.ids.uids.nylon; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-30 01:58:35 +02:00
										 |  |  |     users.groups.nylon.gid = config.ids.gids.nylon; | 
					
						
							| 
									
										
										
										
											2015-01-14 22:08:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-30 20:31:03 +01:00
										 |  |  |     systemd.services = fold (a: b: a // b) {} nylonUnits; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 22:08:19 +01:00
										 |  |  |   }; | 
					
						
							|  |  |  | } |