python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / networking / spiped.nix
blob3e01ace54ad1701bfedb972f77dc4099ccc718fa
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.spiped;
7 in
9   options = {
10     services.spiped = {
11       enable = mkOption {
12         type        = types.bool;
13         default     = false;
14         description = lib.mdDoc "Enable the spiped service module.";
15       };
17       config = mkOption {
18         type = types.attrsOf (types.submodule (
19           {
20             options = {
21               encrypt = mkOption {
22                 type    = types.bool;
23                 default = false;
24                 description = lib.mdDoc ''
25                   Take unencrypted connections from the
26                   `source` socket and send encrypted
27                   connections to the `target` socket.
28                 '';
29               };
31               decrypt = mkOption {
32                 type    = types.bool;
33                 default = false;
34                 description = lib.mdDoc ''
35                   Take encrypted connections from the
36                   `source` socket and send unencrypted
37                   connections to the `target` socket.
38                 '';
39               };
41               source = mkOption {
42                 type    = types.str;
43                 description = lib.mdDoc ''
44                   Address on which spiped should listen for incoming
45                   connections.  Must be in one of the following formats:
46                   `/absolute/path/to/unix/socket`,
47                   `host.name:port`,
48                   `[ip.v4.ad.dr]:port` or
49                   `[ipv6::addr]:port` - note that
50                   hostnames are resolved when spiped is launched and are
51                   not re-resolved later; thus if DNS entries change
52                   spiped will continue to connect to the expired
53                   address.
54                 '';
55               };
57               target = mkOption {
58                 type    = types.str;
59                 description = lib.mdDoc "Address to which spiped should connect.";
60               };
62               keyfile = mkOption {
63                 type    = types.path;
64                 description = lib.mdDoc ''
65                   Name of a file containing the spiped key. As the
66                   daemon runs as the `spiped` user, the
67                   key file must be somewhere owned by that user. By
68                   default, we recommend putting the keys for any spipe
69                   services in `/var/lib/spiped`.
70                 '';
71               };
73               timeout = mkOption {
74                 type = types.int;
75                 default = 5;
76                 description = lib.mdDoc ''
77                   Timeout, in seconds, after which an attempt to connect to
78                   the target or a protocol handshake will be aborted (and the
79                   connection dropped) if not completed
80                 '';
81               };
83               maxConns = mkOption {
84                 type = types.int;
85                 default = 100;
86                 description = lib.mdDoc ''
87                   Limit on the number of simultaneous connections allowed.
88                 '';
89               };
91               waitForDNS = mkOption {
92                 type = types.bool;
93                 default = false;
94                 description = lib.mdDoc ''
95                   Wait for DNS. Normally when `spiped` is
96                   launched it resolves addresses and binds to its source
97                   socket before the parent process returns; with this option
98                   it will daemonize first and retry failed DNS lookups until
99                   they succeed. This allows `spiped` to
100                   launch even if DNS isn't set up yet, but at the expense of
101                   losing the guarantee that once `spiped` has
102                   finished launching it will be ready to create pipes.
103                 '';
104               };
106               disableKeepalives = mkOption {
107                 type = types.bool;
108                 default = false;
109                 description = lib.mdDoc "Disable transport layer keep-alives.";
110               };
112               weakHandshake = mkOption {
113                 type = types.bool;
114                 default = false;
115                 description = lib.mdDoc ''
116                   Use fast/weak handshaking: This reduces the CPU time spent
117                   in the initial connection setup, at the expense of losing
118                   perfect forward secrecy.
119                 '';
120               };
122               resolveRefresh = mkOption {
123                 type = types.int;
124                 default = 60;
125                 description = lib.mdDoc ''
126                   Resolution refresh time for the target socket, in seconds.
127                 '';
128               };
130               disableReresolution = mkOption {
131                 type = types.bool;
132                 default = false;
133                 description = lib.mdDoc "Disable target address re-resolution.";
134               };
135             };
136           }
137         ));
139         default = {};
141         example = literalExpression ''
142           {
143             pipe1 =
144               { keyfile = "/var/lib/spiped/pipe1.key";
145                 encrypt = true;
146                 source  = "localhost:6000";
147                 target  = "endpoint.example.com:7000";
148               };
149             pipe2 =
150               { keyfile = "/var/lib/spiped/pipe2.key";
151                 decrypt = true;
152                 source  = "0.0.0.0:7000";
153                 target  = "localhost:3000";
154               };
155           }
156         '';
158         description = lib.mdDoc ''
159           Configuration for a secure pipe daemon. The daemon can be
160           started, stopped, or examined using
161           `systemctl`, under the name
162           `spiped@foo`.
163         '';
164       };
165     };
166   };
168   config = mkIf cfg.enable {
169     assertions = mapAttrsToList (name: c: {
170       assertion = (c.encrypt -> !c.decrypt) || (c.decrypt -> c.encrypt);
171       message   = "A pipe must either encrypt or decrypt";
172     }) cfg.config;
174     users.groups.spiped.gid = config.ids.gids.spiped;
175     users.users.spiped = {
176       description = "Secure Pipe Service user";
177       group       = "spiped";
178       uid         = config.ids.uids.spiped;
179     };
181     systemd.services."spiped@" = {
182       description = "Secure pipe '%i'";
183       after       = [ "network.target" ];
185       serviceConfig = {
186         Restart   = "always";
187         User      = "spiped";
188         PermissionsStartOnly = true;
189       };
191       preStart  = ''
192         cd /var/lib/spiped
193         chmod -R 0660 *
194         chown -R spiped:spiped *
195       '';
196       scriptArgs = "%i";
197       script = "exec ${pkgs.spiped}/bin/spiped -F `cat /etc/spiped/$1.spec`";
198     };
200     system.activationScripts.spiped = optionalString (cfg.config != {})
201       "mkdir -p /var/lib/spiped";
203     # Setup spiped config files
204     environment.etc = mapAttrs' (name: cfg: nameValuePair "spiped/${name}.spec"
205       { text = concatStringsSep " "
206           [ (if cfg.encrypt then "-e" else "-d")        # Mode
207             "-s ${cfg.source}"                          # Source
208             "-t ${cfg.target}"                          # Target
209             "-k ${cfg.keyfile}"                         # Keyfile
210             "-n ${toString cfg.maxConns}"               # Max number of conns
211             "-o ${toString cfg.timeout}"                # Timeout
212             (optionalString cfg.waitForDNS "-D")        # Wait for DNS
213             (optionalString cfg.weakHandshake "-f")     # No PFS
214             (optionalString cfg.disableKeepalives "-j") # Keepalives
215             (if cfg.disableReresolution then "-R"
216               else "-r ${toString cfg.resolveRefresh}")
217           ];
218       }) cfg.config;
219   };