1 { config, lib, pkgs, ... }:
6 cfg = config.services.spacecookie;
14 format = pkgs.formats.json {};
16 configFile = format.generate "spacecookie.json" spacecookieConfig;
20 (mkRenamedOptionModule [ "services" "spacecookie" "root" ] [ "services" "spacecookie" "settings" "root" ])
21 (mkRenamedOptionModule [ "services" "spacecookie" "hostname" ] [ "services" "spacecookie" "settings" "hostname" ])
26 services.spacecookie = {
28 enable = mkEnableOption "spacecookie";
30 package = mkPackageOption pkgs "spacecookie" {
31 example = "haskellPackages.spacecookie";
34 openFirewall = mkOption {
38 Whether to open the necessary port in the firewall for spacecookie.
46 Port the gopher service should be exposed on.
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).
61 type = types.submodule {
62 freeformType = format.type;
64 options.hostname = mkOption {
66 default = "localhost";
68 The hostname the service is reachable via. Clients
69 will use this hostname for further requests after
70 loading the initial gopher menu.
74 options.root = mkOption {
76 default = "/srv/gopher";
78 The directory spacecookie should serve via gopher.
79 Files in there need to be world-readable since
80 the spacecookie service file sets
86 enable = mkEnableOption "logging for spacecookie"
87 // { default = true; example = false; };
93 If enabled, spacecookie will hide personal
94 information of users like IP addresses from
99 hide-time = mkOption {
101 # since we are starting with systemd anyways
102 # we deviate from the default behavior here:
103 # journald will add timestamps, so no need
107 If enabled, spacecookie will not print timestamps
108 at the beginning of every log line.
120 Log level for the spacecookie service.
127 Settings for spacecookie. The settings set here are
128 directly translated to the spacecookie JSON config
130 [spacecookie.json(5)](https://sternenseemann.github.io/spacecookie/spacecookie.json.5.html)
131 for explanations of all options.
137 config = mkIf cfg.enable {
140 assertion = !(cfg.settings ? user);
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 = {
153 assertion = !(cfg.settings ? listen || cfg.settings ? port);
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.
162 systemd.sockets.spacecookie = {
163 description = "Socket for the Spacecookie Gopher Server";
164 wantedBy = [ "sockets.target" ];
165 listenStreams = [ "${cfg.address}:${toString cfg.port}" ];
167 BindIPv6Only = "both";
171 systemd.services.spacecookie = {
172 description = "Spacecookie Gopher Server";
173 wantedBy = [ "multi-user.target" ];
174 requires = [ "spacecookie.socket" ];
178 ExecStart = "${lib.getBin cfg.package}/bin/spacecookie ${configFile}";
179 FileDescriptorStoreMax = 1;
183 ProtectSystem = "strict";
186 PrivateDevices = true;
187 PrivateMounts = 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";
205 networking.firewall = mkIf cfg.openFirewall {
206 allowedTCPPorts = [ cfg.port ];