python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / networking / ghostunnel.nix
blob4902367e2a6a7f1c2b4011d4314518ad81db13bd
1 { config, lib, pkgs, ... }:
2 let
3   inherit (lib)
4     attrValues
5     concatMap
6     concatStringsSep
7     escapeShellArg
8     literalExpression
9     mapAttrs'
10     mkDefault
11     mkEnableOption
12     mkIf
13     mkOption
14     nameValuePair
15     optional
16     types
17     ;
19   mainCfg = config.services.ghostunnel;
21   module = { config, name, ... }:
22     {
23       options = {
25         listen = mkOption {
26           description = lib.mdDoc ''
27             Address and port to listen on (can be HOST:PORT, unix:PATH).
28           '';
29           type = types.str;
30         };
32         target = mkOption {
33           description = lib.mdDoc ''
34             Address to forward connections to (can be HOST:PORT or unix:PATH).
35           '';
36           type = types.str;
37         };
39         keystore = mkOption {
40           description = lib.mdDoc ''
41             Path to keystore (combined PEM with cert/key, or PKCS12 keystore).
43             NB: storepass is not supported because it would expose credentials via `/proc/*/cmdline`.
45             Specify this or `cert` and `key`.
46           '';
47           type = types.nullOr types.str;
48           default = null;
49         };
51         cert = mkOption {
52           description = lib.mdDoc ''
53             Path to certificate (PEM with certificate chain).
55             Not required if `keystore` is set.
56           '';
57           type = types.nullOr types.str;
58           default = null;
59         };
61         key = mkOption {
62           description = lib.mdDoc ''
63             Path to certificate private key (PEM with private key).
65             Not required if `keystore` is set.
66           '';
67           type = types.nullOr types.str;
68           default = null;
69         };
71         cacert = mkOption {
72           description = lib.mdDoc ''
73             Path to CA bundle file (PEM/X509). Uses system trust store if `null`.
74           '';
75           type = types.nullOr types.str;
76         };
78         disableAuthentication = mkOption {
79           description = lib.mdDoc ''
80             Disable client authentication, no client certificate will be required.
81           '';
82           type = types.bool;
83           default = false;
84         };
86         allowAll = mkOption {
87           description = lib.mdDoc ''
88             If true, allow all clients, do not check client cert subject.
89           '';
90           type = types.bool;
91           default = false;
92         };
94         allowCN = mkOption {
95           description = lib.mdDoc ''
96             Allow client if common name appears in the list.
97           '';
98           type = types.listOf types.str;
99           default = [];
100         };
102         allowOU = mkOption {
103           description = lib.mdDoc ''
104             Allow client if organizational unit name appears in the list.
105           '';
106           type = types.listOf types.str;
107           default = [];
108         };
110         allowDNS = mkOption {
111           description = lib.mdDoc ''
112             Allow client if DNS subject alternative name appears in the list.
113           '';
114           type = types.listOf types.str;
115           default = [];
116         };
118         allowURI = mkOption {
119           description = lib.mdDoc ''
120             Allow client if URI subject alternative name appears in the list.
121           '';
122           type = types.listOf types.str;
123           default = [];
124         };
126         extraArguments = mkOption {
127           description = lib.mdDoc "Extra arguments to pass to `ghostunnel server`";
128           type = types.separatedString " ";
129           default = "";
130         };
132         unsafeTarget = mkOption {
133           description = lib.mdDoc ''
134             If set, does not limit target to localhost, 127.0.0.1, [::1], or UNIX sockets.
136             This is meant to protect against accidental unencrypted traffic on
137             untrusted networks.
138           '';
139           type = types.bool;
140           default = false;
141         };
143         # Definitions to apply at the root of the NixOS configuration.
144         atRoot = mkOption {
145           internal = true;
146         };
147       };
149       # Clients should not be authenticated with the public root certificates
150       # (afaict, it doesn't make sense), so we only provide that default when
151       # client cert auth is disabled.
152       config.cacert = mkIf config.disableAuthentication (mkDefault null);
154       config.atRoot = {
155         assertions = [
156           { message = ''
157               services.ghostunnel.servers.${name}: At least one access control flag is required.
158               Set at least one of:
159                 - services.ghostunnel.servers.${name}.disableAuthentication
160                 - services.ghostunnel.servers.${name}.allowAll
161                 - services.ghostunnel.servers.${name}.allowCN
162                 - services.ghostunnel.servers.${name}.allowOU
163                 - services.ghostunnel.servers.${name}.allowDNS
164                 - services.ghostunnel.servers.${name}.allowURI
165             '';
166             assertion = config.disableAuthentication
167               || config.allowAll
168               || config.allowCN != []
169               || config.allowOU != []
170               || config.allowDNS != []
171               || config.allowURI != []
172               ;
173           }
174         ];
176         systemd.services."ghostunnel-server-${name}" = {
177           after = [ "network.target" ];
178           wants = [ "network.target" ];
179           wantedBy = [ "multi-user.target" ];
180           serviceConfig = {
181             Restart = "always";
182             AmbientCapabilities = ["CAP_NET_BIND_SERVICE"];
183             DynamicUser = true;
184             LoadCredential = optional (config.keystore != null) "keystore:${config.keystore}"
185               ++ optional (config.cert != null) "cert:${config.cert}"
186               ++ optional (config.key != null) "key:${config.key}"
187               ++ optional (config.cacert != null) "cacert:${config.cacert}";
188            };
189           script = concatStringsSep " " (
190             [ "${mainCfg.package}/bin/ghostunnel" ]
191             ++ optional (config.keystore != null) "--keystore=$CREDENTIALS_DIRECTORY/keystore"
192             ++ optional (config.cert != null) "--cert=$CREDENTIALS_DIRECTORY/cert"
193             ++ optional (config.key != null) "--key=$CREDENTIALS_DIRECTORY/key"
194             ++ optional (config.cacert != null) "--cacert=$CREDENTIALS_DIRECTORY/cacert"
195             ++ [
196               "server"
197               "--listen ${config.listen}"
198               "--target ${config.target}"
199             ] ++ optional config.allowAll "--allow-all"
200               ++ map (v: "--allow-cn=${escapeShellArg v}") config.allowCN
201               ++ map (v: "--allow-ou=${escapeShellArg v}") config.allowOU
202               ++ map (v: "--allow-dns=${escapeShellArg v}") config.allowDNS
203               ++ map (v: "--allow-uri=${escapeShellArg v}") config.allowURI
204               ++ optional config.disableAuthentication "--disable-authentication"
205               ++ optional config.unsafeTarget "--unsafe-target"
206               ++ [ config.extraArguments ]
207           );
208         };
209       };
210     };
215   options = {
216     services.ghostunnel.enable = mkEnableOption (lib.mdDoc "ghostunnel");
218     services.ghostunnel.package = mkOption {
219       description = lib.mdDoc "The ghostunnel package to use.";
220       type = types.package;
221       default = pkgs.ghostunnel;
222       defaultText = literalExpression "pkgs.ghostunnel";
223     };
225     services.ghostunnel.servers = mkOption {
226       description = lib.mdDoc ''
227         Server mode ghostunnels (TLS listener -> plain TCP/UNIX target)
228       '';
229       type = types.attrsOf (types.submodule module);
230       default = {};
231     };
232   };
234   config = mkIf mainCfg.enable {
235     assertions = lib.mkMerge (map (v: v.atRoot.assertions) (attrValues mainCfg.servers));
236     systemd = lib.mkMerge (map (v: v.atRoot.systemd) (attrValues mainCfg.servers));
237   };
239   meta.maintainers = with lib.maintainers; [
240     roberth
241   ];