Quellcode durchsuchen

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.
master
Дамян Минков vor 5 Jahren
Ursprung
Commit
c73ba37202
Es ist kein Account mit der E-Mail-Adresse des Committers verbunden

+ 2
- 0
config.js Datei anzeigen

@@ -329,6 +329,8 @@ var config = {
329 329
 
330 330
         // The STUN servers that will be used in the peer to peer connections
331 331
         stunServers: [
332
+
333
+            // { urls: 'stun:jitsi-meet.example.com:443' },
332 334
             { urls: 'stun:stun.l.google.com:19302' },
333 335
             { urls: 'stun:stun1.l.google.com:19302' },
334 336
             { urls: 'stun:stun2.l.google.com:19302' }

+ 5
- 1
debian/control Datei anzeigen

@@ -21,7 +21,7 @@ Description: WebRTC JavaScript video conferences
21 21
 
22 22
 Package: jitsi-meet-web-config
23 23
 Architecture: all
24
-Depends: openssl, nginx | nginx-extras | apache2
24
+Depends: openssl, nginx | nginx-full | nginx-extras | apache2
25 25
 Description: Configuration for web serving of Jitsi Meet
26 26
  Jitsi Meet is a WebRTC JavaScript application that uses Jitsi
27 27
  Videobridge to provide high quality, scalable video conferences.
@@ -54,3 +54,7 @@ Architecture: all
54 54
 Depends: ${misc:Depends}, prosody-trunk (>= 1nightly747) | prosody-0.11 | prosody (>= 0.11.2), libssl-dev, luarocks, jitsi-meet-prosody
55 55
 Description: Prosody token authentication plugin for Jitsi Meet
56 56
 
57
+Package: jitsi-meet-turnserver
58
+Architecture: all
59
+Depends: ${misc:Depends}, nginx (>= 1.13.10) | nginx-full (>= 1.13.10) | nginx-extras (>= 1.13.10), jitsi-meet-prosody, coturn, dnsutils
60
+Description: Configures coturn to be used with Jitsi Meet

+ 15
- 3
debian/jitsi-meet-prosody.postinst Datei anzeigen

@@ -80,6 +80,15 @@ case "$1" in
80 80
         # stores the hostname so we will reuse it later, like in purge
81 81
         db_set jitsi-meet-prosody/jvb-hostname "$JVB_HOSTNAME"
82 82
 
83
+        db_get jitsi-meet-prosody/turn-secret
84
+        if [ -z "$RET" ] ; then
85
+            # 8-chars random secret used for the turnserver
86
+            TURN_SECRET=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1`
87
+            db_set jitsi-meet-prosody/turn-secret "$TURN_SECRET"
88
+        else
89
+            TURN_SECRET="$RET"
90
+        fi
91
+
83 92
         # and we're done with debconf
84 93
         db_stop
85 94
 
@@ -97,6 +106,7 @@ case "$1" in
97 106
             sed -i "s/jitmeet.example.com/$JVB_HOSTNAME/g" $PROSODY_HOST_CONFIG
98 107
             sed -i "s/focusSecret/$JICOFO_SECRET/g" $PROSODY_HOST_CONFIG
99 108
             sed -i "s/focusUser/$JICOFO_AUTH_USER/g" $PROSODY_HOST_CONFIG
109
+            sed -i "s/__turnSecret__/$TURN_SECRET/g" $PROSODY_HOST_CONFIG
100 110
             if [ ! -f /etc/prosody/conf.d/$JVB_HOSTNAME.cfg.lua ]; then
101 111
                 ln -s $PROSODY_HOST_CONFIG /etc/prosody/conf.d/$JVB_HOSTNAME.cfg.lua
102 112
             fi
@@ -115,12 +125,14 @@ case "$1" in
115 125
             PROSODY_CONFIG_PRESENT="false"
116 126
         fi
117 127
 
118
-        # we always try to create the user 'jvb' and not fail configure if user exists
119
-        prosodyctl register jvb $JICOFO_AUTH_DOMAIN $JVB_SECRET || true
128
+        USER_EXISTS_CHECK=`prosodyctl adduser jvb@$JICOFO_AUTH_DOMAIN < /dev/null || true`
129
+        if [ ! "$USER_EXISTS_CHECK" = "That user already exists" ]; then
130
+            prosodyctl register jvb $JICOFO_AUTH_DOMAIN $JVB_SECRET || true
131
+        fi
120 132
 
121 133
         # Check whether prosody config has the internal muc, if not add it,
122 134
         # as we are migrating configs
123
-        if ! grep -q "internal.auth.$JVB_HOSTNAME" $PROSODY_HOST_CONFIG; then
135
+        if [ -f $PROSODY_HOST_CONFIG ] && ! grep -q "internal.auth.$JVB_HOSTNAME" $PROSODY_HOST_CONFIG; then
124 136
             echo -e "\nComponent \"internal.auth.$JVB_HOSTNAME\" \"muc\"" >> $PROSODY_HOST_CONFIG
125 137
             echo -e "    storage = \"null\"" >> $PROSODY_HOST_CONFIG
126 138
             echo -e "    modules_enabled = { \"ping\"; }" >> $PROSODY_HOST_CONFIG

+ 5
- 0
debian/jitsi-meet-prosody.templates Datei anzeigen

@@ -28,3 +28,8 @@ Template: jicofo/jicofosecret
28 28
 Type: password
29 29
 _Description: Jicofo Component secret:
30 30
  The secret used to connect to xmpp server as component
31
+
32
+Template: jitsi-meet-prosody/turn-secret
33
+Type: string
34
+_Description: The turn server secret
35
+ The secret used to connect to turnserver server.

+ 2
- 0
debian/jitsi-meet-turnserver.install Datei anzeigen

@@ -0,0 +1,2 @@
1
+doc/debian/jitsi-meet-turn/turnserver.conf  /usr/share/jitsi-meet-turnserver/
2
+doc/debian/jitsi-meet/jitsi-meet.conf       /usr/share/jitsi-meet-turnserver/

+ 1
- 0
debian/jitsi-meet-turnserver.links Datei anzeigen

@@ -0,0 +1 @@
1
+/usr/share/jitsi-meet-turnserver/jitsi-meet.conf /etc/nginx/modules-enabled/60-jitsi-meet.conf

+ 127
- 0
debian/jitsi-meet-turnserver.postinst Datei anzeigen

@@ -0,0 +1,127 @@
1
+#!/bin/bash
2
+# postinst script for jitsi-meet-turnserver
3
+#
4
+# see: dh_installdeb(1)
5
+
6
+set -e
7
+
8
+# summary of how this script can be called:
9
+#        * <postinst> `configure' <most-recently-configured-version>
10
+#        * <old-postinst> `abort-upgrade' <new version>
11
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
12
+#          <new-version>
13
+#        * <postinst> `abort-remove'
14
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
15
+#          <failed-install-package> <version> `removing'
16
+#          <conflicting-package> <version>
17
+# for details, see http://www.debian.org/doc/debian-policy/ or
18
+# the debian-policy package
19
+
20
+case "$1" in
21
+    configure)
22
+        # loading debconf
23
+        . /usr/share/debconf/confmodule
24
+
25
+        # try to get host from jitsi-videobridge
26
+        db_get jitsi-videobridge/jvb-hostname
27
+        if [ -z "$RET" ] ; then
28
+            # server hostname
29
+            db_set jitsi-videobridge/jvb-hostname "localhost"
30
+            db_input critical jitsi-videobridge/jvb-hostname || true
31
+            db_go
32
+        fi
33
+        JVB_HOSTNAME="$RET"
34
+
35
+        TURN_CONFIG="/etc/turnserver.conf"
36
+        NGINX_CONFIG="/etc/nginx/sites-available/$JVB_HOSTNAME.conf"
37
+        JITSI_MEET_CONFIG="/etc/jitsi/meet/$JVB_HOSTNAME-config.js"
38
+
39
+        # detect dpkg-reconfigure, just delete old links
40
+        db_get jitsi-meet-turnserver/jvb-hostname
41
+        JVB_HOSTNAME_OLD=$RET
42
+        if [ -n "$RET" ] && [ ! "$JVB_HOSTNAME_OLD" = "$JVB_HOSTNAME" ] ; then
43
+            rm -f $TURN_CONFIG
44
+        fi
45
+
46
+        # this detect only old installations with no nginx
47
+        db_get jitsi-meet/jvb-serve || true
48
+        if [ ! -f $NGINX_CONFIG -o "$RET" = "true" ] ; then
49
+            # nothing to do
50
+            echo ""
51
+            echo "turnserver not configured as no nginx found to multiplex traffic"
52
+            echo ""
53
+            db_stop
54
+            exit 0
55
+        fi
56
+
57
+        # stores the hostname so we will reuse it later, like in purge
58
+        db_set jitsi-meet-turnserver/jvb-hostname "$JVB_HOSTNAME"
59
+
60
+        # try to get turnserver password
61
+        db_get jitsi-meet-prosody/turn-secret
62
+        if [ -z "$RET" ] ; then
63
+            db_input critical jitsi-meet-prosody/turn-secret || true
64
+            db_go
65
+        fi
66
+        TURN_SECRET="$RET"
67
+
68
+        if [[ -f $TURN_CONFIG ]] && ! grep -q "jitsi-meet coturn config" "$TURN_CONFIG" ; then
69
+            PUBLIC_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
70
+            cp /usr/share/jitsi-meet-turnserver/turnserver.conf $TURN_CONFIG
71
+            sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" $TURN_CONFIG
72
+            sed -i "s/__turnSecret__/$TURN_SECRET/g" $TURN_CONFIG
73
+            sed -i "s/__external_ip_address__/$JVB_HOSTNAME/g" $TURN_CONFIG
74
+
75
+            # SSL for nginx
76
+            db_get jitsi-meet/cert-choice
77
+            CERT_CHOICE="$RET"
78
+
79
+            if [ "$CERT_CHOICE" = "I want to use my own certificate" ] ; then
80
+                db_get jitsi-meet/cert-path-key
81
+                CERT_KEY="$RET"
82
+                db_get jitsi-meet/cert-path-crt
83
+                CERT_CRT="$RET"
84
+
85
+                # replace self-signed certificate paths with user provided ones
86
+                CERT_KEY_ESC=$(echo $CERT_KEY | sed 's/\./\\\./g')
87
+                CERT_KEY_ESC=$(echo $CERT_KEY_ESC | sed 's/\//\\\//g')
88
+                sed -i "s/pkey=\/etc\/jitsi\/meet\/.*key/pkey=$CERT_KEY_ESC/g" $TURN_CONFIG
89
+                CERT_CRT_ESC=$(echo $CERT_CRT | sed 's/\./\\\./g')
90
+                CERT_CRT_ESC=$(echo $CERT_CRT_ESC | sed 's/\//\\\//g')
91
+                sed -i "s/cert=\/etc\/jitsi\/meet\/.*crt/cert=$CERT_CRT_ESC/g" $TURN_CONFIG
92
+            fi
93
+
94
+            sed -i "s/#TURNSERVER_ENABLED/TURNSERVER_ENABLED/g" /etc/default/coturn
95
+            invoke-rc.d coturn restart || true
96
+
97
+            NGINX_STREAM_CONFIG="/etc/nginx/modules-enabled/60-jitsi-meet.conf"
98
+            if [ -f $NGINX_STREAM_CONFIG ] && [ -f $NGINX_CONFIG ] ; then
99
+                sed -i "s/listen 443 ssl/listen 4444 ssl http2/g" $NGINX_CONFIG
100
+                invoke-rc.d nginx reload || true
101
+            fi
102
+
103
+            # Enable turn server in config.js
104
+            if [ -f $JITSI_MEET_CONFIG ] ; then
105
+                sed -i "s/\/\/ useStunTurn: true/useStunTurn: true/g" $JITSI_MEET_CONFIG
106
+            fi
107
+        fi
108
+
109
+        # and we're done with debconf
110
+        db_stop
111
+    ;;
112
+
113
+    abort-upgrade|abort-remove|abort-deconfigure)
114
+    ;;
115
+
116
+    *)
117
+        echo "postinst called with unknown argument \`$1'" >&2
118
+        exit 1
119
+    ;;
120
+esac
121
+
122
+# dh_installdeb will replace this with shell code automatically
123
+# generated by other debhelper scripts.
124
+
125
+#DEBHELPER#
126
+
127
+exit 0

