Introduces installing coturn as turn server for jitsi-meet (#4959)
* Adds package that can configure using turnserver for jitsi-meet. Activates http2 on the nginx host and uses the alpn send with the web requests to multiplex traffic to be served as web of proxied to the turn server. It needs nginx at least v1.13.10. Adds turncredentials module from Philipp Hancke, with small modification (all int values for hosts need to be strings/tostring()) in order to be able to use the module with prosody 0.11. * Moves loading of stream after loading stream module (50-..). * Leaves DISABLE_TCP_HARVESTER to be handled by jvb. * Fixes comments. * Properly detect first time coturn install and configure it. * Handles upgrading from jetty serving web. * Does not create jvb user if already exists. * Fixes let's encrypt and adds turnserver handling. * Enables use of turn server in config.js if available. * Adds a check whether prosody config exists. There are cases where deployments can still have configured prosody in the main prosody config in /etc/prosody.
This commit is contained in:
parent
659eb6b789
commit
c73ba37202
|
@ -329,6 +329,8 @@ var config = {
|
|||
|
||||
// The STUN servers that will be used in the peer to peer connections
|
||||
stunServers: [
|
||||
|
||||
// { urls: 'stun:jitsi-meet.example.com:443' },
|
||||
{ urls: 'stun:stun.l.google.com:19302' },
|
||||
{ urls: 'stun:stun1.l.google.com:19302' },
|
||||
{ urls: 'stun:stun2.l.google.com:19302' }
|
||||
|
|
|
@ -21,7 +21,7 @@ Description: WebRTC JavaScript video conferences
|
|||
|
||||
Package: jitsi-meet-web-config
|
||||
Architecture: all
|
||||
Depends: openssl, nginx | nginx-extras | apache2
|
||||
Depends: openssl, nginx | nginx-full | nginx-extras | apache2
|
||||
Description: Configuration for web serving of Jitsi Meet
|
||||
Jitsi Meet is a WebRTC JavaScript application that uses Jitsi
|
||||
Videobridge to provide high quality, scalable video conferences.
|
||||
|
@ -54,3 +54,7 @@ Architecture: all
|
|||
Depends: ${misc:Depends}, prosody-trunk (>= 1nightly747) | prosody-0.11 | prosody (>= 0.11.2), libssl-dev, luarocks, jitsi-meet-prosody
|
||||
Description: Prosody token authentication plugin for Jitsi Meet
|
||||
|
||||
Package: jitsi-meet-turnserver
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, nginx (>= 1.13.10) | nginx-full (>= 1.13.10) | nginx-extras (>= 1.13.10), jitsi-meet-prosody, coturn, dnsutils
|
||||
Description: Configures coturn to be used with Jitsi Meet
|
||||
|
|
|
@ -80,6 +80,15 @@ case "$1" in
|
|||
# stores the hostname so we will reuse it later, like in purge
|
||||
db_set jitsi-meet-prosody/jvb-hostname "$JVB_HOSTNAME"
|
||||
|
||||
db_get jitsi-meet-prosody/turn-secret
|
||||
if [ -z "$RET" ] ; then
|
||||
# 8-chars random secret used for the turnserver
|
||||
TURN_SECRET=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1`
|
||||
db_set jitsi-meet-prosody/turn-secret "$TURN_SECRET"
|
||||
else
|
||||
TURN_SECRET="$RET"
|
||||
fi
|
||||
|
||||
# and we're done with debconf
|
||||
db_stop
|
||||
|
||||
|
@ -97,6 +106,7 @@ case "$1" in
|
|||
sed -i "s/jitmeet.example.com/$JVB_HOSTNAME/g" $PROSODY_HOST_CONFIG
|
||||
sed -i "s/focusSecret/$JICOFO_SECRET/g" $PROSODY_HOST_CONFIG
|
||||
sed -i "s/focusUser/$JICOFO_AUTH_USER/g" $PROSODY_HOST_CONFIG
|
||||
sed -i "s/__turnSecret__/$TURN_SECRET/g" $PROSODY_HOST_CONFIG
|
||||
if [ ! -f /etc/prosody/conf.d/$JVB_HOSTNAME.cfg.lua ]; then
|
||||
ln -s $PROSODY_HOST_CONFIG /etc/prosody/conf.d/$JVB_HOSTNAME.cfg.lua
|
||||
fi
|
||||
|
@ -115,12 +125,14 @@ case "$1" in
|
|||
PROSODY_CONFIG_PRESENT="false"
|
||||
fi
|
||||
|
||||
# we always try to create the user 'jvb' and not fail configure if user exists
|
||||
prosodyctl register jvb $JICOFO_AUTH_DOMAIN $JVB_SECRET || true
|
||||
USER_EXISTS_CHECK=`prosodyctl adduser jvb@$JICOFO_AUTH_DOMAIN < /dev/null || true`
|
||||
if [ ! "$USER_EXISTS_CHECK" = "That user already exists" ]; then
|
||||
prosodyctl register jvb $JICOFO_AUTH_DOMAIN $JVB_SECRET || true
|
||||
fi
|
||||
|
||||
# Check whether prosody config has the internal muc, if not add it,
|
||||
# as we are migrating configs
|
||||
if ! grep -q "internal.auth.$JVB_HOSTNAME" $PROSODY_HOST_CONFIG; then
|
||||
if [ -f $PROSODY_HOST_CONFIG ] && ! grep -q "internal.auth.$JVB_HOSTNAME" $PROSODY_HOST_CONFIG; then
|
||||
echo -e "\nComponent \"internal.auth.$JVB_HOSTNAME\" \"muc\"" >> $PROSODY_HOST_CONFIG
|
||||
echo -e " storage = \"null\"" >> $PROSODY_HOST_CONFIG
|
||||
echo -e " modules_enabled = { \"ping\"; }" >> $PROSODY_HOST_CONFIG
|
||||
|
|
|
@ -28,3 +28,8 @@ Template: jicofo/jicofosecret
|
|||
Type: password
|
||||
_Description: Jicofo Component secret:
|
||||
The secret used to connect to xmpp server as component
|
||||
|
||||
Template: jitsi-meet-prosody/turn-secret
|
||||
Type: string
|
||||
_Description: The turn server secret
|
||||
The secret used to connect to turnserver server.
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
doc/debian/jitsi-meet-turn/turnserver.conf /usr/share/jitsi-meet-turnserver/
|
||||
doc/debian/jitsi-meet/jitsi-meet.conf /usr/share/jitsi-meet-turnserver/
|
|
@ -0,0 +1 @@
|
|||
/usr/share/jitsi-meet-turnserver/jitsi-meet.conf /etc/nginx/modules-enabled/60-jitsi-meet.conf
|
|
@ -0,0 +1,127 @@
|
|||
#!/bin/bash
|
||||
# postinst script for jitsi-meet-turnserver
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <postinst> `configure' <most-recently-configured-version>
|
||||
# * <old-postinst> `abort-upgrade' <new version>
|
||||
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
|
||||
# <new-version>
|
||||
# * <postinst> `abort-remove'
|
||||
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
|
||||
# <failed-install-package> <version> `removing'
|
||||
# <conflicting-package> <version>
|
||||
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
# loading debconf
|
||||
. /usr/share/debconf/confmodule
|
||||
|
||||
# try to get host from jitsi-videobridge
|
||||
db_get jitsi-videobridge/jvb-hostname
|
||||
if [ -z "$RET" ] ; then
|
||||
# server hostname
|
||||
db_set jitsi-videobridge/jvb-hostname "localhost"
|
||||
db_input critical jitsi-videobridge/jvb-hostname || true
|
||||
db_go
|
||||
fi
|
||||
JVB_HOSTNAME="$RET"
|
||||
|
||||
TURN_CONFIG="/etc/turnserver.conf"
|
||||
NGINX_CONFIG="/etc/nginx/sites-available/$JVB_HOSTNAME.conf"
|
||||
JITSI_MEET_CONFIG="/etc/jitsi/meet/$JVB_HOSTNAME-config.js"
|
||||
|
||||
# detect dpkg-reconfigure, just delete old links
|
||||
db_get jitsi-meet-turnserver/jvb-hostname
|
||||
JVB_HOSTNAME_OLD=$RET
|
||||
if [ -n "$RET" ] && [ ! "$JVB_HOSTNAME_OLD" = "$JVB_HOSTNAME" ] ; then
|
||||
rm -f $TURN_CONFIG
|
||||
fi
|
||||
|
||||
# this detect only old installations with no nginx
|
||||
db_get jitsi-meet/jvb-serve || true
|
||||
if [ ! -f $NGINX_CONFIG -o "$RET" = "true" ] ; then
|
||||
# nothing to do
|
||||
echo ""
|
||||
echo "turnserver not configured as no nginx found to multiplex traffic"
|
||||
echo ""
|
||||
db_stop
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# stores the hostname so we will reuse it later, like in purge
|
||||
db_set jitsi-meet-turnserver/jvb-hostname "$JVB_HOSTNAME"
|
||||
|
||||
# try to get turnserver password
|
||||
db_get jitsi-meet-prosody/turn-secret
|
||||
if [ -z "$RET" ] ; then
|
||||
db_input critical jitsi-meet-prosody/turn-secret || true
|
||||
db_go
|
||||
fi
|
||||
TURN_SECRET="$RET"
|
||||
|
||||
if [[ -f $TURN_CONFIG ]] && ! grep -q "jitsi-meet coturn config" "$TURN_CONFIG" ; then
|
||||
PUBLIC_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
|
||||
cp /usr/share/jitsi-meet-turnserver/turnserver.conf $TURN_CONFIG
|
||||
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" $TURN_CONFIG
|
||||
sed -i "s/__turnSecret__/$TURN_SECRET/g" $TURN_CONFIG
|
||||
sed -i "s/__external_ip_address__/$JVB_HOSTNAME/g" $TURN_CONFIG
|
||||
|
||||
# SSL for nginx
|
||||
db_get jitsi-meet/cert-choice
|
||||
CERT_CHOICE="$RET"
|
||||
|
||||
if [ "$CERT_CHOICE" = "I want to use my own certificate" ] ; then
|
||||
db_get jitsi-meet/cert-path-key
|
||||
CERT_KEY="$RET"
|
||||
db_get jitsi-meet/cert-path-crt
|
||||
CERT_CRT="$RET"
|
||||
|
||||
# replace self-signed certificate paths with user provided ones
|
||||
CERT_KEY_ESC=$(echo $CERT_KEY | sed 's/\./\\\./g')
|
||||
CERT_KEY_ESC=$(echo $CERT_KEY_ESC | sed 's/\//\\\//g')
|
||||
sed -i "s/pkey=\/etc\/jitsi\/meet\/.*key/pkey=$CERT_KEY_ESC/g" $TURN_CONFIG
|
||||
CERT_CRT_ESC=$(echo $CERT_CRT | sed 's/\./\\\./g')
|
||||
CERT_CRT_ESC=$(echo $CERT_CRT_ESC | sed 's/\//\\\//g')
|
||||
sed -i "s/cert=\/etc\/jitsi\/meet\/.*crt/cert=$CERT_CRT_ESC/g" $TURN_CONFIG
|
||||
fi
|
||||
|
||||
sed -i "s/#TURNSERVER_ENABLED/TURNSERVER_ENABLED/g" /etc/default/coturn
|
||||
invoke-rc.d coturn restart || true
|
||||
|
||||
NGINX_STREAM_CONFIG="/etc/nginx/modules-enabled/60-jitsi-meet.conf"
|
||||
if [ -f $NGINX_STREAM_CONFIG ] && [ -f $NGINX_CONFIG ] ; then
|
||||
sed -i "s/listen 443 ssl/listen 4444 ssl http2/g" $NGINX_CONFIG
|
||||
invoke-rc.d nginx reload || true
|
||||
fi
|
||||
|
||||
# Enable turn server in config.js
|
||||
if [ -f $JITSI_MEET_CONFIG ] ; then
|
||||
sed -i "s/\/\/ useStunTurn: true/useStunTurn: true/g" $JITSI_MEET_CONFIG
|
||||
fi
|
||||
fi
|
||||
|
||||
# and we're done with debconf
|
||||
db_stop
|
||||
;;
|
||||
|
||||
abort-upgrade|abort-remove|abort-deconfigure)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,9 @@
|
|||
Template: jitsi-meet-turnserver/jvb-hostname
|
||||
Type: string
|
||||
_Description: The hostname of the current installation:
|
||||
The value for the hostname that is set in Jitsi Videobridge installation.
|
||||
|
||||
Template: jitsi-videobridge/jvb-hostname
|
||||
Type: string
|
||||
_Description: The hostname of the current installation:
|
||||
The value for the hostname that is set in Jitsi Videobridge installation.
|
|
@ -53,9 +53,12 @@ case "$1" in
|
|||
db_set jitsi-meet/jvb-hostname $JVB_HOSTNAME
|
||||
|
||||
NGINX_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'nginx' 2>/dev/null | awk '{print $3}' || true)"
|
||||
NGINX_FULL_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'nginx-full' 2>/dev/null | awk '{print $3}' || true)"
|
||||
NGINX_EXTRAS_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'nginx-extras' 2>/dev/null | awk '{print $3}' || true)"
|
||||
if [ "$NGINX_INSTALL_CHECK" = "installed" ] \
|
||||
|| [ "$NGINX_INSTALL_CHECK" = "unpacked" ] \
|
||||
|| [ "$NGINX_FULL_INSTALL_CHECK" = "installed" ] \
|
||||
|| [ "$NGINX_FULL_INSTALL_CHECK" = "unpacked" ] \
|
||||
|| [ "$NGINX_EXTRAS_INSTALL_CHECK" = "installed" ] \
|
||||
|| [ "$NGINX_EXTRAS_INSTALL_CHECK" = "unpacked" ] ; then
|
||||
FORCE_NGINX="true"
|
||||
|
@ -105,8 +108,6 @@ case "$1" in
|
|||
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" $JITSI_MEET_CONFIG
|
||||
fi
|
||||
|
||||
JVB_CONFIG="/etc/jitsi/videobridge/sip-communicator.properties"
|
||||
|
||||
# this is new install let's configure jvb to serve meet
|
||||
# no-nginx, no-apache installed on machine, this is new install or reconfiguring old one which have jvb_serve set
|
||||
if [[ "$JVB_SERVE" = "true" ]] ; then
|
||||
|
@ -121,11 +122,6 @@ case "$1" in
|
|||
echo "------------------------------------------------"
|
||||
echo ""
|
||||
elif [[ "$FORCE_NGINX" = "true" && ( -z "$JVB_HOSTNAME_OLD" || "$RECONFIGURING" = "true" ) ]] ; then
|
||||
# disables tcp harvester to make sure jvb will not take port 443
|
||||
if [[ -f $JVB_CONFIG ]] && ! grep -q "org.jitsi.videobridge.DISABLE_TCP_HARVESTER" "$JVB_CONFIG" ;then
|
||||
echo "org.jitsi.videobridge.DISABLE_TCP_HARVESTER=true" >> $JVB_CONFIG
|
||||
invoke-rc.d jvb restart || true
|
||||
fi
|
||||
|
||||
# this is a reconfigure, lets just delete old links
|
||||
if [ "$RECONFIGURING" = "true" ] ; then
|
||||
|
@ -156,11 +152,6 @@ case "$1" in
|
|||
|
||||
invoke-rc.d nginx reload || true
|
||||
elif [[ "$FORCE_APACHE" = "true" && ( -z "$JVB_HOSTNAME_OLD" || "$RECONFIGURING" = "true" ) ]] ; then
|
||||
# disables tcp harvester to make sure jvb will not take port 443
|
||||
if [[ -f $JVB_CONFIG ]] && ! grep -q "org.jitsi.videobridge.DISABLE_TCP_HARVESTER" "$JVB_CONFIG" ;then
|
||||
echo "org.jitsi.videobridge.DISABLE_TCP_HARVESTER=true" >> $JVB_CONFIG
|
||||
invoke-rc.d jvb restart || true
|
||||
fi
|
||||
|
||||
# this is a reconfigure, lets just delete old links
|
||||
if [ "$RECONFIGURING" = "true" ] ; then
|
||||
|
|
|
@ -3,6 +3,17 @@ plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }
|
|||
-- domain mapper options, must at least have domain base set to use the mapper
|
||||
muc_mapper_domain_base = "jitmeet.example.com";
|
||||
|
||||
turncredentials_secret = "__turnSecret__";
|
||||
|
||||
turncredentials = {
|
||||
{ type = "stun", host = "jitmeet.example.com", port = "443" },
|
||||
{ type = "turn", host = "jitmeet.example.com", port = "443", transport = "udp" },
|
||||
{ type = "turns", host = "jitmeet.example.com", port = "443", transport = "tcp" }
|
||||
};
|
||||
|
||||
cross_domain_bosh = false;
|
||||
consider_bosh_secure = true;
|
||||
|
||||
VirtualHost "jitmeet.example.com"
|
||||
-- enabled = false -- Remove this line to enable this host
|
||||
authentication = "anonymous"
|
||||
|
@ -25,6 +36,7 @@ VirtualHost "jitmeet.example.com"
|
|||
"pubsub";
|
||||
"ping"; -- Enable mod_ping
|
||||
"speakerstats";
|
||||
"turncredentials";
|
||||
}
|
||||
c2s_require_encryption = false
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Coturn configuration for Jitsi Meet
|
|
@ -0,0 +1,13 @@
|
|||
# jitsi-meet coturn config. Do not modify this line
|
||||
lt-cred-mech
|
||||
use-auth-secret
|
||||
keep-address-family
|
||||
static-auth-secret=__turnSecret__
|
||||
realm=jitsi-meet.example.com
|
||||
cert=/etc/jitsi/meet/jitsi-meet.example.com.crt
|
||||
pkey=/etc/jitsi/meet/jitsi-meet.example.com.key
|
||||
|
||||
no-tcp
|
||||
listening-port=443
|
||||
tls-listening-port=4445
|
||||
external-ip=__external_ip_address__
|
|
@ -0,0 +1,30 @@
|
|||
# this is jitsi-meet nginx module configuration
|
||||
# this forward all http traffic to the nginx virtual host port
|
||||
# and the rest to the turn server
|
||||
|
||||
stream {
|
||||
upstream web {
|
||||
server 127.0.0.1:4444;
|
||||
}
|
||||
upstream turn {
|
||||
server 127.0.0.1:4445;
|
||||
}
|
||||
# since 1.13.10
|
||||
map $ssl_preread_alpn_protocols $upstream {
|
||||
"h2" web;
|
||||
"http/1.1" web;
|
||||
"h2,http/1.1" web;
|
||||
default turn;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443;
|
||||
|
||||
# since 1.11.5
|
||||
ssl_preread on;
|
||||
proxy_pass $upstream;
|
||||
|
||||
# Increase buffer to serve video
|
||||
proxy_buffer_size 10m;
|
||||
}
|
||||
}
|
|
@ -3,7 +3,17 @@ server_names_hash_bucket_size 64;
|
|||
server {
|
||||
listen 80;
|
||||
server_name jitsi-meet.example.com;
|
||||
return 301 https://$host$request_uri;
|
||||
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
default_type "text/plain";
|
||||
root /usr/share/jitsi-meet;
|
||||
}
|
||||
location = /.well-known/acme-challenge/ {
|
||||
return 404;
|
||||
}
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
server {
|
||||
listen 443 ssl;
|
||||
|
|
|
@ -6,7 +6,7 @@ Debian Wheezy and other older systems may require additional things to be done.
|
|||
|
||||
Also note that a recent default Ubuntu installation has only the `main` repository enabled, and Jitsi Meet needs packages from `universe`. Check your `/etc/apt/sources.list` file, and if `universe` is not present refer to [Ubuntu's documentation](https://help.ubuntu.com/community/Repositories/Ubuntu) on how to enable it. (Usually it amounts to copying the `main` lines and changing to `universe`.)
|
||||
|
||||
N.B.:
|
||||
N.B.:
|
||||
|
||||
a.) All commands are supposed to be run by root. If you are logged in as a regular user with sudo rights, please prepend ___sudo___ to each of the commands.
|
||||
|
||||
|
@ -46,7 +46,7 @@ During the installation, you will be asked to enter the hostname of the Jitsi Me
|
|||
|
||||
This hostname (or IP address) will be used for virtualhost configuration inside the Jitsi Meet and also, you and your correspondents will be using it to access the web conferences.
|
||||
|
||||
### Generate a Let's Encrypt certificate
|
||||
### Generate a Let's Encrypt certificate
|
||||
|
||||
Simply run the following in your shell
|
||||
|
||||
|
@ -109,7 +109,7 @@ Enjoy!
|
|||
## Uninstall
|
||||
|
||||
```sh
|
||||
apt-get purge jigasi jitsi-meet jitsi-meet-web-config jitsi-meet-prosody jitsi-meet-web jicofo jitsi-videobridge
|
||||
apt-get purge jigasi jitsi-meet jitsi-meet-web-config jitsi-meet-prosody jitsi-meet-turnserver jitsi-meet-web jicofo jitsi-videobridge
|
||||
```
|
||||
|
||||
Sometimes the following packages will fail to uninstall properly:
|
||||
|
|
|
@ -57,6 +57,15 @@ if [ -f /etc/nginx/sites-enabled/$DOMAIN.conf ] ; then
|
|||
echo "service nginx reload" >> $CRON_FILE
|
||||
service nginx reload
|
||||
|
||||
TURN_CONFIG="/etc/turnserver.conf"
|
||||
if [ -f $TURN_CONFIG ] && grep -q "jitsi-meet coturn config" "$TURN_CONFIG" ; then
|
||||
echo "Configuring turnserver"
|
||||
sed -i "s/cert=\/etc\/jitsi\/meet\/.*crt/cert=$CERT_CRT_ESC/g" $TURN_CONFIG
|
||||
sed -i "s/pkey=\/etc\/jitsi\/meet\/.*key/pkey=$CERT_KEY_ESC/g" $TURN_CONFIG
|
||||
|
||||
echo "service coturn restart" >> $CRON_FILE
|
||||
service coturn restart
|
||||
fi
|
||||
elif [ -f /etc/apache2/sites-enabled/$DOMAIN.conf ] ; then
|
||||
|
||||
./certbot-auto certonly --noninteractive \
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
-- XEP-0215 implementation for time-limited turn credentials
|
||||
-- Copyright (C) 2012-2014 Philipp Hancke
|
||||
-- This file is MIT/X11 licensed.
|
||||
|
||||
--turncredentials_secret = "keepthissecret";
|
||||
--turncredentials = {
|
||||
-- { type = "stun", host = "8.8.8.8" },
|
||||
-- { type = "turn", host = "8.8.8.8", port = "3478" },
|
||||
-- { type = "turn", host = "8.8.8.8", port = "80", transport = "tcp" }
|
||||
--}
|
||||
-- for stun servers, host is required, port defaults to 3478
|
||||
-- for turn servers, host is required, port defaults to tcp,
|
||||
-- transport defaults to udp
|
||||
-- hosts can be a list of server names / ips for random
|
||||
-- choice loadbalancing
|
||||
|
||||
local st = require "util.stanza";
|
||||
local hmac_sha1 = require "util.hashes".hmac_sha1;
|
||||
local base64 = require "util.encodings".base64;
|
||||
local os_time = os.time;
|
||||
local secret = module:get_option_string("turncredentials_secret");
|
||||
local ttl = module:get_option_number("turncredentials_ttl", 86400);
|
||||
local hosts = module:get_option("turncredentials") or {};
|
||||
if not (secret) then
|
||||
module:log("error", "turncredentials not configured");
|
||||
return;
|
||||
end
|
||||
|
||||
module:add_feature("urn:xmpp:extdisco:1");
|
||||
|
||||
function random(arr)
|
||||
local index = math.random(1, #arr);
|
||||
return arr[index];
|
||||
end
|
||||
|
||||
|
||||
module:hook_global("config-reloaded", function()
|
||||
module:log("debug", "config-reloaded")
|
||||
secret = module:get_option_string("turncredentials_secret");
|
||||
ttl = module:get_option_number("turncredentials_ttl", 86400);
|
||||
hosts = module:get_option("turncredentials") or {};
|
||||
end);
|
||||
|
||||
module:hook("iq-get/host/urn:xmpp:extdisco:1:services", function(event)
|
||||
local origin, stanza = event.origin, event.stanza;
|
||||
if origin.type ~= "c2s" then
|
||||
return;
|
||||
end
|
||||
local now = os_time() + ttl;
|
||||
local userpart = tostring(now);
|
||||
local nonce = base64.encode(hmac_sha1(secret, tostring(userpart), false));
|
||||
local reply = st.reply(stanza):tag("services", {xmlns = "urn:xmpp:extdisco:1"})
|
||||
for idx, item in pairs(hosts) do
|
||||
if item.type == "stun" or item.type == "stuns" then
|
||||
-- stun items need host and port (defaults to 3478)
|
||||
reply:tag("service",
|
||||
{ type = item.type, host = item.host, port = tostring(item.port) or "3478" }
|
||||
):up();
|
||||
elseif item.type == "turn" or item.type == "turns" then
|
||||
local turn = {}
|
||||
-- turn items need host, port (defaults to 3478),
|
||||
-- transport (defaults to udp)
|
||||
-- username, password, ttl
|
||||
turn.type = item.type;
|
||||
turn.port = tostring(item.port);
|
||||
turn.transport = item.transport;
|
||||
turn.username = userpart;
|
||||
turn.password = nonce;
|
||||
turn.ttl = tostring(ttl);
|
||||
if item.hosts then
|
||||
turn.host = random(item.hosts)
|
||||
else
|
||||
turn.host = item.host
|
||||
end
|
||||
reply:tag("service", turn):up();
|
||||
end
|
||||
end
|
||||
origin.send(reply);
|
||||
return true;
|
||||
end);
|
Loading…
Reference in New Issue