Self Hosting Jitsi Meet Server on Ubuntu

Jitsi Meet is a free and open-source alternative to popular video conferencing services like Google Meet, Zoom, and Microsoft Teams. All Jitsi meetings are ephemeral, and encrypted using DTLS-SRTP, and can operate in 2 ways, either via peer-to-peer mode for 1-to-1 meetings or via the …

Jitsi Meet is a free and open-source alternative to popular video conferencing services like Google Meet, Zoom, and Microsoft Teams.

All Jitsi meetings are ephemeral, and encrypted using DTLS-SRTP, and can operate in 2 ways, either via peer-to-peer mode for 1-to-1 meetings or via the Jitsi Videobridge ; Jitsi also has support for end-to-end encryption.

There’s a free hosted version of Jitsi Meet that you can use for up to 100 participants, they also a premium Jitsi as a Service by 8×8, the parent company of Jitsi.

This tutorial will cover pretty much everything you need to know about self-hosting your private Jitsi Meet server to host meetings and video calls.

Alright, let’s get into it.

Step1: Creating a Virtual Machine

You’ll need a Linux virtual machine with at least these minimum specs for proper functioning:

  • 1 GB of RAM
  • 1 CPU cores

Although, you’ll need to increase your RAM and CPU depending on the number of users, pick a server location that’s closest to you for low latency.

I’ll be using an Ubuntu VM on Linode, although, Debian and other Debian-based distros should be fine, you’ll need to use Docker if you want to use any other distro.

Step 2: Updating the DNS Entry

Note down the IP address of the virtual machine, and go to your domain registrar and add an A record with the IP address of the VM.

I’ll be using jitsi.example.com as an example in the tutorial from now on.

Step 2.1: Setting up Fully Qualified Domain Name

Jitsi recommends setting up a FQDN, you can do so using the following command:

sudo hostnamectl set-hostname jitsi.example.com

Next up, add the same FQDN in the /etc/hosts file:

# Opening hosts file
sudo nano /etc/hosts

Add 123.45.67.89 jitsi.example.com to that file, put your server IP & hostname:

# Output
# /etc/hosts
127.0.0.1       localhost

# The following lines are desirable for IPv6 capable hosts
::1               localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters

123.45.67.89    jitsi.example.com

We’ll be securing connections to our Jitsi Meet instance via a trusted SSL certificate from Let’s Encrypt.

Step 3: Configuring the Virtual Machine for Jitsi Meet

Now, let’s configure our server:

Step 3.1: Connect to the Server via SSH

Open up the terminal on your device, and run this command:

ssh root@123.45.67.89

If you chose a username while creating the virtual machine, use that instead of root, and replace 123.45.67.89 with the IP address of your VM.

You’ll be prompted with “The authenticity of host…”, just type yes, and then enter the password.

Step 3.2: Configure Automatic Updates

Let’s update packages and configure automatic updates so that our server gets patched automatically.

# Update packages
sudo apt update && apt upgrade

# Install unattended-upgrades
sudo apt install unattended-upgrades

# Configure unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

# Test unattended-upgrades
sudo unattended-upgrades --dry-run --debug

Step 3.3: Creating a “sudo” user

If your cloud provider didn’t ask you to choose a username while creating it, you are given root access to your server; it is recommended to not use the “root” user, which has unlimited privileges and can execute any command, even ones that could potentially disrupt your server.

Let’s create a new user on a server that can use “sudo” to do day-to-day administration tasks.

# Create a new user
adduser username

# Add user to the "sudo" group
usermod -aG sudo username

# Check user's group
groups username

# Switching users
su - username
su - root

Step 3.4: Configure SSH Keys

Using SSH keys instead of passwords provides you with better security, as SSH keys are far more long and complex than any password could ever be; you can also add an extra password to the SSH keys, requiring both the SSH key and the password to access the server.

Log out of the server or just open up a new terminal on your computer to create SSH keys:

# Create ssh keys
ssh-keygen -b 4096 

# View ssh keys
ls -l ~/.ssh

# Add public key to server
ssh-copy-id -i ~/.ssh/keyname.pub username@123.45.67.89

# Switch ssh keys on client
ssh-add ~/.ssh/keyname

During the ssh-keygen process, you’ll be prompted for file location, use the default one or give a new location by typing in /home/username/.ssh/keyname, and enter a strong password for the SSH key.

In the .ssh folder, there’ll be two files, the one with “.pub” extension is your public key, the other one is your private key, never share the private key with anyone.

You might get a message like Could not open a connection to your authentication agent when switching SSH keys, you’ll need to start ssh-agent first using:

eval `ssh-agent`

Once done, you can log in to the server by just using the ssh username@123.45.67.89 command without entering the user password, although you will need to enter the password of your SSH key.

Step 3.5: Disable root login