+ 9
- 0
debian/jitsi-meet-turnserver.templates Datei anzeigen

@@ -0,0 +1,9 @@
1
+Template: jitsi-meet-turnserver/jvb-hostname
2
+Type: string
3
+_Description: The hostname of the current installation:
4
+ The value for the hostname that is set in Jitsi Videobridge installation.
5
+
6
+Template: jitsi-videobridge/jvb-hostname
7
+Type: string
8
+_Description: The hostname of the current installation:
9
+ The value for the hostname that is set in Jitsi Videobridge installation.

+ 3
- 12
debian/jitsi-meet-web-config.postinst Datei anzeigen

@@ -53,9 +53,12 @@ case "$1" in
53 53
         db_set jitsi-meet/jvb-hostname $JVB_HOSTNAME
54 54
 
55 55
         NGINX_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'nginx' 2>/dev/null | awk '{print $3}' || true)"
56
+        NGINX_FULL_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'nginx-full' 2>/dev/null | awk '{print $3}' || true)"
56 57
         NGINX_EXTRAS_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'nginx-extras' 2>/dev/null | awk '{print $3}' || true)"
57 58
         if [ "$NGINX_INSTALL_CHECK" = "installed" ] \
58 59
            || [ "$NGINX_INSTALL_CHECK" = "unpacked" ] \
