python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / nixos / modules / services / networking / biboumi.nix
blob896a2350e3d55619d3b958c9699fda8ccf9063f4
1 { config, lib, pkgs, options, ... }:
2 with lib;
3 let
4   cfg = config.services.biboumi;
5   inherit (config.environment) etc;
6   rootDir = "/run/biboumi/mnt-root";
7   stateDir = "/var/lib/biboumi";
8   settingsFile = pkgs.writeText "biboumi.cfg" (
9     generators.toKeyValue {
10       mkKeyValue = k: v:
11         if v == null then ""
12         else generators.mkKeyValueDefault {} "=" k v;
13     } cfg.settings);
14   need_CAP_NET_BIND_SERVICE = cfg.settings.identd_port != 0 && cfg.settings.identd_port < 1024;
17   options = {
18     services.biboumi = {
19       enable = mkEnableOption (lib.mdDoc "the Biboumi XMPP gateway to IRC");
21       settings = mkOption {
22         description = lib.mdDoc ''
23           See [biboumi 8.5](https://lab.louiz.org/louiz/biboumi/blob/8.5/doc/biboumi.1.rst)
24           for documentation.
25         '';
26         default = {};
27         type = types.submodule {
28           freeformType = with types;
29             (attrsOf (nullOr (oneOf [str int bool]))) // {
30               description = "settings option";
31             };
32           options.admin = mkOption {
33             type = with types; listOf str;
34             default = [];
35             example = ["admin@example.org"];
36             apply = concatStringsSep ":";
37             description = lib.mdDoc ''
38               The bare JID of the gateway administrator. This JID will have more
39               privileges than other standard users, for example some administration
40               ad-hoc commands will only be available to that JID.
41             '';
42           };
43           options.ca_file = mkOption {
44             type = types.path;
45             default = "/etc/ssl/certs/ca-certificates.crt";
46             description = lib.mdDoc ''
47               Specifies which file should be used as the list of trusted CA
48               when negociating a TLS session.
49             '';
50           };
51           options.db_name = mkOption {
52             type = with types; either path str;
53             default = "${stateDir}/biboumi.sqlite";
54             description = lib.mdDoc ''
55               The name of the database to use.
56             '';
57             example = "postgresql://user:secret@localhost";
58           };
59           options.hostname = mkOption {
60             type = types.str;
61             example = "biboumi.example.org";
62             description = lib.mdDoc ''
63               The hostname served by the XMPP gateway.
64               This domain must be configured in the XMPP server
65               as an external component.
66             '';
67           };
68           options.identd_port = mkOption {
69             type = types.port;
70             default = 113;
71             example = 0;
72             description = lib.mdDoc ''
73               The TCP port on which to listen for identd queries.
74             '';
75           };
76           options.log_level = mkOption {
77             type = types.ints.between 0 3;
78             default = 1;
79             description = lib.mdDoc ''
80               Indicate what type of log messages to write in the logs.
81               0 is debug, 1 is info, 2 is warning, 3 is error.
82             '';
83           };
84           options.password = mkOption {
85             type = with types; nullOr str;
86             description = lib.mdDoc ''
87               The password used to authenticate the XMPP component to your XMPP server.
88               This password must be configured in the XMPP server,
89               associated with the external component on
90               [hostname](#opt-services.biboumi.settings.hostname).
92               Set it to null and use [credentialsFile](#opt-services.biboumi.credentialsFile)
93               if you do not want this password to go into the Nix store.
94             '';
95           };
96           options.persistent_by_default = mkOption {
97             type = types.bool;
98             default = false;
99             description = lib.mdDoc ''
100               Whether all rooms will be persistent by default:
101               the value of the “persistent” option in the global configuration of each
102               user will be “true”, but the value of each individual room will still
103               default to false. This means that a user just needs to change the global
104               “persistent” configuration option to false in order to override this.
105             '';
106           };
107           options.policy_directory = mkOption {
108             type = types.path;
109             default = "${pkgs.biboumi}/etc/biboumi";
110             defaultText = literalExpression ''"''${pkgs.biboumi}/etc/biboumi"'';
111             description = lib.mdDoc ''
112               A directory that should contain the policy files,
113               used to customize Botan’s behaviour
114               when negociating the TLS connections with the IRC servers.
115             '';
116           };
117           options.port = mkOption {
118             type = types.port;
119             default = 5347;
120             description = lib.mdDoc ''
121               The TCP port to use to connect to the local XMPP component.
122             '';
123           };
124           options.realname_customization = mkOption {
125             type = types.bool;
126             default = true;
127             description = lib.mdDoc ''
128               Whether the users will be able to use
129               the ad-hoc commands that lets them configure
130               their realname and username.
131             '';
132           };
133           options.realname_from_jid = mkOption {
134             type = types.bool;
135             default = false;
136             description = lib.mdDoc ''
137               Whether the realname and username of each biboumi
138               user will be extracted from their JID.
139               Otherwise they will be set to the nick
140               they used to connect to the IRC server.
141             '';
142           };
143           options.xmpp_server_ip = mkOption {
144             type = types.str;
145             default = "127.0.0.1";
146             description = lib.mdDoc ''
147               The IP address to connect to the XMPP server on.
148               The connection to the XMPP server is unencrypted,
149               so the biboumi instance and the server should
150               normally be on the same host.
151             '';
152           };
153         };
154       };
156       credentialsFile = mkOption {
157         type = types.path;
158         description = lib.mdDoc ''
159           Path to a configuration file to be merged with the settings.
160           Beware not to surround "=" with spaces when setting biboumi's options in this file.
161           Useful to merge a file which is better kept out of the Nix store
162           because it contains sensible data like
163           [password](#opt-services.biboumi.settings.password).
164         '';
165         default = "/dev/null";
166         example = "/run/keys/biboumi.cfg";
167       };
169       openFirewall = mkEnableOption (lib.mdDoc "opening of the identd port in the firewall");
170     };
171   };
173   config = mkIf cfg.enable {
174     networking.firewall = mkIf (cfg.openFirewall && cfg.settings.identd_port != 0)
175       { allowedTCPPorts = [ cfg.settings.identd_port ]; };
177     systemd.services.biboumi = {
178       description = "Biboumi, XMPP to IRC gateway";
179       after = [ "network.target" ];
180       wantedBy = [ "multi-user.target" ];
182       serviceConfig = {
183         Type = "notify";
184         # Biboumi supports systemd's watchdog.
185         WatchdogSec = 20;
186         Restart = "always";
187         # Use "+" because credentialsFile may not be accessible to User= or Group=.
188         ExecStartPre = [("+" + pkgs.writeShellScript "biboumi-prestart" ''
189           set -eux
190           cat ${settingsFile} '${cfg.credentialsFile}' |
191           install -m 644 /dev/stdin /run/biboumi/biboumi.cfg
192         '')];
193         ExecStart = "${pkgs.biboumi}/bin/biboumi /run/biboumi/biboumi.cfg";
194         ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
195         # Firewalls needing opening for output connections can still do that
196         # selectively for biboumi with:
197         # users.users.biboumi.isSystemUser = true;
198         # and, for example:
199         # networking.nftables.ruleset = ''
200         #   add rule inet filter output meta skuid biboumi tcp accept
201         # '';
202         DynamicUser = true;
203         RootDirectory = rootDir;
204         RootDirectoryStartOnly = true;
205         InaccessiblePaths = [ "-+${rootDir}" ];
206         RuntimeDirectory = [ "biboumi" (removePrefix "/run/" rootDir) ];
207         RuntimeDirectoryMode = "700";
208         StateDirectory = "biboumi";
209         StateDirectoryMode = "700";
210         MountAPIVFS = true;
211         UMask = "0066";
212         BindPaths = [
213           stateDir
214           # This is for Type="notify"
215           # See https://github.com/systemd/systemd/issues/3544
216           "/run/systemd/notify"
217           "/run/systemd/journal/socket"
218         ];
219         BindReadOnlyPaths = [
220           builtins.storeDir
221           "/etc"
222         ];
223         # The following options are only for optimizing:
224         # systemd-analyze security biboumi
225         AmbientCapabilities = [ (optionalString need_CAP_NET_BIND_SERVICE "CAP_NET_BIND_SERVICE") ];
226         CapabilityBoundingSet = [ (optionalString need_CAP_NET_BIND_SERVICE "CAP_NET_BIND_SERVICE") ];
227         # ProtectClock= adds DeviceAllow=char-rtc r
228         DeviceAllow = "";
229         LockPersonality = true;
230         MemoryDenyWriteExecute = true;
231         NoNewPrivileges = true;
232         PrivateDevices = true;
233         PrivateMounts = true;
234         PrivateNetwork = mkDefault false;
235         PrivateTmp = true;
236         # PrivateUsers=true breaks AmbientCapabilities=CAP_NET_BIND_SERVICE
237         # See https://bugs.archlinux.org/task/65921
238         PrivateUsers = !need_CAP_NET_BIND_SERVICE;
239         ProtectClock = true;
240         ProtectControlGroups = true;
241         ProtectHome = true;
242         ProtectHostname = true;
243         ProtectKernelLogs = true;
244         ProtectKernelModules = true;
245         ProtectKernelTunables = true;
246         ProtectSystem = "strict";
247         RemoveIPC = true;
248         # AF_UNIX is for /run/systemd/notify
249         RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
250         RestrictNamespaces = true;
251         RestrictRealtime = true;
252         RestrictSUIDSGID = true;
253         SystemCallFilter = [
254           "@system-service"
255           # Groups in @system-service which do not contain a syscall
256           # listed by perf stat -e 'syscalls:sys_enter_*' biboumi biboumi.cfg
257           # in tests, and seem likely not necessary for biboumi.
258           # To run such a perf in ExecStart=, you have to:
259           # - AmbientCapabilities="CAP_SYS_ADMIN"
260           # - mount -o remount,mode=755 /sys/kernel/debug/{,tracing}
261           "~@aio" "~@chown" "~@ipc" "~@keyring" "~@resources" "~@setuid" "~@timer"
262         ];
263         SystemCallArchitectures = "native";
264         SystemCallErrorNumber = "EPERM";
265       };
266     };
267   };
269   meta.maintainers = with maintainers; [ julm ];