DEV Community

Cover image for How to Set up Cascaded Jitsi Videobridges
Kofi Mupati
Kofi Mupati

Posted on • Edited on

How to Set up Cascaded Jitsi Videobridges

INTRODUCTION

After self-hosting a Jitsi server, one will soon be required to add multiple videobridges to support the load.
I take you through a manual step in adding multiple videobridges. The understanding of this can help you write your ansible playbook for automating this process.

This article assumes the following:

  1. Ability to create and configure droplets on DigitalOcean.
  2. Set up a Jitsi server by following the self-hosting guide.
  3. Configured a subdomain for hosting your Jitsi server. I’ll use meet.kofimupati.com (At the time of reading the article I would have shut down the servers)

We’ll create and configure 2 additional video bridge servers:
jvb1 and jvb2 which will then be connected to our existing Jitsi server.

UPDATING JITSI SERVER CONFIGURATION

Modify the Videobridge Connected to the Jitsi Server
Jitsi Videobridge is a WebRTC compatible video router or SFU that lets build highly scalable video conferencing infrastructure (i.e., up to hundreds of conferences per server).”

Allow the following ports as well:

9090/tcp
9090/udp
5222/tcp
5222/udp
Enter fullscreen mode Exit fullscreen mode

Update the config: /etc/jitsi/videobridge/config

-- JVB_HOST=
++ JVB_HOST=meet.kofimupati.com
++ JVB_OPTS="--apis=rest,xmpp --subdomain=jitsi-videobridge"
++ AUTHBIND=yes
Enter fullscreen mode Exit fullscreen mode

Update jvb.conf: /etc/jitsi/videobridge/jvb.conf

The xmpp-client.configs.xmpp-server-1 values can be found in the default /etc/jitsi/videobridge/sip-communicator.properties

The region and relay-id under relay are defined to distinguish each video bridge in the cascaded videobridge setup.

videobridge {
  stats {
    enabled = true
    transports = [
      { type = "muc" }
    ]
  }

  apis {
    rest {
      enabled = true
    }
    xmpp-client {
      configs {
        xmpp-server-1 {
        hostname="meet.kofimupati.com"
        domain = "auth.meet.kofimupati.com"
        username = "jvb"
        password = "18YlmYSH"
        muc_jids = "JvbBrewery@internal.auth.kofimupati.com"
        muc_nickname = "08a74380-a3d3-4763-adf4-545c55743b3e"
      }
    }
   }
  }

  cc {
    max-time-between-calculations = 5 seconds
    bwe-change-threshold = 0.1
    padding-period = 10ms
    jvb-last-n = -1
    trust-bwe = false
  }

  http-servers {
    public {
    port = 9090
   }
 }

  websockets {
    enabled = true
    domain = "meet.kofimupati.com:443"
    tls = true
  }

  relay {
    enabled=true
    region="region1"
    relay-id="jitsi-videobridge"
  }

}
Enter fullscreen mode Exit fullscreen mode

Note: The use of sip-communicator.properties is currently deprecated.
Update the sip-communicator.properties: /etc/jitsi/videobridge/sip-communicator.properties

org.ice4j.ice.harvest.DISABLE_AWS_HARVESTER=true
org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSES=meet-jit-si-turnrelay.jitsi.net:443

++org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=10.106.0.3 #Private IP of the Server
++org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=178.62.18.4. #Public IP of the Server

org.jitsi.videobridge.ENABLE_STATISTICS=true

--org.jitsi.videobridge.STATISTICS_TRANSPORT=muc
++org.jitsi.videobridge.STATISTICS_TRANSPORT=muc,colibri

++org.jitsi.videobridge.STATISTICS_INTERVAL=2000

--org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=localhost
++org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=meet.kofimupati.com

org.jitsi.videobridge.xmpp.user.shard.DOMAIN=auth.meet.kofimupati.com
org.jitsi.videobridge.xmpp.user.shard.USERNAME=jvb
org.jitsi.videobridge.xmpp.user.shard.PASSWORD=18YlmYSH
org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS=JvbBrewery@internal.auth.meet.virtualcp.app
org.jitsi.videobridge.xmpp.user.shard.MUC_NICKNAME=be350741-2b3d-4829-95ee-a60c4fbae28b

++org.jitsi.videobridge.SINGLE_PORT_HARVESTER_PORT=10000
++org.jitsi.videobridge.TCP_HARVESTER_PORT=443
++org.jitsi.videobridge.octo.BIND_ADDRESS=10.106.0.3 #Private IP of the Server
++org.jitsi.videobridge.octo.PUBLIC_ADDRESS=178.62.18.4 #Public IP of the Server
++org.jitsi.videobridge.octo.BIND_PORT=4096
+++org.jitsi.videobridge.REGION=region1
Enter fullscreen mode Exit fullscreen mode

