diff options
Diffstat (limited to 'nixpkgs/nixos/modules/services/networking/jigasi.nix')
-rw-r--r-- | nixpkgs/nixos/modules/services/networking/jigasi.nix | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/networking/jigasi.nix b/nixpkgs/nixos/modules/services/networking/jigasi.nix new file mode 100644 index 000000000000..e701689031b1 --- /dev/null +++ b/nixpkgs/nixos/modules/services/networking/jigasi.nix @@ -0,0 +1,237 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.jigasi; + homeDirName = "jigasi-home"; + stateDir = "/tmp"; + sipCommunicatorPropertiesFile = "${stateDir}/${homeDirName}/sip-communicator.properties"; + sipCommunicatorPropertiesFileUnsubstituted = "${pkgs.jigasi}/etc/jitsi/jigasi/sip-communicator.properties"; +in +{ + options.services.jigasi = with types; { + enable = mkEnableOption "Jitsi Gateway to SIP - component of Jitsi Meet"; + + xmppHost = mkOption { + type = str; + example = "localhost"; + description = '' + Hostname of the XMPP server to connect to. + ''; + }; + + xmppDomain = mkOption { + type = nullOr str; + example = "meet.example.org"; + description = '' + Domain name of the XMMP server to which to connect as a component. + + If null, <option>xmppHost</option> is used. + ''; + }; + + componentPasswordFile = mkOption { + type = str; + example = "/run/keys/jigasi-component"; + description = '' + Path to file containing component secret. + ''; + }; + + userName = mkOption { + type = str; + default = "callcontrol"; + description = '' + User part of the JID for XMPP user connection. + ''; + }; + + userDomain = mkOption { + type = str; + example = "internal.meet.example.org"; + description = '' + Domain part of the JID for XMPP user connection. + ''; + }; + + userPasswordFile = mkOption { + type = str; + example = "/run/keys/jigasi-user"; + description = '' + Path to file containing password for XMPP user connection. + ''; + }; + + bridgeMuc = mkOption { + type = str; + example = "jigasibrewery@internal.meet.example.org"; + description = '' + JID of the internal MUC used to communicate with Videobridges. + ''; + }; + + defaultJvbRoomName = mkOption { + type = str; + default = ""; + example = "siptest"; + description = '' + Name of the default JVB room that will be joined if no special header is included in SIP invite. + ''; + }; + + environmentFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + File containing environment variables to be passed to the jigasi service, + in which secret tokens can be specified securely by defining values for + <literal>JIGASI_SIPUSER</literal>, + <literal>JIGASI_SIPPWD</literal>, + <literal>JIGASI_SIPSERVER</literal> and + <literal>JIGASI_SIPPORT</literal>. + ''; + }; + + config = mkOption { + type = attrsOf str; + default = { }; + example = literalExpression '' + { + "org.jitsi.jigasi.auth.URL" = "XMPP:jitsi-meet.example.com"; + } + ''; + description = '' + Contents of the <filename>sip-communicator.properties</filename> configuration file for jigasi. + ''; + }; + }; + + config = mkIf cfg.enable { + services.jicofo.config = { + "org.jitsi.jicofo.jigasi.BREWERY" = "${cfg.bridgeMuc}"; + }; + + services.jigasi.config = mapAttrs (_: v: mkDefault v) { + "org.jitsi.jigasi.BRIDGE_MUC" = cfg.bridgeMuc; + }; + + users.groups.jitsi-meet = {}; + + systemd.services.jigasi = let + jigasiProps = { + "-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION" = "${stateDir}"; + "-Dnet.java.sip.communicator.SC_HOME_DIR_NAME" = "${homeDirName}"; + "-Djava.util.logging.config.file" = "${pkgs.jigasi}/etc/jitsi/jigasi/logging.properties"; + }; + in + { + description = "Jitsi Gateway to SIP"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + preStart = '' + [ -f "${sipCommunicatorPropertiesFile}" ] && rm -f "${sipCommunicatorPropertiesFile}" + mkdir -p "$(dirname ${sipCommunicatorPropertiesFile})" + temp="${sipCommunicatorPropertiesFile}.unsubstituted" + + export DOMAIN_BASE="${cfg.xmppDomain}" + export JIGASI_XMPP_PASSWORD=$(cat "${cfg.userPasswordFile}") + export JIGASI_DEFAULT_JVB_ROOM_NAME="${cfg.defaultJvbRoomName}" + + # encode the credentials to base64 + export JIGASI_SIPPWD=$(echo -n "$JIGASI_SIPPWD" | base64 -w 0) + export JIGASI_XMPP_PASSWORD_BASE64=$(cat "${cfg.userPasswordFile}" | base64 -w 0) + + cp "${sipCommunicatorPropertiesFileUnsubstituted}" "$temp" + chmod 644 "$temp" + cat <<EOF >>"$temp" + net.java.sip.communicator.impl.protocol.sip.acc1403273890647.SERVER_PORT=$JIGASI_SIPPORT + net.java.sip.communicator.impl.protocol.sip.acc1403273890647.PREFERRED_TRANSPORT=udp + EOF + chmod 444 "$temp" + + # Replace <<$VAR_NAME>> from example config to $VAR_NAME for environment substitution + sed -i -E \ + 's/<<([^>]+)>>/\$\1/g' \ + "$temp" + + sed -i \ + 's|\(net\.java\.sip\.communicator\.impl\.protocol\.jabber\.acc-xmpp-1\.PASSWORD=\).*|\1\$JIGASI_XMPP_PASSWORD_BASE64|g' \ + "$temp" + + sed -i \ + 's|\(#\)\(org.jitsi.jigasi.DEFAULT_JVB_ROOM_NAME=\).*|\2\$JIGASI_DEFAULT_JVB_ROOM_NAME|g' \ + "$temp" + + ${pkgs.envsubst}/bin/envsubst \ + -o "${sipCommunicatorPropertiesFile}" \ + -i "$temp" + + # Set the brewery room name + sed -i \ + 's|\(net\.java\.sip\.communicator\.impl\.protocol\.jabber\.acc-xmpp-1\.BREWERY=\).*|\1${cfg.bridgeMuc}|g' \ + "${sipCommunicatorPropertiesFile}" + sed -i \ + 's|\(org\.jitsi\.jigasi\.ALLOWED_JID=\).*|\1${cfg.bridgeMuc}|g' \ + "${sipCommunicatorPropertiesFile}" + + + # Disable certificate verification for self-signed certificates + sed -i \ + 's|\(# \)\(net.java.sip.communicator.service.gui.ALWAYS_TRUST_MODE_ENABLED=true\)|\2|g' \ + "${sipCommunicatorPropertiesFile}" + ''; + + restartTriggers = [ + config.environment.etc."jitsi/jigasi/sip-communicator.properties".source + ]; + environment.JAVA_SYS_PROPS = concatStringsSep " " (mapAttrsToList (k: v: "${k}=${toString v}") jigasiProps); + + script = '' + ${pkgs.jigasi}/bin/jigasi \ + --host="${cfg.xmppHost}" \ + --domain="${if cfg.xmppDomain == null then cfg.xmppHost else cfg.xmppDomain}" \ + --secret="$(cat ${cfg.componentPasswordFile})" \ + --user_name="${cfg.userName}" \ + --user_domain="${cfg.userDomain}" \ + --user_password="$(cat ${cfg.userPasswordFile})" \ + --configdir="${stateDir}" \ + --configdirname="${homeDirName}" + ''; + + serviceConfig = { + Type = "exec"; + + DynamicUser = true; + User = "jigasi"; + Group = "jitsi-meet"; + + CapabilityBoundingSet = ""; + NoNewPrivileges = true; + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + ProtectHostname = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; + RestrictNamespaces = true; + LockPersonality = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + StateDirectory = baseNameOf stateDir; + EnvironmentFile = cfg.environmentFile; + }; + }; + + environment.etc."jitsi/jigasi/sip-communicator.properties".source = + mkDefault "${sipCommunicatorPropertiesFile}"; + environment.etc."jitsi/jigasi/logging.properties".source = + mkDefault "${stateDir}/logging.properties-journal"; + }; + + meta.maintainers = lib.teams.jitsi.members; +} |