diff --git a/config.js b/config.js index 326e4ac999ad..f855184bdd37 100644 --- a/config.js +++ b/config.js @@ -343,7 +343,7 @@ 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:jitsi-meet.example.com:4446' }, { urls: 'stun:meet-jit-si-turnrelay.jitsi.net:443' } ], diff --git a/debian/control b/debian/control index 740888ca461e..2c8c551fae41 100644 --- a/debian/control +++ b/debian/control @@ -53,5 +53,6 @@ Description: Prosody token authentication plugin for Jitsi Meet Package: jitsi-meet-turnserver Architecture: all Breaks: apache2 +Pre-Depends: jitsi-meet-web-config 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 diff --git a/debian/jitsi-meet-prosody.postinst b/debian/jitsi-meet-prosody.postinst index 2da07f4ab6f2..5735a3bb6069 100644 --- a/debian/jitsi-meet-prosody.postinst +++ b/debian/jitsi-meet-prosody.postinst @@ -134,7 +134,7 @@ case "$1" in # as we are migrating configs 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 " storage = \"memory\"" >> $PROSODY_HOST_CONFIG echo -e " modules_enabled = { \"ping\"; }" >> $PROSODY_HOST_CONFIG echo -e " admins = { \"$JICOFO_AUTH_USER@auth.$JVB_HOSTNAME\", \"jvb@auth.$JVB_HOSTNAME\" }" >> $PROSODY_HOST_CONFIG fi @@ -148,14 +148,13 @@ case "$1" in ln -sf /var/lib/prosody/$JVB_HOSTNAME.crt /etc/prosody/certs/$JVB_HOSTNAME.crt fi - PR11_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'prosody-0.11' 2>/dev/null | awk '{print $3}' || true)" + PRTRUNK_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'prosody-trunk' 2>/dev/null | awk '{print $3}' || true)" PR10_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'prosody-0.10' 2>/dev/null | awk '{print $3}' || true)" PR_VER_INSTALLED=$(dpkg-query -f='${Version}\n' --show prosody 2>/dev/null || true) - if [ "$PR11_INSTALL_CHECK" = "installed" ] \ - || [ "$PR11_INSTALL_CHECK" = "unpacked" ] \ - || dpkg --compare-versions "$PR_VER_INSTALLED" gt "0.11" ; then + if [ "$PRTRUNK_INSTALL_CHECK" = "installed" ] \ + || [ "$PRTRUNK_INSTALL_CHECK" = "unpacked" ] ; then if [ -f $PROSODY_HOST_CONFIG ]; then - sed -i 's/storage = \"null\"/storage = \"memory\"/g' $PROSODY_HOST_CONFIG + sed -i 's/storage = \"memory\"/storage = \"null\"/g' $PROSODY_HOST_CONFIG # trigger a restart PROSODY_CONFIG_PRESENT="false" @@ -168,7 +167,7 @@ case "$1" in # if the version is 0.10.X (>0.10 and <0.11) if [ -f $PROSODY_HOST_CONFIG ] \ && dpkg --compare-versions "$PR_VER_INSTALLED" lt "0.11" ; then - sed -i 's/storage = \"null\"/storage = \"none\"/g' $PROSODY_HOST_CONFIG + sed -i 's/storage = \"memory\"/storage = \"none\"/g' $PROSODY_HOST_CONFIG # trigger a restart PROSODY_CONFIG_PRESENT="false" diff --git a/debian/jitsi-meet-tokens.postinst b/debian/jitsi-meet-tokens.postinst index 431320290162..392fbef0ba0d 100644 --- a/debian/jitsi-meet-tokens.postinst +++ b/debian/jitsi-meet-tokens.postinst @@ -69,12 +69,15 @@ case "$1" in echo "Failed to install basexx - try installing it manually" fi - PR11_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'prosody-0.11' 2>/dev/null | awk '{print $3}' || true)" + PR10_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'prosody-0.10' 2>/dev/null | awk '{print $3}' || true)" + PRTRUNK_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'prosody-trunk' 2>/dev/null | awk '{print $3}' || true)" PR_VER_INSTALLED=$(dpkg-query -f='${Version}\n' --show prosody 2>/dev/null || true) - if [ "$PR11_INSTALL_CHECK" = "installed" ] \ - || [ "$PR11_INSTALL_CHECK" = "unpacked" ] \ - || dpkg --compare-versions "$PR_VER_INSTALLED" gt "0.11" ; then - sed -i 's/module:hook/module:hook_global/g' /usr/share/jitsi-meet/prosody-plugins/mod_auth_token.lua + if [ "$PR10_INSTALL_CHECK" = "installed" ] \ + || "$PR10_INSTALL_CHECK" = "unpacked" \ + || "$PRTRUNK_INSTALL_CHECK" = "installed" \ + || "$PRTRUNK_INSTALL_CHECK" = "unpacked" \ + || dpkg --compare-versions "$PR_VER_INSTALLED" lt "0.11" ; then + sed -i 's/module:hook_global(/module:hook(/g' /usr/share/jitsi-meet/prosody-plugins/mod_auth_token.lua fi if [ -x "/etc/init.d/prosody" ]; then diff --git a/debian/jitsi-meet-turnserver.install b/debian/jitsi-meet-turnserver.install index ba71b7a979db..9d8098b2b589 100644 --- a/debian/jitsi-meet-turnserver.install +++ b/debian/jitsi-meet-turnserver.install @@ -1,2 +1,3 @@ -doc/debian/jitsi-meet-turn/turnserver.conf /usr/share/jitsi-meet-turnserver/ -doc/debian/jitsi-meet/jitsi-meet.conf /usr/share/jitsi-meet-turnserver/ +doc/debian/jitsi-meet-turn/turnserver.conf /usr/share/jitsi-meet-turnserver/ +doc/debian/jitsi-meet/jitsi-meet.conf /usr/share/jitsi-meet-turnserver/ +doc/debian/jitsi-meet-turn/coturn-certbot-deploy.sh /usr/share/jitsi-meet-turnserver/ diff --git a/debian/jitsi-meet-turnserver.postinst b/debian/jitsi-meet-turnserver.postinst index 07b442423686..bde88ae0a189 100644 --- a/debian/jitsi-meet-turnserver.postinst +++ b/debian/jitsi-meet-turnserver.postinst @@ -38,6 +38,7 @@ case "$1" in NGINX_SITES_ENABLED="/etc/nginx/sites-enabled/" NGINX_CONFIG_ENABLED="${NGINX_SITES_ENABLED}${JVB_HOSTNAME}.conf" + NGINX_MULTIPLEXING="true" for site in ${NGINX_SITES_ENABLED}*; do # if it is not a file continue [ -f "${site}" ] || continue @@ -48,11 +49,10 @@ case "$1" in # nothing to do echo "------------------------------------------------" echo "" - echo "turnserver not configured as other nginx sites use port 443" + echo "turnserver is listening on tcp 4445 as other nginx sites use port 443" echo "" echo "------------------------------------------------" - db_stop - exit 0 + NGINX_MULTIPLEXING="false" fi done @@ -77,7 +77,7 @@ case "$1" in # nothing to do echo "------------------------------------------------" echo "" - echo "turnserver not configured as no nginx found to multiplex traffic" + echo "turnserver not configured" echo "" echo "------------------------------------------------" db_stop @@ -106,18 +106,19 @@ case "$1" in TURN_SECRET="$RET" # no turn config exists, lt's copy template and fill it in - PUBLIC_IP=$(dig +short myip.opendns.com @resolver1.opendns.com) + PUBLIC_IP=$(dig +short myip.opendns.com @resolver1.opendns.com) || true + if [ -z "$PUBLIC_IP" ] ; then + PUBLIC_IP="127.0.0.1" + echo "------------------------------------------------" + echo "Warning! Could not resolve your external ip address! Error:^" + echo "Your turn server will not work till you edit your $TURN_CONFIG config file." + echo "You need to set your external ip address in external-ip and restart coturn service." + echo "------------------------------------------------" + fi 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 - - # Hack Debian Buster coturn to be able to bind privileged port 443 - COTURN_UNIT_FILE="/lib/systemd/system/coturn.service" - if [[ -f $COTURN_UNIT_FILE ]] && ! grep -q "CAP_NET_BIND_SERVICE" "$COTURN_UNIT_FILE" ; then - sed -i "s/\[Service\]/\[Service\]\nAmbientCapabilities=CAP_NET_BIND_SERVICE/g" $COTURN_UNIT_FILE - systemctl daemon-reload - fi + sed -i "s/__external_ip_address__/$PUBLIC_IP/g" $TURN_CONFIG # SSL for nginx db_get jitsi-meet/cert-choice @@ -142,11 +143,18 @@ case "$1" in 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 + if [ $NGINX_MULTIPLEXING = "true" ] && [ ! -f $NGINX_STREAM_CONFIG ] && [ -f $NGINX_CONFIG ] ; then ln -s /usr/share/jitsi-meet-turnserver/jitsi-meet.conf $NGINX_STREAM_CONFIG sed -i "s/listen 443 ssl/listen 4444 ssl http2/g" $NGINX_CONFIG sed -i "s/listen \[\:\:\]\:443 ssl/listen \[\:\:\]\:4444 ssl http2/g" $NGINX_CONFIG invoke-rc.d nginx reload || true + else + PROSODY_HOST_CONFIG="/etc/prosody/conf.avail/$JVB_HOSTNAME.cfg.lua" + if [ -f $PROSODY_HOST_CONFIG ] ; then + # If we are not multiplexing we need to change the port in prosody config + sed -i 's/"443"/"4445"/g' $PROSODY_HOST_CONFIG + invoke-rc.d prosody restart || true + fi fi # Enable turn server in config.js diff --git a/doc/debian/jitsi-meet-prosody/prosody.cfg.lua-jvb.example b/doc/debian/jitsi-meet-prosody/prosody.cfg.lua-jvb.example index 407da6c3ec93..3866d328afe7 100644 --- a/doc/debian/jitsi-meet-prosody/prosody.cfg.lua-jvb.example +++ b/doc/debian/jitsi-meet-prosody/prosody.cfg.lua-jvb.example @@ -6,8 +6,8 @@ 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 = "stun", host = "jitmeet.example.com", port = "4446" }, + { type = "turn", host = "jitmeet.example.com", port = "4446", transport = "udp" }, { type = "turns", host = "jitmeet.example.com", port = "443", transport = "tcp" } }; @@ -43,7 +43,7 @@ VirtualHost "jitmeet.example.com" c2s_require_encryption = false Component "conference.jitmeet.example.com" "muc" - storage = "null" + storage = "memory" modules_enabled = { "muc_meeting_id"; "muc_domain_mapper"; @@ -55,11 +55,13 @@ Component "conference.jitmeet.example.com" "muc" -- internal muc component Component "internal.auth.jitmeet.example.com" "muc" - storage = "null" + storage = "memory" modules_enabled = { "ping"; } admins = { "focusUser@auth.jitmeet.example.com", "jvb@auth.jitmeet.example.com" } + muc_room_locking = false + muc_room_default_public_jids = true VirtualHost "auth.jitmeet.example.com" authentication = "internal_plain" diff --git a/doc/debian/jitsi-meet-turn/coturn-certbot-deploy.sh b/doc/debian/jitsi-meet-turn/coturn-certbot-deploy.sh new file mode 100644 index 000000000000..6bc9f55dd203 --- /dev/null +++ b/doc/debian/jitsi-meet-turn/coturn-certbot-deploy.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +set -e + +COTURN_CERT_DIR="/etc/coturn/certs" +TURN_CONFIG="/etc/turnserver.conf" + +# create a directory to store certs if it does not exists +if [ ! -d "$COTURN_CERT_DIR" ]; then + mkdir -p $COTURN_CERT_DIR + chown -R turnserver:turnserver /etc/coturn/ + chmod -R 700 /etc/coturn/ +fi + +# This is a template and when copied to /etc/letsencrypt/renewal-hooks/deploy/ +# during creating the Let's encrypt certs script +# jitsi-meet.example.com will be replaced with the real domain of deployment +for domain in $RENEWED_DOMAINS; do + case $domain in + jitsi-meet.example.com) + # Make sure the certificate and private key files are + # never world readable, even just for an instant while + # we're copying them into daemon_cert_root. + umask 077 + + cp "$RENEWED_LINEAGE/fullchain.pem" "$COTURN_CERT_DIR/$domain.fullchain.pem" + cp "$RENEWED_LINEAGE/privkey.pem" "$COTURN_CERT_DIR/$domain.privkey.pem" + + # Apply the proper file ownership and permissions for + # the daemon to read its certificate and key. + chown turnserver "$COTURN_CERT_DIR/$domain.fullchain.pem" \ + "$COTURN_CERT_DIR/$domain.privkey.pem" + chmod 400 "$COTURN_CERT_DIR/$domain.fullchain.pem" \ + "$COTURN_CERT_DIR/$domain.privkey.pem" + + if [ -f $TURN_CONFIG ] && grep -q "jitsi-meet coturn config" "$TURN_CONFIG" ; then + echo "Configuring turnserver" + sed -i "/^cert/c\cert=\/etc\/coturn\/certs\/${domain}.fullchain.pem" $TURN_CONFIG + sed -i "/^pkey/c\pkey=\/etc\/coturn\/certs\/${domain}.privkey.pem" $TURN_CONFIG + fi + service coturn restart + ;; + esac +done + diff --git a/doc/debian/jitsi-meet-turn/turnserver.conf b/doc/debian/jitsi-meet-turn/turnserver.conf index e8fc9e37a368..584431f6bafc 100644 --- a/doc/debian/jitsi-meet-turn/turnserver.conf +++ b/doc/debian/jitsi-meet-turn/turnserver.conf @@ -1,5 +1,4 @@ # jitsi-meet coturn config. Do not modify this line -lt-cred-mech use-auth-secret keep-address-family static-auth-secret=__turnSecret__ @@ -8,7 +7,7 @@ cert=/etc/jitsi/meet/jitsi-meet.example.com.crt pkey=/etc/jitsi/meet/jitsi-meet.example.com.key no-tcp -listening-port=443 +listening-port=4446 tls-listening-port=4445 external-ip=__external_ip_address__ diff --git a/doc/quick-install.md b/doc/quick-install.md index e751bd9fd7de..a7b64aa8d7a3 100644 --- a/doc/quick-install.md +++ b/doc/quick-install.md @@ -29,7 +29,7 @@ wget -qO - https://download.jitsi.org/jitsi-key.gpg.key | sudo apt-key add - ### Install Jitsi Meet _Note_: The installer will check if [Nginx](https://nginx.org/) or [Apache](https://httpd.apache.org/) is present (in that order) and configure a virtualhost within the web server it finds to serve Jitsi Meet. If none of the above is found it then defaults to Nginx. -If you are already running Nginx on port 443 on the same machine you better skip the turnserver configuration as it will conflict with your current port 443, so use the command `apt install --no-install-recommends jitsi-meet`. +If you are already running Nginx on port 443 on the same machine turnserver configuration will be skipped as it will conflict with your current port 443. ```sh # Ensure support is available for apt repositories served via HTTPS diff --git a/resources/install-letsencrypt-cert.sh b/resources/install-letsencrypt-cert.sh index 064e6ab8010e..51f1f688a859 100755 --- a/resources/install-letsencrypt-cert.sh +++ b/resources/install-letsencrypt-cert.sh @@ -14,6 +14,8 @@ echo "- Download certbot-auto from https://dl.eff.org to /usr/local/sbin" echo "- Install additional dependencies in order to request Let’s Encrypt certificate" echo "- If running with jetty serving web content, will stop Jitsi Videobridge" echo "- Configure and reload nginx or apache2, whichever is used" +echo "- Configure the coturn server to use Let's Encrypt certificate and add required deploy hooks" +echo "- Add command in weekly cron job to renew certificates regularly" echo "" echo "You need to agree to the ACME server's Subscriber Agreement (https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf) " echo "by providing an email address for important account notifications" @@ -40,10 +42,21 @@ CERT_CRT="/etc/letsencrypt/live/$DOMAIN/fullchain.pem" if [ -f /etc/nginx/sites-enabled/$DOMAIN.conf ] ; then + TURN_CONFIG="/etc/turnserver.conf" + TURN_HOOK=/etc/letsencrypt/renewal-hooks/deploy/0000-coturn-certbot-deploy.sh + if [ -f $TURN_CONFIG ] && grep -q "jitsi-meet coturn config" "$TURN_CONFIG" ; then + mkdir -p $(dirname $TURN_HOOK) + + cp /usr/share/jitsi-meet-turnserver/coturn-certbot-deploy.sh $TURN_HOOK + chmod u+x $TURN_HOOK + sed -i "s/jitsi-meet.example.com/$DOMAIN/g" $TURN_HOOK + fi + ./certbot-auto certonly --noninteractive \ --webroot --webroot-path /usr/share/jitsi-meet \ -d $DOMAIN \ - --agree-tos --email $EMAIL + --agree-tos --email $EMAIL \ + --deploy-hook $TURN_HOOK echo "Configuring nginx" @@ -59,16 +72,6 @@ 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 \ @@ -90,27 +93,6 @@ elif [ -f /etc/apache2/sites-enabled/$DOMAIN.conf ] ; then echo "service apache2 reload" >> $CRON_FILE service apache2 reload -else - service jitsi-videobridge stop - - ./certbot-auto certonly --noninteractive \ - --standalone \ - -d $DOMAIN \ - --agree-tos --email $EMAIL - - echo "Configuring jetty" - - CERT_P12="/etc/jitsi/videobridge/$DOMAIN.p12" - CERT_JKS="/etc/jitsi/videobridge/$DOMAIN.jks" - # create jks from certs - openssl pkcs12 -export \ - -in $CERT_CRT -inkey $CERT_KEY -passout pass:changeit > $CERT_P12 - keytool -importkeystore -destkeystore $CERT_JKS \ - -srckeystore $CERT_P12 -srcstoretype pkcs12 \ - -noprompt -storepass changeit -srcstorepass changeit - - service jitsi-videobridge start - fi # the cron file that will renew certificates diff --git a/resources/prosody-plugins/mod_auth_token.lua b/resources/prosody-plugins/mod_auth_token.lua index 815f49405d36..9c8fdff3d379 100644 --- a/resources/prosody-plugins/mod_auth_token.lua +++ b/resources/prosody-plugins/mod_auth_token.lua @@ -37,8 +37,8 @@ function init_session(event) end end -module:hook("bosh-session", init_session); -module:hook("websocket-session", init_session); +module:hook_global("bosh-session", init_session); +module:hook_global("websocket-session", init_session); function provider.test_password(username, password) return nil, "Password based auth not supported";