Self-Hosted Jitsi Server

18. December, 2022 5 min read Tutorial

A personal Jitsi Server on Ubuntu

Are you tired of Google Meets, Skype or Zoom? Want an open-source solution that doesn't spy on you in the background? Say welcome to Jitsi Meet.

I’m not a privacy advocate, but I wanted to play around with Jitsi Meet for a while now that meet.switch.ch has closed its doors. This a great excuse to see if I can host Jitsi on my own and allow access from the outside.

Setting up Jitsi Meet isn’t that difficult. The team provides a great quickstart guide. That doesn’t mean it is without its challenges, especially when you are not following the installation instructions 🫣. You can run into encryption issues when the domain isn’t incorrectly set up or connection troubles when a package is missing.

Getting started

I will start from a standard Ubuntu server installation on a minted VM. Always ensure Ubuntu is up to date, SSH into the VM and run:

sudo apt update
sudo apt upgrade
sudo apt full-upgrade

Next, we must figure out how to reach the server before installing Jitsi Meet. My scenario resolves around https://meet.dini.dev/. The service should be reachable through that domain from the outside, encrypted. For that to happen:

  • I need to configure my DNS provider to point to my WAN IP and refresh it, as it is not a static IP.
  • I must ensure my firewall accepts and forwards incoming connections to the Ubuntu server.

Configuring the DNS

I use dnsimple to manage my domains. The first step is to go to the configuration settings and set up a new subdomain for https://meet.dini.dev/ that points to my current WAN IP address. I can get that quickly by running ip -a in a terminal window.

The problem is that my WAN IP is dynamic and changes over time. To solve this, I could either get a static IP or let dnsimple know about any changes. dnsimple provides some tools to help us with this. Their ddns.sh script is what I’m looking for. SSH into the Ubuntu instance, run vim ~/ddns.sh and add the following content:

#!/bin/bash

TOKEN="{% token from user settings > user access tokens %}"
ACCOUNT_ID="{% account id shown under account > automation %}"
ZONE_ID="{% your primary domain name %}"
RECORD_ID="{% the record id from one of the DNS records %}"
IP=`curl --ipv4 -s http://icanhazip.com/`

curl -H "Authorization: Bearer $TOKEN" \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     -X "PATCH" \
     -i "https://api.dnsimple.com/v2/$ACCOUNT_ID/zones/$ZONE_ID/records/$RECORD_ID" \
     -d "{\"content\":\"$IP\"}"

The TOKEN, ACCOUNT_ID, ZONE_ID and RECORD_ID need to be replaced accordingly. I added hints in the script on where to get it from dnsimple.

Next, run sudo chmod +x ./ddns.sh to allow the script to be executed through crontab. A crontab can easily be set up by running crontab -e. I decided to set up a crontab that runs the script every 5 minutes, so add the following at the end of the file:

*/5 * * * 1-4 /path/to/ddns.sh &

This command will update dnsimple’s records every 5 minutes with my current WAN IP address 🥳. A simple way of creating a dynamic DNS. Test if the crontab is working through sudo service cron start and check the logs by running systemctl status cron.

Configuring the Firewall

I’m running Pi-hole as my primary local DNS Server. As such, I can trick my local network into forwarding an incoming request from https://meet.dini.dev/ to redirect to my Jitsi server.

Login to Pi-hole and select “DNS records” from the menu. Choose to add a “new domain/IP combination” and add the hostname (meet.dini.dev) and IP address of the Ubuntu server accordingly.

Next, we need to ensure traffic through the ports is routed correctly. Go to your routers firewall settings and make sure the following ports are forwarded from your WAN IP to the Jitsi server:

  • TCP: 80,443,5349
  • UDP: 3478,10000

To enable additional security, enable ufw by running sudo ufw enable on the Jitsi server followed by:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3478/udp
sudo ufw allow 5349/tcp
sudo ufw allow 10000/udp

Check the status using sudo ufw status. Next, we install Jitsi Meet!

Installing Jitsi Meet

Before starting the installation, ensure the steps above are working correctly. I made a mistake installing Jitsi first, which required setting up the encryption manually afterwards.

To get started, run the following commands in sequence:

# preparing the server
sudo apt update
sudo apt install apt-transport-https gnupg2 nginx-full socat
sudo apt-add-repository universe
sudo apt update

# install dependencies
echo deb http://packages.prosody.im/debian $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list
wget https://prosody.im/files/prosody-debian-packages.key -O- | sudo apt-key add -
sudo apt install lua5.2

# setup the repository
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
sudo apt update

# start installation
sudo apt install jitsi-meet

You will be prompted to configure your hostname and SSL/TSL certificate. For the hostname, enter the domain you decided to go with (for me, meet.dini.dev). For the certificate, choose “Let’s Encrypt” if you do not want to upload your certificate.

The verification process will only be configured appropriately when the domain is set up correctly. However, you can create the certificates manually afterwards by running:

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

At this stage, the Jitsi Server is running and can be reached through the local IP address of the Ubuntu server or the hostname you have set up. That’s all there is to it 🫣.

Yatta

I now have my own personal Jitsi Meet server running on https://meet.dini.dev/ 🎉.

‘Till next time!