Merge #361424: refactor lib.packagesFromDirectoryRecursive (v2)
[NixPkgs.git] / nixos / modules / services / networking / jigasi.nix
blob54b2f36685f6a42350273b19b36d7fcb48d29912
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
7 let
8   cfg = config.services.jigasi;
9   homeDirName = "jigasi-home";
10   stateDir = "/tmp";
11   sipCommunicatorPropertiesFile = "${stateDir}/${homeDirName}/sip-communicator.properties";
12   sipCommunicatorPropertiesFileUnsubstituted = "${pkgs.jigasi}/etc/jitsi/jigasi/sip-communicator.properties";
15   options.services.jigasi = with lib.types; {
16     enable = lib.mkEnableOption "Jitsi Gateway to SIP - component of Jitsi Meet";
18     xmppHost = lib.mkOption {
19       type = str;
20       example = "localhost";
21       description = ''
22         Hostname of the XMPP server to connect to.
23       '';
24     };
26     xmppDomain = lib.mkOption {
27       type = nullOr str;
28       example = "meet.example.org";
29       description = ''
30         Domain name of the XMMP server to which to connect as a component.
32         If null, <option>xmppHost</option> is used.
33       '';
34     };
36     componentPasswordFile = lib.mkOption {
37       type = str;
38       example = "/run/keys/jigasi-component";
39       description = ''
40         Path to file containing component secret.
41       '';
42     };
44     userName = lib.mkOption {
45       type = str;
46       default = "callcontrol";
47       description = ''
48         User part of the JID for XMPP user connection.
49       '';
50     };
52     userDomain = lib.mkOption {
53       type = str;
54       example = "internal.meet.example.org";
55       description = ''
56         Domain part of the JID for XMPP user connection.
57       '';
58     };
60     userPasswordFile = lib.mkOption {
61       type = str;
62       example = "/run/keys/jigasi-user";
63       description = ''
64         Path to file containing password for XMPP user connection.
65       '';
66     };
68     bridgeMuc = lib.mkOption {
69       type = str;
70       example = "jigasibrewery@internal.meet.example.org";
71       description = ''
72         JID of the internal MUC used to communicate with Videobridges.
73       '';
74     };
76     defaultJvbRoomName = lib.mkOption {
77       type = str;
78       default = "";
79       example = "siptest";
80       description = ''
81         Name of the default JVB room that will be joined if no special header is included in SIP invite.
82       '';
83     };
85     environmentFile = lib.mkOption {
86       type = lib.types.nullOr lib.types.path;
87       default = null;
88       description = ''
89         File containing environment variables to be passed to the jigasi service,
90         in which secret tokens can be specified securely by defining values for
91         <literal>JIGASI_SIPUSER</literal>,
92         <literal>JIGASI_SIPPWD</literal>,
93         <literal>JIGASI_SIPSERVER</literal> and
94         <literal>JIGASI_SIPPORT</literal>.
95       '';
96     };
98     config = lib.mkOption {
99       type = attrsOf str;
100       default = { };
101       example = lib.literalExpression ''
102         {
103           "org.jitsi.jigasi.auth.URL" = "XMPP:jitsi-meet.example.com";
104         }
105       '';
106       description = ''
107         Contents of the <filename>sip-communicator.properties</filename> configuration file for jigasi.
108       '';
109     };
110   };
112   config = lib.mkIf cfg.enable {
113     services.jicofo.config = {
114       "org.jitsi.jicofo.jigasi.BREWERY" = "${cfg.bridgeMuc}";
115     };
117     services.jigasi.config = lib.mapAttrs (_: v: lib.mkDefault v) {
118       "org.jitsi.jigasi.BRIDGE_MUC" = cfg.bridgeMuc;
119     };
121     users.groups.jitsi-meet = { };
123     systemd.services.jigasi =
124       let
125         jigasiProps = {
126           "-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION" = "${stateDir}";
127           "-Dnet.java.sip.communicator.SC_HOME_DIR_NAME" = "${homeDirName}";
128           "-Djava.util.logging.config.file" = "${pkgs.jigasi}/etc/jitsi/jigasi/logging.properties";
129         };
130       in
131       {
132         description = "Jitsi Gateway to SIP";
133         wantedBy = [ "multi-user.target" ];
134         after = [ "network.target" ];
136         preStart = ''
137           [ -f "${sipCommunicatorPropertiesFile}" ] && rm -f "${sipCommunicatorPropertiesFile}"
138           mkdir -p "$(dirname ${sipCommunicatorPropertiesFile})"
139           temp="${sipCommunicatorPropertiesFile}.unsubstituted"
141           export DOMAIN_BASE="${cfg.xmppDomain}"
142           export JIGASI_XMPP_PASSWORD=$(cat "${cfg.userPasswordFile}")
143           export JIGASI_DEFAULT_JVB_ROOM_NAME="${cfg.defaultJvbRoomName}"
145           # encode the credentials to base64
146           export JIGASI_SIPPWD=$(echo -n "$JIGASI_SIPPWD" | base64 -w 0)
147           export JIGASI_XMPP_PASSWORD_BASE64=$(cat "${cfg.userPasswordFile}" | base64 -w 0)
149           cp "${sipCommunicatorPropertiesFileUnsubstituted}" "$temp"
150           chmod 644 "$temp"
151           cat <<EOF >>"$temp"
152           net.java.sip.communicator.impl.protocol.sip.acc1403273890647.SERVER_PORT=$JIGASI_SIPPORT
153           net.java.sip.communicator.impl.protocol.sip.acc1403273890647.PREFERRED_TRANSPORT=udp
154           EOF
155           chmod 444 "$temp"
157           # Replace <<$VAR_NAME>> from example config to $VAR_NAME for environment substitution
158           sed -i -E \
159             's/<<([^>]+)>>/\$\1/g' \
160             "$temp"
162           sed -i \
163             's|\(net\.java\.sip\.communicator\.impl\.protocol\.jabber\.acc-xmpp-1\.PASSWORD=\).*|\1\$JIGASI_XMPP_PASSWORD_BASE64|g' \
164             "$temp"
166           sed -i \
167             's|\(#\)\(org.jitsi.jigasi.DEFAULT_JVB_ROOM_NAME=\).*|\2\$JIGASI_DEFAULT_JVB_ROOM_NAME|g' \
168             "$temp"
170           ${pkgs.envsubst}/bin/envsubst \
171             -o "${sipCommunicatorPropertiesFile}" \
172             -i "$temp"
174           # Set the brewery room name
175           sed -i \
176             's|\(net\.java\.sip\.communicator\.impl\.protocol\.jabber\.acc-xmpp-1\.BREWERY=\).*|\1${cfg.bridgeMuc}|g' \
177             "${sipCommunicatorPropertiesFile}"
178           sed -i \
179             's|\(org\.jitsi\.jigasi\.ALLOWED_JID=\).*|\1${cfg.bridgeMuc}|g' \
180             "${sipCommunicatorPropertiesFile}"
183           # Disable certificate verification for self-signed certificates
184           sed -i \
185             's|\(# \)\(net.java.sip.communicator.service.gui.ALWAYS_TRUST_MODE_ENABLED=true\)|\2|g' \
186             "${sipCommunicatorPropertiesFile}"
187         '';
189         restartTriggers = [
190           config.environment.etc."jitsi/jigasi/sip-communicator.properties".source
191         ];
192         environment.JAVA_SYS_PROPS = lib.concatStringsSep " " (
193           lib.mapAttrsToList (k: v: "${k}=${toString v}") jigasiProps
194         );
196         script = ''
197           ${pkgs.jigasi}/bin/jigasi \
198             --host="${cfg.xmppHost}" \
199             --domain="${if cfg.xmppDomain == null then cfg.xmppHost else cfg.xmppDomain}" \
200             --secret="$(cat ${cfg.componentPasswordFile})" \
201             --user_name="${cfg.userName}" \
202             --user_domain="${cfg.userDomain}" \
203             --user_password="$(cat ${cfg.userPasswordFile})" \
204             --configdir="${stateDir}" \
205             --configdirname="${homeDirName}"
206         '';
208         serviceConfig = {
209           Type = "exec";
211           DynamicUser = true;
212           User = "jigasi";
213           Group = "jitsi-meet";
215           CapabilityBoundingSet = "";
216           NoNewPrivileges = true;
217           ProtectSystem = "strict";
218           ProtectHome = true;
219           PrivateTmp = true;
220           PrivateDevices = true;
221           ProtectHostname = true;
222           ProtectKernelTunables = true;
223           ProtectKernelModules = true;
224           ProtectControlGroups = true;
225           RestrictAddressFamilies = [
226             "AF_INET"
227             "AF_INET6"
228             "AF_UNIX"
229           ];
230           RestrictNamespaces = true;
231           LockPersonality = true;
232           RestrictRealtime = true;
233           RestrictSUIDSGID = true;
234           StateDirectory = baseNameOf stateDir;
235           EnvironmentFile = cfg.environmentFile;
236         };
237       };
239     environment.etc."jitsi/jigasi/sip-communicator.properties".source = lib.mkDefault "${
240       sipCommunicatorPropertiesFile
241     }";
242     environment.etc."jitsi/jigasi/logging.properties".source =
243       lib.mkDefault "${stateDir}/logging.properties-journal";
244   };
246   meta.maintainers = lib.teams.jitsi.members;