60
+           || [ "$NGINX_FULL_INSTALL_CHECK" = "installed" ] \
61
+           || [ "$NGINX_FULL_INSTALL_CHECK" = "unpacked" ] \
59 62
            || [ "$NGINX_EXTRAS_INSTALL_CHECK" = "installed" ] \
60 63
            || [ "$NGINX_EXTRAS_INSTALL_CHECK" = "unpacked" ] ; then
61 64
             FORCE_NGINX="true"
@@ -105,8 +108,6 @@ case "$1" in
105 108
             sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" $JITSI_MEET_CONFIG
106 109
         fi
107 110
 
108
-        JVB_CONFIG="/etc/jitsi/videobridge/sip-communicator.properties"
109
-
110 111
         # this is new install let's configure jvb to serve meet
111 112
         # no-nginx, no-apache installed on machine, this is new install or reconfiguring old one which have jvb_serve set
112 113
         if [[ "$JVB_SERVE" = "true" ]] ; then
@@ -121,11 +122,6 @@ case "$1" in
121 122
             echo "------------------------------------------------"
122 123
             echo ""
123 124
         elif [[ "$FORCE_NGINX" = "true" && ( -z "$JVB_HOSTNAME_OLD" || "$RECONFIGURING" = "true" ) ]] ; then
