at 25.11-pre 8.0 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 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"; 13in 14{ 15 options.services.jigasi = with lib.types; { 16 enable = lib.mkEnableOption "Jitsi Gateway to SIP - component of Jitsi Meet"; 17 18 xmppHost = lib.mkOption { 19 type = str; 20 example = "localhost"; 21 description = '' 22 Hostname of the XMPP server to connect to. 23 ''; 24 }; 25 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. 31 32 If null, <option>xmppHost</option> is used. 33 ''; 34 }; 35 36 componentPasswordFile = lib.mkOption { 37 type = str; 38 example = "/run/keys/jigasi-component"; 39 description = '' 40 Path to file containing component secret. 41 ''; 42 }; 43 44 userName = lib.mkOption { 45 type = str; 46 default = "callcontrol"; 47 description = '' 48 User part of the JID for XMPP user connection. 49 ''; 50 }; 51 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 }; 59 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 }; 67 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 }; 75 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 }; 84 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 }; 97 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 }; 111 112 config = lib.mkIf cfg.enable { 113 services.jicofo.config = { 114 "org.jitsi.jicofo.jigasi.BREWERY" = "${cfg.bridgeMuc}"; 115 }; 116 117 services.jigasi.config = lib.mapAttrs (_: v: lib.mkDefault v) { 118 "org.jitsi.jigasi.BRIDGE_MUC" = cfg.bridgeMuc; 119 }; 120 121 users.groups.jitsi-meet = { }; 122 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" ]; 135 136 preStart = '' 137 [ -f "${sipCommunicatorPropertiesFile}" ] && rm -f "${sipCommunicatorPropertiesFile}" 138 mkdir -p "$(dirname ${sipCommunicatorPropertiesFile})" 139 temp="${sipCommunicatorPropertiesFile}.unsubstituted" 140 141 export DOMAIN_BASE="${cfg.xmppDomain}" 142 export JIGASI_XMPP_PASSWORD=$(cat "${cfg.userPasswordFile}") 143 export JIGASI_DEFAULT_JVB_ROOM_NAME="${cfg.defaultJvbRoomName}" 144 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) 148 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" 156 157 # Replace <<$VAR_NAME>> from example config to $VAR_NAME for environment substitution 158 sed -i -E \ 159 's/<<([^>]+)>>/\$\1/g' \ 160 "$temp" 161 162 sed -i \ 163 's|\(net\.java\.sip\.communicator\.impl\.protocol\.jabber\.acc-xmpp-1\.PASSWORD=\).*|\1\$JIGASI_XMPP_PASSWORD_BASE64|g' \ 164 "$temp" 165 166 sed -i \ 167 's|\(#\)\(org.jitsi.jigasi.DEFAULT_JVB_ROOM_NAME=\).*|\2\$JIGASI_DEFAULT_JVB_ROOM_NAME|g' \ 168 "$temp" 169 170 ${pkgs.envsubst}/bin/envsubst \ 171 -o "${sipCommunicatorPropertiesFile}" \ 172 -i "$temp" 173 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}" 181 182 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 ''; 188 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 ); 195 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 ''; 207 208 serviceConfig = { 209 Type = "exec"; 210 211 DynamicUser = true; 212 User = "jigasi"; 213 Group = "jitsi-meet"; 214 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 }; 238 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 }; 245 246 meta.maintainers = lib.teams.jitsi.members; 247}