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