124
-            # disables tcp harvester to make sure jvb will not take port 443
125
-            if [[ -f $JVB_CONFIG ]] && ! grep -q "org.jitsi.videobridge.DISABLE_TCP_HARVESTER" "$JVB_CONFIG"  ;then
126
-                echo "org.jitsi.videobridge.DISABLE_TCP_HARVESTER=true" >> $JVB_CONFIG
127
-                invoke-rc.d jvb restart || true
128
-            fi
129 125
 
130 126
             # this is a reconfigure, lets just delete old links
131 127
             if [ "$RECONFIGURING" = "true" ] ; then
@@ -156,11 +152,6 @@ case "$1" in
156 152
 
157 153
             invoke-rc.d nginx reload || true
158 154
         elif [[ "$FORCE_APACHE" = "true" && ( -z "$JVB_HOSTNAME_OLD" || "$RECONFIGURING" = "true" ) ]] ; then
159
-            # disables tcp harvester to make sure jvb will not take port 443
160
-            if [[ -f $JVB_CONFIG ]] && ! grep -q "org.jitsi.videobridge.DISABLE_TCP_HARVESTER" "$JVB_CONFIG"  ;then
161
-                echo "org.jitsi.videobridge.DISABLE_TCP_HARVESTER=true" >> $JVB_CONFIG
162
-                invoke-rc.d jvb restart || true
163
-            fi
164 155
 
165 156
             # this is a reconfigure, lets just delete old links
166 157
             if [ "$RECONFIGURING" = "true" ] ; then

+ 12
- 0
doc/debian/jitsi-meet-prosody/prosody.cfg.lua-jvb.example Datei anzeigen

@@ -3,6 +3,17 @@ plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }
3 3
 -- domain mapper options, must at least have domain base set to use the mapper
4 4
 muc_mapper_domain_base = "jitmeet.example.com";
5 5
 
6
+turncredentials_secret = "__turnSecret__";
7
+
8
+turncredentials = {
9
+  { type = "stun", host = "jitmeet.example.com", port = "443" },
10
+  { type = "turn", host = "jitmeet.example.com", port = "443", transport = "udp" },
11
+  { type = "turns", host = "jitmeet.example.com", port = "443", transport = "tcp" }
12
+};
13
+
14
+cross_domain_bosh = false;
15
+consider_bosh_secure = true;
16
+
6 17
 VirtualHost "jitmeet.example.com"
7 18
         -- enabled = false -- Remove this line to enable this host
8 19
         authentication = "anonymous"
@@ -25,6 +36,7 @@ VirtualHost "jitmeet.example.com"
25 36
             "pubsub";
