Script for Autoscaling JVB

Hi All,

In order to allow autoscaling of JVB, there are a few steps required:

Signalling server:

  1. Add mod_admin_rest module in prosody module folder /usr/lib/prosody/modules/mod_admin_rest.lua. (https://github.com/wltsmrz/mod_admin_rest)
  2. Modify /etc/prosody/prosody.cfg.lua and add an admin account (e.g. admin@meet.jit.si) and enable admin_rest module.
  3. Reload prosody.
  4. Open port 5280 access to the JVB instances.

JVB image server:
4. On a fresh install of JVB2, modify /usr/share/jitsi-videobridge/jvb.sh and add the following lines on top

RAND=`openssl rand -hex 5`
USERNAME=jvb$RAND
BRIDGE=bridge$RAND
JVB_SECRET=`openssl rand -hex 10`
NICKNAME=`uuidgen`
LOCAL_ADDRESS=`hostname -I | awk '{print $1}'`
PUBLIC_ADDRESS=`curl ifconfig.me`
sed -i "s/\(JVB_SECRET=\).*\$/\1${JVB_SECRET}/" /etc/jitsi/videobridge/config
sed -i "s/\(org.jitsi.videobridge.xmpp.user.shard.USERNAME=\).*\$/\1${USERNAME}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.jitsi.videobridge.xmpp.user.shard.PASSWORD=\).*\$/\1${JVB_SECRET}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.jitsi.videobridge.xmpp.user.shard.MUC_NICKNAME=\).*\$/\1${NICKNAME}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=\).*\$/\1${LOCAL_ADDRESS}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=\).*\$/\1${PUBLIC_ADDRESS}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.jitsi.videobridge.octo.BIND_ADDRESS=\).*\$/\1${LOCAL_ADDRESS}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.jitsi.videobridge.octo.PUBLIC_ADDRESS=\).*\$/\1${PUBLIC_ADDRESS}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.jitsi.videobridge.REGION=\).*\$/\1${BRIDGE}/" /etc/jitsi/videobridge/sip-communicator.properties
URL="http://meet.jit.si:5280/admin_rest/user/$USERNAME"
curl --location --request POST $URL --header 'Content-Type: application/json' --header 'Host: auth.meet.jit.si' --header 'Authorization: Basic YWRtaW5AbWVldC5qaXQuc2k6cGFzc3dvcmQ=' --data '{"password":"'"$JVB_SECRET"'"}'

What this does is generate a random JVB username and password and register to prosody by a webservice call.

We have implented this and it is working well for us. Additionally, make sure that jvb2 is setup properly before modifying jvb.sh, things such as updating ca cert should be in place.

Regards,
Anthony

You can use same jvb username and password just different nickname, that way you create the username and password once.

Thanks for the tip!

Can you share me how to use admin_rest module and where can I get this Authorization token?

Hi,

We do not use token in our implementation but the rest call its a curl to prosody. It uses basic authentication which you can generate here but of course you must have registered the user in prosody before being able to use that account.

1 Like

Here is step by step I did to my prosody.

  1. added mod_admin_rest in prosody.cfg.lua
  2. Then I restart prosody service.
  3. Then I register one user.

I can’t hit api with that user credential like you said.

{"result":"Host does not exist or is malformed"}

Above error return. Can you please guide me your step by step? Thanks a lot

Make sure you add this to your header

--header 'Host: auth.meet.your.domain'
1 Like

I copy your url and change my credentials and host , then still got this error.

Can you try adding this config in your prosody.cfg.lua

admins = { admin@auth.meet.your.domain }
component_interface = "0.0.0.0"

Hi Anthony ,

I am also trying to set up multi JVB platform for auto-scaling.Do you have any documents or step by step guide which can help me to achieve the same .Your help would be appreciated.

Hi,

You can try the following:

  1. Register jvb in prosody server
prosodyctl register jvb auth.meet.yourdomain yourjvbpassword
  1. Spin up a new jvb instance and install jvb only.
  2. You may follow this sample for /etc/jitsi/videobridge/sip-communicator.properties
org.jitsi.videobridge.xmpp.user.shard.DISABLE_CERTIFICATE_VERIFICATION=true
org.ice4j.ice.harvest.DISABLE_AWS_HARVESTER=true
org.jitsi.videobridge.ENABLE_STATISTICS=true
org.jitsi.videobridge.STATISTICS_TRANSPORT=muc
org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=meet.yourdomain
org.jitsi.videobridge.xmpp.user.shard.DOMAIN=auth.meet.yourdomain
org.jitsi.videobridge.xmpp.user.shard.USERNAME=jvb
org.jitsi.videobridge.xmpp.user.shard.PASSWORD=yourjvbpassword
org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS=jvbbrewery@internal.auth.meet.yourdomain
org.jitsi.videobridge.xmpp.user.shard.MUC_NICKNAME=1cc60513-7064-4c47-afee-a838eb29a58c
org.jitsi.videobridge.DISABLE_TCP_HARVESTER=false
org.jitsi.videobridge.TCP_HARVESTER_PORT=4443
org.jitsi.videobridge.TCP_HARVESTER_MAPPED_PORT=443
org.jitsi.videobridge.TCP_HARVESTER_SSLTCP=true
org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=172.0.0.1
org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=11.22.33.44
  1. Modify /usr/share/jitsi-videobridge/jvb.sh and add this on top
RAND=`openssl rand -hex 5`
USERNAME=jvb
BRIDGE=bridge$RAND
JVB_SECRET=yourjvbpassword
NICKNAME=`uuidgen`
LOCAL_ADDRESS=`hostname -I | awk '{print $1}'`
PUBLIC_ADDRESS=`curl ifconfig.me`
sed -i "s/\(JVB_SECRET=\).*\$/\1${JVB_SECRET}/" /etc/jitsi/videobridge/config
sed -i "s/\(org.jitsi.videobridge.xmpp.user.shard.USERNAME=\).*\$/\1${USERNAME}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.jitsi.videobridge.xmpp.user.shard.PASSWORD=\).*\$/\1${JVB_SECRET}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.jitsi.videobridge.xmpp.user.shard.MUC_NICKNAME=\).*\$/\1${NICKNAME}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=\).*\$/\1${LOCAL_ADDRESS}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=\).*\$/\1${PUBLIC_ADDRESS}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.jitsi.videobridge.octo.BIND_ADDRESS=\).*\$/\1${LOCAL_ADDRESS}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.jitsi.videobridge.octo.PUBLIC_ADDRESS=\).*\$/\1${PUBLIC_ADDRESS}/" /etc/jitsi/videobridge/sip-communicator.properties
sed -i "s/\(org.jitsi.videobridge.REGION=\).*\$/\1${BRIDGE}/" /etc/jitsi/videobridge/sip-communicator.properties
  1. Restart jvb and check for any errors.
  2. If no errors, enable auto start
systemctl enable jitsi-videobridge2
  1. Shutdown server and create your image and autoscaling.

Hi @waiyanwinhtain,

You may follow the guide above. It does not require the mod_admin_rest anymore as it is using the same jvb account in all autoscaled instances.

1 Like

Thanks Anthony.It works fine now .

Does this work on Ubuntu 18.04?

Can I know which version you have tested this on?

Yes it works on Ubuntu 18.04 which we are using now. It also works on RHEL/CentOS if you know how to port the jar files and startup scripts.

Why do you prefer to use a jvb.sh modification, instead of a system startup script? Like for example rc.local or a custom systemd service?
rc.local works well and is straightforward, you only need to change the nickname - everything else can be pre-set in the jvb config files.

A custom modification in jvb.sh means you have to take care it’s not being overwritten on package upgrades, while rc.local is a part of the system configuration and won’t be changed on upgrades.

For example something like this in /etc/rc.local:

sed -i -e “s/.*MUC_NICKNAME=.*/org.jitsi.videobridge.xmpp.user.shard.MUC_NICKNAME=`uuidgen`/” /etc/jitsi/videobridge/sip-communicator.properties

1 Like

Or even better:

sed -i -e “s/MUC_NICKNAME=.*/MUC_NICKNAME=`uuidgen`/” /etc/jitsi/videobridge/sip-communicator.properties

This way you won’t touch the “shard” name and you can have a properties file with multiple shards for the JVB to connect to, you change only its nickname. :wink:
If you are using AWS or something similar and you have IDs of the instances, you can use these instanceIDs for nicknames, so that you can recognize the JVBs easier in the logs.

1 Like

I have these two:

/etc/systemd/system/jvb-config.service
/usr/local/sbin/jvb-config

sed changes only the active MUC_NICKNAME line

1 Like

@Yasen_Pramatarov1 @emrah
Thanks for the tips guys!

How de we configure in prosody in meet server?
Keep it default or do we need to modify?
And also jvb config need to modify?
Follow are my configs
/etc/jitsi/videobridge/config

# Jitsi Videobridge settings

# sets the XMPP domain (default: none)
JVB_HOSTNAME=meet.somethig.com

# sets the hostname of the XMPP server (default: domain if set, localhost otherwise)
JVB_HOST=meet.something.com

# sets the port of the XMPP server (default: 5275)
JVB_PORT=5347

# sets the shared secret used to authenticate to the XMPP server
JVB_SECRET=some_password

# extra options to pass to the JVB daemon
#JVB_OPTS="--apis=,rest,xmpp --subdomain=videobridge"
JVB_OPTS=""

# adds java system props that are passed to jvb (default are for home and logging config file)
JAVA_SYS_PROPS="-Dnet.java.sip.communicator.SC_HOME_DIR_LOCATION=/etc/jitsi -Dnet.java.sip.communicator.SC_HOME_DIR_NAME=videobridge -Dnet.java.sip.communicator.SC_LOG_DIR_LOCATION=/var/log/jitsi -Djava.util.logging.config.file=/etc/jitsi/videobridge/logging.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.jitsi.videobridge.ENABLE_STATISTICS=true
org.jitsi.videobridge.STATISTICS_TRANSPORT=muc
org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=meet.something.com
org.jitsi.videobridge.xmpp.user.shard.DOMAIN=auth.meet.something.com
org.jitsi.videobridge.xmpp.user.shard.USERNAME=jvb
org.jitsi.videobridge.xmpp.user.shard.PASSWORD=mypassword
org.jitsi.videobridge.xmpp.user.shard.DISABLE_CERTIFICATE_VERIFICATION=true
org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS=JvbBrewery@internal.auth.meet.something.com
org.jitsi.videobridge.xmpp.user.shard.MUC_NICKNAME=6e9fef4e-0727-4597-9c03-67d92cdbac08
org.jitsi.videobridge.TCP_HARVESTER_PORT=4443
org.jitsi.videobridge.TCP_HARVESTER_MAPPED_PORT=443
org.jitsi.videobridge.TCP_HARVESTER_SSLTCP=true
org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=172.31.29.54
org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=11.22.33.44

With above configs, I got the following error logs from prosody and jvb
prosody.log

Jun 29 14:55:19 jcp55cac213bed0 info    component disconnected: nil (false)
Jun 29 14:55:24 jcp55cac27593b0 info    Incoming Jabber component connection
Jun 29 14:55:24 mod_component   info    Disconnecting component, <stream:error> is: <stream:error><host-unknown xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xmlns='urn:ietf:params:xml:ns:xmpp-streams'>jitsi-videobridge.meet.something.com does not match any configured external components</text></stream:error>

jvb.log

=====>: org_jitsi_modified_sctp4j_SctpJni.c calling init
=====>: org_jitsi_modified_sctp4j_SctpJni.c about to set SCTP_DEBUG_ALL
2020-06-29 14:51:15.731 INFO: [27] AbstractHealthCheckService.run#171: Performed a successful health check in PT1.089S. Sticky failure: false
2020-06-29 14:51:19.704 SEVERE: [32] ComponentMain.lambda$getConnectCallable$0#293: host-unknown, host:meet.something.com, port:5347
org.xmpp.component.ComponentException: host-unknown
        at org.jivesoftware.whack.ExternalComponent.connect(ExternalComponent.java:243)
        at org.jivesoftware.whack.ExternalComponentManager.addComponent(ExternalComponentManager.java:242)
        at org.jivesoftware.whack.ExternalComponentManager.addComponent(ExternalComponentManager.java:222)
        at org.jitsi.meet.ComponentMain.lambda$getConnectCallable$0(ComponentMain.java:285)
        at org.jitsi.retry.RetryStrategy$TaskRunner.run(RetryStrategy.java:193)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

Coz I am very new to this application.
I really appreciate your help and guide.