at 17.09-beta 4.2 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.services.nylon; 8 9 homeDir = "/var/lib/nylon"; 10 11 configFile = cfg: pkgs.writeText "nylon-${cfg.name}.conf" '' 12 [General] 13 No-Simultaneous-Conn=${toString cfg.nrConnections} 14 Log=${if cfg.logging then "1" else "0"} 15 Verbose=${if cfg.verbosity then "1" else "0"} 16 17 [Server] 18 Binding-Interface=${cfg.acceptInterface} 19 Connecting-Interface=${cfg.bindInterface} 20 Port=${toString cfg.port} 21 Allow-IP=${concatStringsSep " " cfg.allowedIPRanges} 22 Deny-IP=${concatStringsSep " " cfg.deniedIPRanges} 23 ''; 24 25 nylonOpts = { name, config, ... }: { 26 27 options = { 28 29 enable = mkOption { 30 type = types.bool; 31 default = false; 32 description = '' 33 Enables nylon as a running service upon activation. 34 ''; 35 }; 36 37 name = mkOption { 38 type = types.str; 39 default = ""; 40 description = "The name of this nylon instance."; 41 }; 42 43 nrConnections = mkOption { 44 type = types.int; 45 default = 10; 46 description = '' 47 The number of allowed simultaneous connections to the daemon, default 10. 48 ''; 49 }; 50 51 logging = mkOption { 52 type = types.bool; 53 default = false; 54 description = '' 55 Enable logging, default is no logging. 56 ''; 57 }; 58 59 verbosity = mkOption { 60 type = types.bool; 61 default = false; 62 description = '' 63 Enable verbose output, default is to not be verbose. 64 ''; 65 }; 66 67 acceptInterface = mkOption { 68 type = types.string; 69 default = "lo"; 70 description = '' 71 Tell nylon which interface to listen for client requests on, default is "lo". 72 ''; 73 }; 74 75 bindInterface = mkOption { 76 type = types.string; 77 default = "enp3s0f0"; 78 description = '' 79 Tell nylon which interface to use as an uplink, default is "enp3s0f0". 80 ''; 81 }; 82 83 port = mkOption { 84 type = types.int; 85 default = 1080; 86 description = '' 87 What port to listen for client requests, default is 1080. 88 ''; 89 }; 90 91 allowedIPRanges = mkOption { 92 type = with types; listOf string; 93 default = [ "192.168.0.0/16" "127.0.0.1/8" "172.16.0.1/12" "10.0.0.0/8" ]; 94 description = '' 95 Allowed client IP ranges are evaluated first, defaults to ARIN IPv4 private ranges: 96 [ "192.168.0.0/16" "127.0.0.0/8" "172.16.0.0/12" "10.0.0.0/8" ] 97 ''; 98 }; 99 100 deniedIPRanges = mkOption { 101 type = with types; listOf string; 102 default = [ "0.0.0.0/0" ]; 103 description = '' 104 Denied client IP ranges, these gets evaluated after the allowed IP ranges, defaults to all IPv4 addresses: 105 [ "0.0.0.0/0" ] 106 To block all other access than the allowed. 107 ''; 108 }; 109 }; 110 config = { name = mkDefault name; }; 111 }; 112 113 mkNamedNylon = cfg: { 114 "nylon-${cfg.name}" = { 115 description = "Nylon, a lightweight SOCKS proxy server"; 116 after = [ "network.target" ]; 117 wantedBy = [ "multi-user.target" ]; 118 serviceConfig = 119 { 120 User = "nylon"; 121 Group = "nylon"; 122 WorkingDirectory = homeDir; 123 ExecStart = "${pkgs.nylon}/bin/nylon -f -c ${configFile cfg}"; 124 }; 125 }; 126 }; 127 128 anyNylons = collect (p: p ? enable) cfg; 129 enabledNylons = filter (p: p.enable == true) anyNylons; 130 nylonUnits = map (nylon: mkNamedNylon nylon) enabledNylons; 131 132in 133 134{ 135 136 ###### interface 137 138 options = { 139 140 services.nylon = mkOption { 141 default = {}; 142 description = "Collection of named nylon instances"; 143 type = with types; loaOf (submodule nylonOpts); 144 internal = true; 145 options = [ nylonOpts ]; 146 }; 147 148 }; 149 150 ###### implementation 151 152 config = mkIf (length(enabledNylons) > 0) { 153 154 users.extraUsers.nylon = { 155 group = "nylon"; 156 description = "Nylon SOCKS Proxy"; 157 home = homeDir; 158 createHome = true; 159 uid = config.ids.uids.nylon; 160 }; 161 162 users.extraGroups.nylon.gid = config.ids.gids.nylon; 163 164 systemd.services = fold (a: b: a // b) {} nylonUnits; 165 166 }; 167}