vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / networking / microsocks.nix
blob09afaf6edf031c86fa2285bfed4324e456eaf042
1 { config,
2   lib,
3   pkgs,
4   ...
5 }:
7 let
8   cfg = config.services.microsocks;
10   cmd =
11     if cfg.execWrapper != null
12     then "${cfg.execWrapper} ${cfg.package}/bin/microsocks"
13     else "${cfg.package}/bin/microsocks";
14   args =
15     [ "-i" cfg.ip "-p" (toString cfg.port) ]
16     ++ lib.optionals (cfg.authOnce) [ "-1" ]
17     ++ lib.optionals (cfg.disableLogging) [ "-q" ]
18     ++ lib.optionals (cfg.outgoingBindIp != null) [ "-b" cfg.outgoingBindIp ]
19     ++ lib.optionals (cfg.authUsername != null) [ "-u" cfg.authUsername ];
20 in {
21   options.services.microsocks = {
22     enable = lib.mkEnableOption "Tiny, portable SOCKS5 server with very moderate resource usage";
23     user = lib.mkOption {
24       default = "microsocks";
25       description = "User microsocks runs as.";
26       type = lib.types.str;
27     };
28     group = lib.mkOption {
29       default = "microsocks";
30       description = "Group microsocks runs as.";
31       type = lib.types.str;
32     };
33     package = lib.mkPackageOption pkgs "microsocks" {};
34     ip = lib.mkOption {
35       type = lib.types.str;
36       default = "127.0.0.1";
37       description = ''
38         IP on which microsocks should listen. Defaults to 127.0.0.1 for
39         security reasons.
40       '';
41     };
42     port = lib.mkOption {
43       type = lib.types.port;
44       default = 1080;
45       description = "Port on which microsocks should listen.";
46     };
47     disableLogging = lib.mkOption {
48       type = lib.types.bool;
49       default = false;
50       description = "If true, microsocks will not log any messages to stdout/stderr.";
51     };
52     authOnce = lib.mkOption {
53       type = lib.types.bool;
54       default = false;
55       description = ''
56         If true, once a specific ip address authed successfully with user/pass,
57         it is added to a whitelist and may use the proxy without auth.
58       '';
59     };
60     outgoingBindIp = lib.mkOption {
61       type = lib.types.nullOr lib.types.str;
62       default = null;
63       description = "Specifies which ip outgoing connections are bound to";
64     };
65     authUsername = lib.mkOption {
66       type = lib.types.nullOr lib.types.str;
67       default = null;
68       example = "alice";
69       description = "Optional username to use for authentication.";
70     };
71     authPasswordFile = lib.mkOption {
72       type = lib.types.nullOr lib.types.path;
73       default = null;
74       example = "/run/secrets/microsocks-password";
75       description = "Path to a file containing the password for authentication.";
76     };
77     execWrapper = lib.mkOption {
78       type = lib.types.nullOr lib.types.str;
79       default = null;
80       example = ''
81         ''${pkgs.mullvad-vpn}/bin/mullvad-exclude
82       '';
83       description = ''
84         An optional command to prepend to the microsocks command (such as proxychains, or a VPN exclude command).
85       '';
86     };
87   };
88   config = lib.mkIf cfg.enable {
89     assertions = [
90       {
91         assertion = (cfg.authUsername != null) == (cfg.authPasswordFile != null);
92         message = "Need to set both authUsername and authPasswordFile for microsocks";
93       }
94     ];
95     users = {
96       users = lib.mkIf (cfg.user == "microsocks") {
97         microsocks = {
98           group = cfg.group;
99           isSystemUser = true;
100         };
101       };
102       groups = lib.mkIf (cfg.group == "microsocks") {
103         microsocks = {};
104       };
105     };
106     systemd.services.microsocks = {
107       enable = true;
108       description = "a tiny socks server";
109       after = [ "network.target" ];
110       wantedBy = [ "multi-user.target" ];
111       serviceConfig = {
112         User = cfg.user;
113         Group = cfg.group;
114         Restart = "on-failure";
115         RestartSec = 10;
116         LoadCredential = lib.optionalString (cfg.authPasswordFile != null) "MICROSOCKS_PASSWORD_FILE:${cfg.authPasswordFile}";
117         MemoryDenyWriteExecute = true;
118         SystemCallArchitectures = "native";
119         PrivateTmp = true;
120         NoNewPrivileges = true;
121         ProtectSystem = "strict";
122         ProtectHome = true;
123         ProtectKernelModules = true;
124         ProtectKernelTunables = true;
125         PrivateDevices = true;
126         RestrictSUIDSGID = true;
127         RestrictNamespaces = [
128           "cgroup"
129           "ipc"
130           "pid"
131           "user"
132           "uts"
133         ];
134       };
135       script =
136         if cfg.authPasswordFile != null
137         then ''
138           PASSWORD=$(cat "$CREDENTIALS_DIRECTORY/MICROSOCKS_PASSWORD_FILE")
139           ${cmd} ${lib.escapeShellArgs args} -P "$PASSWORD"
140         ''
141         else ''
142           ${cmd} ${lib.escapeShellArgs args}
143         '';
144     };
145   };