26 37
             "ping"; -- Enable mod_ping
27 38
             "speakerstats";
39
+            "turncredentials";
28 40
         }
29 41
         c2s_require_encryption = false
30 42
 

+ 1
- 0
doc/debian/jitsi-meet-turn/RREADME Datei anzeigen

@@ -0,0 +1 @@
1
+Coturn configuration for Jitsi Meet

+ 13
- 0
doc/debian/jitsi-meet-turn/turnserver.conf Datei anzeigen

@@ -0,0 +1,13 @@
1
+# jitsi-meet coturn config. Do not modify this line
2
+lt-cred-mech
3
+use-auth-secret
4
+keep-address-family
5
+static-auth-secret=__turnSecret__
6
+realm=jitsi-meet.example.com
7
+cert=/etc/jitsi/meet/jitsi-meet.example.com.crt
8
+pkey=/etc/jitsi/meet/jitsi-meet.example.com.key
9
+
10
+no-tcp
11
+listening-port=443
12
+tls-listening-port=4445
13
+external-ip=__external_ip_address__

+ 30
- 0
doc/debian/jitsi-meet/jitsi-meet.conf Datei anzeigen

@@ -0,0 +1,30 @@
1
+# this is jitsi-meet nginx module configuration
2
+# this forward all http traffic to the nginx virtual host port
3
+# and the rest to the turn server
4
+
5
+stream {
6
+    upstream web {
7
+        server 127.0.0.1:4444;
8
+    }
9
+    upstream turn {
10
+        server 127.0.0.1:4445;
11
+    }
12
+    # since 1.13.10
13
+    map $ssl_preread_alpn_protocols $upstream {
14
+        "h2"            web;
15
+        "http/1.1"      web;
16
+        "h2,http/1.1"   web;
17
+        default         turn;
18
+    }
19
+
20
+    server {
21
+        listen 443;
22
+
23
+        # since 1.11.5
24
+        ssl_preread on;
25
+        proxy_pass $upstream;
26
+
27
+        # Increase buffer to serve video
28
+        proxy_buffer_size 10m;
29
+    }
30
+}

+ 11
- 1
doc/debian/jitsi-meet/jitsi-meet.example Datei anzeigen

@@ -3,7 +3,17 @@ server_names_hash_bucket_size 64;
3 3
 server {
4 4
     listen 80;
5 5
     server_name jitsi-meet.example.com;
6
-    return 301 https://$host$request_uri;
6
+
7
+    location ^~ /.well-known/acme-challenge/ {
8
+       default_type "text/plain";
9
+       root         /usr/share/jitsi-meet;
10
+    }
11
+    location = /.well-known/acme-challenge/ {
12
+       return 404;
13
+    }
14
+    location / {
15
+       return 301 https://$host$request_uri;
16
+    }
7 17
 }