Now that we have a new user with limited privileges that can run “sudo” commands and can access the server via SSH keys; let’s lock down our root user, as it is usually the most targeted account by hackers.

To do so, type in sudo nano /etc/ssh/sshd_config, and update PermitRootLogin to no and add AllowUsers username as shown below:

Disable root login via SSH

Optionally, you can also go ahead and disable password-based login via SSH for all users, including the new user account we just created, by updating these values in the same sshd config file:

# Disable password-based login via ssh for all users [optional]
PasswordAuthentication no
ChallengeResponseAuthentication no

Once done, save the file using Ctrl + O & Ctrl + X, and restart the sshd service using this command:

sudo systemctl restart sshd

Now, your server is ready to install the Jitsi Meet, let’s get into it.

Step 4: Installing Jitsi Meet

You’ll need curl to download the Jitsi, install it if it doesn’t come with your installation:

sudo apt install curl

Step 4.1: Adding Jitsi Repository

Let’s start by adding the Jitsi repository our package source:

curl 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 > /dev/null

# update all package sources
sudo apt update

Step 4.2: Configuring Firewall

Jitsi needs the following ports need to be open in your firewall, to allow traffic to the Jitsi Meet server:

  • 80 TCP — for SSL certificate verification / renewal with Let’s Encrypt
  • 443 TCP — for general access to Jitsi Meet
  • 10000 UDP — for general network video/audio communication
  • 3478 UDP — for querying the stun server (coturn, optional, needs config.js change to enable it)
  • 5349 TCP — for fallback network video/audio communications over TCP (when UDP is blocked for example), served by coturn

We’ll additionally also need to allow port 22 for SSH access, you can update firewall rules in UFW using these commands:

# Updating Firewall Rules
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 10000/udp
sudo ufw allow 3478/udp
sudo ufw allow 5349/tcp
sudo ufw allow 22/tcp

# Enabling UFW
sudo ufw enable

Check UFW firewall status:

sudo ufw status verbose
# Output
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
80/tcp                     ALLOW IN    Anywhere
443/tcp                    ALLOW IN    Anywhere
10000/tcp                  ALLOW IN    Anywhere
3478/tcp                   ALLOW IN    Anywhere
5349/tcp                   ALLOW IN    Anywhere
22/tcp                     ALLOW IN    Anywhere
80/tcp (v6)                ALLOW IN    Anywhere (v6)
443/tcp (v6)               ALLOW IN    Anywhere (v6)
10000/tcp (v6)             ALLOW IN    Anywhere (v6)
3478/tcp (v6)              ALLOW IN    Anywhere (v6)
5349/tcp (v6)              ALLOW IN    Anywhere (v6)
22/tcp (v6)                ALLOW IN    Anywhere (v6)

Step 4.3: Installing Jitsi Meet

Now, our server is ready for Jitsi installation:

sudo apt install jitsi-meet

This’ll install everything your Jitsi Meet server will need, you’ll be prompted twice:

Jitsi Meet Hostname Configuration

Type in the FQDN and select OK (press Tab to select different options).

There’ll be another option, asking for SSL configuration:

Jitsi Meet SSL Configuration

Select “Generate a new self-signed certificate” option, we’ll install a free SSL certificate from Let’s Encrypt later.

Step 4.4: Installing SSL Certificate

Alright, let’s secure the connection to our Jitsi Meet server using an SSL certificate from Let’s Encrypt:

sudo /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh

You’ll be asked to enter an email address for important account notifications.

# Output
-------------------------------------------------------------------------
This script will:
- Need a working DNS record pointing to this machine(for domain jitsi.nas.codes)
- Download certbot-auto from https://dl.eff.org to /usr/local/sbin
- Install additional dependencies in order to request Let’s Encrypt certificate
- If running with jetty serving web content, will stop Jitsi Videobridge
- Configure and reload nginx or apache2, whichever is used
- Configure the coturn server to use Let's Encrypt certificate and add required deploy hooks
- Add command in weekly cron job to renew certificates regularly

You need to agree to the ACME server's Subscriber Agreement (https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf)
by providing an email address for important account notifications
Enter your email and press [ENTER]: mail@example.com

It’ll take a few moments, and if all goes well, you’ll be greeted with a screen like this:

# Output 
- Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/jitsi.example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/jitsi.example.com/privkey.pem
   Your cert will expire on XXXX-XX-XX. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Configuring nginx

Step 5: Create a Jitsi Meeting

Your private Jitsi Meet server is up and running, go type in the URL in your web browser, and you should see something like this:

Private Self-Hosted Jitsi Meet

You can create a new meeting right from that page, you can also use native Jitsi Meet apps.

That’s it folks!

I’ll be updating this guide soon with guides on blocking public access to your Jitsi Meet server, you can try following this guide by Jitsi.org