**Modify the Jicofo Configuration on the Jitsi Server
**It is responsible for managing media sessions between each of the participants and the video bridge. Link to repository

Update the config: /etc/jitsi/jicofo/config

--JICOFO_HOST=localhost
++JICOFO_HOST=meet.kofimupati.com
Enter fullscreen mode Exit fullscreen mode

Update the jicofo.conf: /etc/jitsi/jicofo/jicofo.conf

selection-strategy: This is used to define how “participants” on a call are assigned to videobridges.
octo: Enabling octo is what causes Jicofo to assign “participants” in a single conference across multiple videobridges.

jicofo {
  xmpp: {
    client: {
    client-proxy: focus.meet.kofimupati.com
   }  
    trusted-domains: [ "recorder.meet.kofimupati.com" ]
  }

  bridge {
    brewery-jid: "JvbBrewery@internal.auth.meet.kofimupati.com"
    selection-strategy = SplitBridgeSelectionStrategy
  }

  octo {
    enabled = true
    id = "1"
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Modify the Jicofo Configuration on the Jitsi Server

Configure the app-config.js i.e **/etc/jitsi/meet/meet.kofimupati.com-config.js **to enable WebSocket and any configuration needed for your use case.
This might not be necessary for you.

--// websocket: 'wss://meet.kofimupati.com/' + subdir + 'xmpp-websocket',
++websocket: 'wss://meet.kofimupati.com/' + subdir + 'xmpp-websocket',

// Add the following line just before the section which begins with the comment // UI
openBridgeChannel: 'websocket',
Enter fullscreen mode Exit fullscreen mode

Modify the Prosody Configuration on the Jitsi Server

Prosody is the XMPP component of Jitsi that handles the messaging.
We also enable communication via WebSocket instead of BOSH which happens to be the default on a fresh installation.

Enable ports and allow all IPs to reach the prosody server by adding the following to /etc/prosody/prosody.cfg.lua

admin = {}
component_ports = { 5347 }
component_interface = "0.0.0.0"

--use_libevent = true
use_libevent = true

-- Uncomment websocket under HTTP modules
--"websocket"
"websocket"

-- Comment out VirtualHost "localhost" under the Virtual hosts section

VirtualHost "localhost"
--VirtualHost "localhost"
Enter fullscreen mode Exit fullscreen mode

Configure the domain-specific prosody settings by modifying /etc/prosody/conf.d/meet.virtualcp.app.cfg.lua

-- Add the following to allow the use of websocket with the low-level library.
cross_domain_bosh = false;
consider_bosh_secure = true;
cross_domain_websocket = true;
consider_websocket_secure = true;


-- Add smacks and websocket to modules enabled and configurations for smacks
modules_enables = {
  "smacks";
  "websocket";
}

smacks_max_unacked_stanzas = 5;
smacks_hibernation_time = 60;
smacks_max_hibernated_sessions = 1;
smacks_max_old_sessions = 1;
Enter fullscreen mode Exit fullscreen mode

**Modify the Nginx Configuration on the Jitsi Server
**Add the following to enable WebSocket connection between external video bridges which will be configured later. The following nginx location blocks are needed for the cascaded videobridges to work.

Add them after the location ~ ^/colibri-ws/default-id/(.*) block.

location ~ ^/colibri-ws/([0-9.]*)/(.*) {
  proxy_pass http://$1:9090/colibri-ws/$1/$2$is_args$args;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  tcp_nodelay on;
}

# colibri secure-octo relay websockets for jvb1

location ~ ^/colibri-relay-ws/default-id/(.*) {
  proxy_pass http://jvb1/colibri-relay-ws/default-id/$1$is_args$args;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  tcp_nodelay on;
}


location ~ ^/colibri-relay-ws/([0-9.]*)/(.*) {
  proxy_pass http://$1:9090/colibri-relay-ws/$1/$2$is_args$args;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  proxy_set_header Host meet.virtualcp.app;
  tcp_nodelay on;
}
Enter fullscreen mode Exit fullscreen mode

CONFIGURING EXTERNAL VIDEO BRIDGES

  1. Install just the jitsi-videobridge2 component on each of the external JVBs.

add jitsi package repository

curl -sL https://download.jitsi.org/jitsi-key.gpg.key | sudo sh -c 'gpg --dearmor > /usr/share/keyrings/jitsi-keyring.gpg'

echo "deb [signed-by=/usr/share/keyrings/jitsi-keyring.gpg] https://download.jitsi.org stable/" | sudo tee /etc/apt/sources.list.d/jitsi-stable.list

sudo apt install jitsi-videobridge2
Enter fullscreen mode Exit fullscreen mode
  1. During installation enter the domain of the Jitsi Server in the prompt that shows up i.e. meet.kofimupati.com in my case.

  2. Allow access to the following ports on the firewall.

    ufw allow 9090/tcp
    ufw allow 9090/udp
    ufw allow 5347/tcp
    ufw allow 5347/udp
    ufw allow 5222/tcp
    ufw allow 5222/udp
    ufw allow 10000/tcp
    ufw allow 10000/udp
    ufw allow 4096/tcp
    ufw allow 4096/udp
    ufw enable
Enter fullscreen mode Exit fullscreen mode
  1. Configure the VideoBridge Replace jvb.conf, sip-communicator.properties, and **config **on the external video bridge with what was configured on the Jitsi Server.

Using jvb1 as an example:

Changes to **/etc/jitsi/videobridge/config
*JVB_SECRET
* should have the same value for the main and external video bridges.

JVB_HOST=
JVB_SECRET=18YlmYSH
JVB_OPTS="--apis=rest,xmpp --subdomain=jvb1"
Enter fullscreen mode Exit fullscreen mode

Changes to ***/etc/jitsi/videobridge/jvb.conf

  • *Add **disable_certificate_verification = true to **xmpp-client.configs.xmpp-server-1
  • Set the **muc_nickname with the value found in sip-communicator.properties of the current external videobridge (jvb1) being configured.
  • Set a different region and relay-id for each external videobridge.
  • Add a server-id option to the WebSocket block of only the external videobridges. This value should be the Public IP of the videobridge server.
    videobridge {
      stats {
        enabled = true
        transports = [
          { type = "muc" }
        ]
      }

      apis {
        rest {
          enabled = true
        }
        xmpp-client {
          configs {
            xmpp-server-1 {
            hostname="meet.kofimupati.com"
            domain = "auth.meet.kofimupati.com"
            username = "jvb"
            password = "18YlmYSH"
            muc_jids = "JvbBrewery@internal.auth.kofimupati.com"
            muc_nickname = "44643c18-e111-4bfc-9fcc-29f57bb415d8"
            disable_certificate_verification = true
          }
        }
       }
      }

      cc {
        max-time-between-calculations = 5 seconds
        bwe-change-threshold = 0.1
        padding-period = 10ms
        jvb-last-n = -1
        trust-bwe = false
      }

      http-servers {
        public {
        port = 9090
       }
     }

      websockets {
        server-id = "203.500.130.37"
        enabled = true
        domain = "meet.kofimupati.com:443"
        tls = true
      }

      relay {
        enabled=true
        region="region2"
        relay-id="jvb1"
      }

    }
Enter fullscreen mode Exit fullscreen mode

Changes to /etc/jitsi/videobridge/sip-communicator.properties

--org.jitsi.videobridge.xmpp.user.shard
++org.jitsi.videobridge.xmpp.user.jvb1

org.ice4j.ice.harvest.DISABLE_AWS_HARVESTER=true
org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSES=meet-jit-si-turnrelay.jitsi.net:443

++org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=10.106.0.3 #Private IP of the jvb1
++org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=178.62.18.4. #Public IP of the jvb1

org.jitsi.videobridge.ENABLE_STATISTICS=true

--org.jitsi.videobridge.STATISTICS_TRANSPORT=muc
++org.jitsi.videobridge.STATISTICS_TRANSPORT=muc,colibri

++org.jitsi.videobridge.STATISTICS_INTERVAL=2000

--org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=localhost
++org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=meet.kofimupati.com

org.jitsi.videobridge.xmpp.user.jvb1.DOMAIN=auth.meet.kofimupati.com
org.jitsi.videobridge.xmpp.user.jvb1.USERNAME=jvb
org.jitsi.videobridge.xmpp.user.jvb1.PASSWORD=18YlmYSH
org.jitsi.videobridge.xmpp.user.jvb1.MUC_JIDS=JvbBrewery@internal.auth.meet.virtualcp.app
org.jitsi.videobridge.xmpp.user.jvb1.MUC_NICKNAME=44643c18-e111-4bfc-9fcc-29f57bb415d8
++org.jitsi.videobridge.xmpp.user.jvb1.DISABLE_CERTIFICATE_VERIFICATION=true

++org.jitsi.videobridge.SINGLE_PORT_HARVESTER_PORT=10000
++org.jitsi.videobridge.TCP_HARVESTER_PORT=443
++org.jitsi.videobridge.octo.BIND_ADDRESS=10.106.0.3 #Private IP of the jvb1
++org.jitsi.videobridge.octo.PUBLIC_ADDRESS=178.62.18.4 #Public IP of the jvb1
++org.jitsi.videobridge.octo.BIND_PORT=4096
+++org.jitsi.videobridge.REGION=region2
Enter fullscreen mode Exit fullscreen mode

Repeat the above external video bridge configuration steps for all the videobridges you want to use.

Conclusion

Jitsi is an open-source video conferencing solution that can serve most of your needs. You can self-host and use the **lib-meet-jitsi **to build whichever experience you want.

If you need help building your custom application on top of Jitsi, you know what to do 😉

Top comments (0)