8 18
 server {
9 19
     listen 443 ssl;

+ 3
- 3
doc/quick-install.md Datei anzeigen

@@ -6,7 +6,7 @@ Debian Wheezy and other older systems may require additional things to be done.
6 6
 
7 7
 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`.)
8 8
 
9
-N.B.: 
9
+N.B.:
10 10
 
11 11
 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.
12 12
 
@@ -46,7 +46,7 @@ During the installation, you will be asked to enter the hostname of the Jitsi Me
46 46
 
47 47
 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.
48 48
 
49
-### Generate a Let's Encrypt certificate 
49
+### Generate a Let's Encrypt certificate
50 50
 
51 51
 Simply run the following in your shell
52 52
 
@@ -109,7 +109,7 @@ Enjoy!
109 109
 ## Uninstall
110 110
 
111 111
 ```sh
112
-apt-get purge jigasi jitsi-meet jitsi-meet-web-config jitsi-meet-prosody jitsi-meet-web jicofo jitsi-videobridge
112
+apt-get purge jigasi jitsi-meet jitsi-meet-web-config jitsi-meet-prosody jitsi-meet-turnserver jitsi-meet-web jicofo jitsi-videobridge
113 113
 ```
114 114
 
115 115
 Sometimes the following packages will fail to uninstall properly:

+ 9
- 0
resources/install-letsencrypt-cert.sh Datei anzeigen

@@ -57,6 +57,15 @@ if [ -f /etc/nginx/sites-enabled/$DOMAIN.conf ] ; then
57 57
     echo "service nginx reload" >> $CRON_FILE
58 58
     service nginx reload
59 59
 
60
+    TURN_CONFIG="/etc/turnserver.conf"
61
+    if [ -f $TURN_CONFIG ] && grep -q "jitsi-meet coturn config" "$TURN_CONFIG" ; then
62
+        echo "Configuring turnserver"
63
+        sed -i "s/cert=\/etc\/jitsi\/meet\/.*crt/cert=$CERT_CRT_ESC/g" $TURN_CONFIG
64
+        sed -i "s/pkey=\/etc\/jitsi\/meet\/.*key/pkey=$CERT_KEY_ESC/g" $TURN_CONFIG
65
+
66
+        echo "service coturn restart" >> $CRON_FILE
67
+        service coturn restart
68
+    fi
60 69
 elif [ -f /etc/apache2/sites-enabled/$DOMAIN.conf ] ; then
61 70
 
62 71
     ./certbot-auto certonly --noninteractive \

+ 80
- 0
resources/prosody-plugins/mod_turncredentials.lua Datei anzeigen

@@ -0,0 +1,80 @@
1
+-- XEP-0215 implementation for time-limited turn credentials
2
+-- Copyright (C) 2012-2014 Philipp Hancke
3
+-- This file is MIT/X11 licensed.
4
+
5
+--turncredentials_secret = "keepthissecret";
6
+--turncredentials = {
7
+--    { type = "stun", host = "8.8.8.8" },
8
+--    { type = "turn", host = "8.8.8.8", port = "3478" },
9
+--    { type = "turn", host = "8.8.8.8", port = "80", transport = "tcp" }
10
+--}
11
+-- for stun servers, host is required, port defaults to 3478
12
+-- for turn servers, host is required, port defaults to tcp,
13
+--          transport defaults to udp
14
+--          hosts can be a list of server names / ips for random
15
+--          choice loadbalancing
16
+
17
+local st = require "util.stanza";
18
+local hmac_sha1 = require "util.hashes".hmac_sha1;
19
+local base64 = require "util.encodings".base64;
20
+local os_time = os.time;
21
+local secret = module:get_option_string("turncredentials_secret");
22
+local ttl = module:get_option_number("turncredentials_ttl", 86400);
23
+local hosts = module:get_option("turncredentials") or {};
24
+if not (secret) then
25
+    module:log("error", "turncredentials not configured");
26
+    return;
27
+end
28
+
29
+module:add_feature("urn:xmpp:extdisco:1");
30
+
31
+function random(arr)
32
+    local index = math.random(1, #arr);
33
+    return arr[index];
34
+end
35
+
36
+
37
+module:hook_global("config-reloaded", function()
38
+    module:log("debug", "config-reloaded")
39
+    secret = module:get_option_string("turncredentials_secret");
40
+    ttl = module:get_option_number("turncredentials_ttl", 86400);
41
+    hosts = module:get_option("turncredentials") or {};
42
+end);
43
+
44
+module:hook("iq-get/host/urn:xmpp:extdisco:1:services", function(event)
45
+    local origin, stanza = event.origin, event.stanza;
46
+    if origin.type ~= "c2s" then
47
+        return;
48
+    end
49
+    local now = os_time() + ttl;
50
+    local userpart = tostring(now);
51
+    local nonce = base64.encode(hmac_sha1(secret, tostring(userpart), false));
52
+    local reply = st.reply(stanza):tag("services", {xmlns = "urn:xmpp:extdisco:1"})
53
+    for idx, item in pairs(hosts) do
54
+        if item.type == "stun" or item.type == "stuns" then
55
+            -- stun items need host and port (defaults to 3478)
56
+            reply:tag("service",
57
+                { type = item.type, host = item.host, port = tostring(item.port) or "3478" }
58
+            ):up();
59
+        elseif item.type == "turn" or item.type == "turns" then
60
+            local turn = {}
61
+            -- turn items need host, port (defaults to 3478),
62
+	          -- transport (defaults to udp)
63
+	          -- username, password, ttl
64
+            turn.type = item.type;
65
+            turn.port = tostring(item.port);
66
+            turn.transport = item.transport;
67
+            turn.username = userpart;
68
+            turn.password = nonce;
69
+            turn.ttl = tostring(ttl);
70
+            if item.hosts then
71
+                turn.host = random(item.hosts)
72
+            else
73
+                turn.host = item.host
74
+            end
75
+            reply:tag("service", turn):up();
76
+        end
77
+    end
78
+    origin.send(reply);
79
+    return true;
80
+end);

Laden…
Abbrechen
Speichern