2015-01-14 21:08:19 +00:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
|
|
|
|
let
|
|
|
|
|
|
|
|
cfg = config.services.nylon;
|
|
|
|
|
|
|
|
homeDir = "/var/lib/nylon";
|
|
|
|
|
2017-01-30 19:31:03 +00:00
|
|
|
configFile = cfg: pkgs.writeText "nylon-${cfg.name}.conf" ''
|
2015-01-14 21:08:19 +00: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 21:08:19 +00:00
|
|
|
|
2017-01-30 19:31:03 +00:00
|
|
|
options = {
|
2015-01-14 21:08:19 +00:00
|
|
|
|
|
|
|
enable = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc ''
|
2015-01-14 21:08:19 +00:00
|
|
|
Enables nylon as a running service upon activation.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
2017-01-30 19:31:03 +00:00
|
|
|
name = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc "The name of this nylon instance.";
|
2017-01-30 19:31:03 +00:00
|
|
|
};
|
|
|
|
|
2015-01-14 21:08:19 +00:00
|
|
|
nrConnections = mkOption {
|
|
|
|
type = types.int;
|
|
|
|
default = 10;
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc ''
|
2015-01-14 21:08:19 +00:00
|
|
|
The number of allowed simultaneous connections to the daemon, default 10.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
logging = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc ''
|
2015-01-14 21:08:19 +00:00
|
|
|
Enable logging, default is no logging.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
verbosity = mkOption {
|
|
|
|
type = types.bool;
|
|
|
|
default = false;
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc ''
|
2015-01-14 21:08:19 +00:00
|
|
|
Enable verbose output, default is to not be verbose.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
acceptInterface = mkOption {
|
2019-08-08 20:48:27 +00:00
|
|
|
type = types.str;
|
2015-01-14 21:08:19 +00:00
|
|
|
default = "lo";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc ''
|
2015-01-14 21:08:19 +00:00
|
|
|
Tell nylon which interface to listen for client requests on, default is "lo".
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
bindInterface = mkOption {
|
2019-08-08 20:48:27 +00:00
|
|
|
type = types.str;
|
2015-01-14 21:08:19 +00:00
|
|
|
default = "enp3s0f0";
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc ''
|
2015-01-14 21:08:19 +00:00
|
|
|
Tell nylon which interface to use as an uplink, default is "enp3s0f0".
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
port = mkOption {
|
|
|
|
type = types.int;
|
|
|
|
default = 1080;
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc ''
|
2015-01-14 21:08:19 +00:00
|
|
|
What port to listen for client requests, default is 1080.
|
|
|
|
'';
|
|
|
|
};
|
|
|
|
|
|
|
|
allowedIPRanges = mkOption {
|
2019-08-08 20:48:27 +00:00
|
|
|
type = with types; listOf str;
|
2015-01-14 21:08:19 +00:00
|
|
|
default = [ "192.168.0.0/16" "127.0.0.1/8" "172.16.0.1/12" "10.0.0.0/8" ];
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc ''
|
2015-01-14 21:08:19 +00:00
|
|
|
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 {
|
2019-08-08 20:48:27 +00:00
|
|
|
type = with types; listOf str;
|
2015-01-14 21:08:19 +00:00
|
|
|
default = [ "0.0.0.0/0" ];
|
2022-07-28 21:19:15 +00:00
|
|
|
description = lib.mdDoc ''
|
2015-01-14 21:08:19 +00:00
|
|
|
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 19:31:03 +00: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";
|
2020-08-22 23:28:45 +00:00
|
|
|
type = with types; attrsOf (submodule nylonOpts);
|
2017-01-30 19:31:03 +00:00
|
|
|
internal = true;
|
|
|
|
};
|
|
|
|
|
2015-01-14 21:08:19 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
###### implementation
|
|
|
|
|
2017-01-30 19:31:03 +00:00
|
|
|
config = mkIf (length(enabledNylons) > 0) {
|
2015-01-14 21:08:19 +00:00
|
|
|
|
2018-06-29 23:58:35 +00:00
|
|
|
users.users.nylon = {
|
2015-01-14 21:08:19 +00:00
|
|
|
group = "nylon";
|
|
|
|
description = "Nylon SOCKS Proxy";
|
|
|
|
home = homeDir;
|
|
|
|
createHome = true;
|
|
|
|
uid = config.ids.uids.nylon;
|
|
|
|
};
|
|
|
|
|
2018-06-29 23:58:35 +00:00
|
|
|
users.groups.nylon.gid = config.ids.gids.nylon;
|
2015-01-14 21:08:19 +00:00
|
|
|
|
2021-01-25 06:57:48 +00:00
|
|
|
systemd.services = foldr (a: b: a // b) {} nylonUnits;
|
2017-01-30 19:31:03 +00:00
|
|
|
|
2015-01-14 21:08:19 +00:00
|
|
|
};
|
|
|
|
}
|