1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 cfg = config.services.nylon;
8
9 homeDir = "/var/lib/nylon";
10
11 configFile = pkgs.writeText "nylon.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
25in
26
27{
28
29 ###### interface
30
31 options = {
32
33 services.nylon = {
34
35 enable = mkOption {
36 type = types.bool;
37 default = false;
38 description = ''
39 Enables nylon as a running service upon activation.
40 '';
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 };
111
112 ###### implementation
113
114 config = mkIf cfg.enable {
115
116 users.extraUsers.nylon= {
117 group = "nylon";
118 description = "Nylon SOCKS Proxy";
119 home = homeDir;
120 createHome = true;
121 uid = config.ids.uids.nylon;
122 };
123
124 users.extraGroups.nylon.gid = config.ids.gids.nylon;
125
126 systemd.services.nylon = {
127 description = "Nylon, a lightweight SOCKS proxy server";
128 after = [ "network.target" ];
129 wantedBy = [ "multi-user.target" ];
130 serviceConfig =
131 {
132 User = "nylon";
133 Group = "nylon";
134 WorkingDirectory = homeDir;
135 ExecStart = "${pkgs.nylon}/bin/nylon -f -c ${configFile}";
136 };
137 };
138 };
139}