234 lines
7.5 KiB
Nix
234 lines
7.5 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
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 lib.types; {
|
|
enable = lib.mkEnableOption "Jitsi Gateway to SIP - component of Jitsi Meet";
|
|
|
|
xmppHost = lib.mkOption {
|
|
type = str;
|
|
example = "localhost";
|
|
description = ''
|
|
Hostname of the XMPP server to connect to.
|
|
'';
|
|
};
|
|
|
|
xmppDomain = lib.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 = lib.mkOption {
|
|
type = str;
|
|
example = "/run/keys/jigasi-component";
|
|
description = ''
|
|
Path to file containing component secret.
|
|
'';
|
|
};
|
|
|
|
userName = lib.mkOption {
|
|
type = str;
|
|
default = "callcontrol";
|
|
description = ''
|
|
User part of the JID for XMPP user connection.
|
|
'';
|
|
};
|
|
|
|
userDomain = lib.mkOption {
|
|
type = str;
|
|
example = "internal.meet.example.org";
|
|
description = ''
|
|
Domain part of the JID for XMPP user connection.
|
|
'';
|
|
};
|
|
|
|
userPasswordFile = lib.mkOption {
|
|
type = str;
|
|
example = "/run/keys/jigasi-user";
|
|
description = ''
|
|
Path to file containing password for XMPP user connection.
|
|
'';
|
|
};
|
|
|
|
bridgeMuc = lib.mkOption {
|
|
type = str;
|
|
example = "jigasibrewery@internal.meet.example.org";
|
|
description = ''
|
|
JID of the internal MUC used to communicate with Videobridges.
|
|
'';
|
|
};
|
|
|
|
defaultJvbRoomName = lib.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 = lib.mkOption {
|
|
type = lib.types.nullOr lib.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 = lib.mkOption {
|
|
type = attrsOf str;
|
|
default = { };
|
|
example = lib.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 = lib.mkIf cfg.enable {
|
|
services.jicofo.config = {
|
|
"org.jitsi.jicofo.jigasi.BREWERY" = "${cfg.bridgeMuc}";
|
|
};
|
|
|
|
services.jigasi.config = lib.mapAttrs (_: v: lib.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 = lib.concatStringsSep " " (lib.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 =
|
|
lib.mkDefault "${sipCommunicatorPropertiesFile}";
|
|
environment.etc."jitsi/jigasi/logging.properties".source =
|
|
lib.mkDefault "${stateDir}/logging.properties-journal";
|
|
};
|
|
|
|
meta.maintainers = lib.teams.jitsi.members;
|
|
}
|