vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / services / networking / spacecookie.nix
blob0e37b6d0305eb08b3a63dcff5b2dff1b7d15f1bd
1 { config, lib, pkgs, ... }:
3 with lib;
5 let
6   cfg = config.services.spacecookie;
8   spacecookieConfig = {
9     listen = {
10       inherit (cfg) port;
11     };
12   } // cfg.settings;
14   format = pkgs.formats.json {};
16   configFile = format.generate "spacecookie.json" spacecookieConfig;
18 in {
19   imports = [
20     (mkRenamedOptionModule [ "services" "spacecookie" "root" ] [ "services" "spacecookie" "settings" "root" ])
21     (mkRenamedOptionModule [ "services" "spacecookie" "hostname" ] [ "services" "spacecookie" "settings" "hostname" ])
22   ];
24   options = {
26     services.spacecookie = {
28       enable = mkEnableOption "spacecookie";
30       package = mkPackageOption pkgs "spacecookie" {
31         example = "haskellPackages.spacecookie";
32       };
34       openFirewall = mkOption {
35         type = types.bool;
36         default = false;
37         description = ''
38           Whether to open the necessary port in the firewall for spacecookie.
39         '';
40       };
42       port = mkOption {
43         type = types.port;
44         default = 70;
45         description = ''
46           Port the gopher service should be exposed on.
47         '';
48       };
50       address = mkOption {
51         type = types.str;
52         default = "[::]";
53         description = ''
54           Address to listen on. Must be in the
55           `ListenStream=` syntax of
56           [systemd.socket(5)](https://www.freedesktop.org/software/systemd/man/systemd.socket.html).
57         '';
58       };
60       settings = mkOption {
61         type = types.submodule {
62           freeformType = format.type;
64           options.hostname = mkOption {
65             type = types.str;
66             default = "localhost";
67             description = ''
68               The hostname the service is reachable via. Clients
69               will use this hostname for further requests after
70               loading the initial gopher menu.
71             '';
72           };
74           options.root = mkOption {
75             type = types.path;
76             default = "/srv/gopher";
77             description = ''
78               The directory spacecookie should serve via gopher.
79               Files in there need to be world-readable since
80               the spacecookie service file sets
81               `DynamicUser=true`.
82             '';
83           };
85           options.log = {
86             enable = mkEnableOption "logging for spacecookie"
87               // { default = true; example = false; };
89             hide-ips = mkOption {
90               type = types.bool;
91               default = true;
92               description = ''
93                 If enabled, spacecookie will hide personal
94                 information of users like IP addresses from
95                 log output.
96               '';
97             };
99             hide-time = mkOption {
100               type = types.bool;
101               # since we are starting with systemd anyways
102               # we deviate from the default behavior here:
103               # journald will add timestamps, so no need
104               # to double up.
105               default = true;
106               description = ''
107                 If enabled, spacecookie will not print timestamps
108                 at the beginning of every log line.
109               '';
110             };
112             level = mkOption {
113               type = types.enum [
114                 "info"
115                 "warn"
116                 "error"
117               ];
118               default = "info";
119               description = ''
120                 Log level for the spacecookie service.
121               '';
122             };
123           };
124         };
126         description = ''
127           Settings for spacecookie. The settings set here are
128           directly translated to the spacecookie JSON config
129           file. See
130           [spacecookie.json(5)](https://sternenseemann.github.io/spacecookie/spacecookie.json.5.html)
131           for explanations of all options.
132         '';
133       };
134     };
135   };
137   config = mkIf cfg.enable {
138     assertions = [
139       {
140         assertion = !(cfg.settings ? user);
141         message = ''
142           spacecookie is started as a normal user, so the setuid
143           feature doesn't work. If you want to run spacecookie as
144           a specific user, set:
145           systemd.services.spacecookie.serviceConfig = {
146             DynamicUser = false;
147             User = "youruser";
148             Group = "yourgroup";
149           }
150         '';
151       }
152       {
153         assertion = !(cfg.settings ? listen || cfg.settings ? port);
154         message = ''
155           The NixOS spacecookie module uses socket activation,
156           so the listen options have no effect. Use the port
157           and address options in services.spacecookie instead.
158         '';
159       }
160     ];
162     systemd.sockets.spacecookie = {
163       description = "Socket for the Spacecookie Gopher Server";
164       wantedBy = [ "sockets.target" ];
165       listenStreams = [ "${cfg.address}:${toString cfg.port}" ];
166       socketConfig = {
167         BindIPv6Only = "both";
168       };
169     };
171     systemd.services.spacecookie = {
172       description = "Spacecookie Gopher Server";
173       wantedBy = [ "multi-user.target" ];
174       requires = [ "spacecookie.socket" ];
176       serviceConfig = {
177         Type = "notify";
178         ExecStart = "${lib.getBin cfg.package}/bin/spacecookie ${configFile}";
179         FileDescriptorStoreMax = 1;
181         DynamicUser = true;
183         ProtectSystem = "strict";
184         ProtectHome = true;
185         PrivateTmp = true;
186         PrivateDevices = true;
187         PrivateMounts = true;
188         PrivateUsers = true;
190         ProtectKernelTunables = true;
191         ProtectKernelModules = true;
192         ProtectControlGroups = true;
194         CapabilityBoundingSet = "";
195         NoNewPrivileges = true;
196         LockPersonality = true;
197         RestrictRealtime = true;
199         # AF_UNIX for communication with systemd
200         # AF_INET replaced by BindIPv6Only=both
201         RestrictAddressFamilies = "AF_UNIX AF_INET6";
202       };
203     };
205     networking.firewall = mkIf cfg.openFirewall {
206       allowedTCPPorts = [ cfg.port ];
207     };
208   };