Jitsi on server with dynamic IP

Hi,
I’ve got a Jitsi server (on Debian Bullseye) behind a NAT with dynamic IP (changes non-regular after a few weeks, because of upcoming ISP change probably daily IP change soon). There is a dynamic DNS installed on the router, so the server is always accessible. Unfortunately every time there is an IP change video/audio doesn’t work anymore without any error message at the client side. The following message appears in the syslog:
turnserver: 1319442: ERROR: A peer IP 192.168.1.11 denied in the range: 192.168.0.0-192.168.255.255 (192.168.1.11 is the IP inside the LAN).
I searched the forum and other people seem to have similar problems, but for them the public IP is somewhere in the config, either in the sip-communicator.properties or the turnserver.conf. For me in none of them I can find any reference to my public IP. But there is an entry denied-peer-ip=192.168.0.0-192.168.255.255 for the turnserver. I can fix the problem by restarting Jitsi without changing any configuration file, so the error message seems to be somewhat misleading. My question: Is there any way to a) make Jitsi independent of the public IP or b) make Jitsi check if the public IP and automatically adapt itself to it.
Best regards
Stefan

Welcome to the forum.

For audio and video to be transmitted between clients, the JVB (bridge) has to be accessible and its IP discoverable by clients. By default it communicates through port 10000. If for any reason the port is not accessible or the IP is not known, then clients cannot transmit media. When you restart JVB, it autodiscovers its IP address, which explains why restarting fixes your problem.

Thanks for the fast answer and explanation, but the question remains: Is it possible to make JVB automatically rediscover the public IP address every time a new meeting is started and not only during startup? Otherwise the only solution I can think of is to have a script running to check every minute or so if the public IP has changed and if yes => restart JVB. But that doesn’t seem to be ideal to me.

No, JVB can only autodiscover during a startup, so if you want to use dynamic IP, you would need to employ a script that checks your IP periodically and then restarts JVB if there’s a change.

to be pedantic, the IP address change does not cause this error message; what happens is that following the IP address change, your clients can’t access port 10000 anymore, and then try to use turn. This fails because coturn default configuration denies the access to a private IP address (for security reason). But it’s a separate problem.

Too bad, I wrote a simple script and a systemd file to make it a service. Not sure if it works, because I cannot provoke an IP change, it all depends on my ISP.
You just need to change your domain in the script (replace mydomain.tld with yours) and optionally change to another DNS server.

/usr/local/bin/jvb-dynip-restart.py

#!/usr/bin/env python3

import dns.resolver
import os
import syslog
import time

# config start

my_domain = 'mydomain.tld'
dns_to_use = '8.8.8.8'

# config end

last_ip = ''

dns_resolver = dns.resolver.Resolver()
dns_resolver.nameservers = [dns_to_use]


while True:
	r = dns_resolver.resolve(my_domain, 'A')
	for ipval in r:
		if ipval.to_text() != last_ip:
			last_ip = ipval.to_text()
			syslog.syslog(syslog.LOG_NOTICE, 'Public IP has changed: '+last_ip+', restarting jitsi-videobridge')
			os.system('systemctl restart jitsi-videobridge2.service')
	time.sleep(60)

/usr/lib/systemd/system/jvb-dynip-restart.service:

[Unit]
Description=JVB dynmaic IP restarter
After=syslog.target network.target multi-user.target jitsi-videobridge2.service

[Service]
ExecStart=/usr/local/bin/jvb-dynip-restart.py
Restart=on-failure
KillMode=mixed

[Install]
WantedBy=multi-user.target

Assume the jitsi-videobridge detects the public ip 1.2.3.4 during startup, the ip changes, a client connects using the domain with the new ip, but now jitsi tells the client to connect to 1.2.3.4:10000 and not domain:10000, the client fails to do so and tried to use turn (which wouldn’t help, because ip is still wrong). And jitsi-videobridge not only checks ip only at startup, there is also no option to tell jitsi-videobrige ‘always use domain, not IP’?

#!/bin/bash
set -e

LAST_IP=$(cat /tmp/last-ip 2>/dev/null) || true
CURRENT_IP=$(dig -4 +short myip.opendns.com a @resolver1.opendns.com)

if [[ "$CURRENT_IP" != "$LAST_IP" ]]; then
    systemctl restart jitsi-videobridge2.service
    echo $CURRENT_IP >/tmp/last-ip
fi

well, you can try to set up your jvb.conf like that (do NOT include this in the videobridge section, this should be ADDED in a separate section):

ice4j {
  harvest {
     mapping {
        static-mappings = [ 
           {
             local-address = "1.2.3.4"
             public-address = "your.domain.tld"
           }   
        ]   
     }   
  }   
}

and see what happens (replace 1.2.3.4 by your private IP address and the name your.domain.tld by your public domain of course). I have no way to confirm that it will work when the IP address changes since I have no computer with dynamic IP address.

All I can say is that the first time jicofo asks its address to jvb, it returns the IP address corresponding to the name entered. JVB has to have DNS access of course. But what will happen when the DNS changes, I don’t know. It may depend of DNS caching on the JVB host, or the software.
I can be reasonably certain that even if it works, running meetings will probably crash.

Thanks for that! It still works, but it doesn’t seem to have any effect: I connected a client from another public IP using WireGuard to the host that also runs the Jitsi Server. It also provides a DNS that redirects my.domain.tld to the local IP of 192.168… Opening https://my.domain.tld loads Jitsi from 192.168… (as expected), but the video/audio traffic is still send to the public IP of the Jitsi server, this IP can only be known because the client was told so by Jitsi, as the domain does not resolve to that IP (checked the traffic using WireShark).
Or is the name resolved by the JVB? Is it possible to move address resolving to the client? This could also help improve performance: Participants in a meeting within the same local network would not cause any traffic on the internet connection (this a very common scenario for my Jitsi instances: In a small business some poeple join the meeting from home and some from the office where the Jitsi server is located).
Crashing meetings during an IP change is not a big deal, if reconnect is possible immediately.

yes that’s it. When a conference is initiated, Jicofo asks to JVB what are the addresses it can give to the client for connecting. If there is a name in the jvb.conf mapping, Jvb resolves it and gives back an IP to Jicofo - who transmits it to the client. I have not taken in account the VPN scenario. Ideally Jitsi-meet should use only private IP if possible, but I have no idea on to achieve this. Is the VPN interface even available when Jvb is started ?

Yes, all interfaces are available. NAT is activated on the host, so incoming traffic at the VPN interface is forwarded to the local network interface.
I have configured VPN that way, that internet traffic is not using VPN, only the subnet 192.168.1…, that way the Jitsi-Webinterface is accessed over VPN (because the my.domain.tld resolves to the private IP), but video/audio traffic is transmitted outside the VPN (because Jicofo tells the client the public IP address). If I would route all traffic through VPN the bandwidth requirement for each client over VPN would double: The data would to the public IP would be transmitted using VPN to the host, from there to the internet and then back to the JVB. This is already the case for clients that are in the same local network as the Jitsi server.
I see to possible options to eliminate that problem, but they are probably not implemented (yet):

  • JVB does not resolve the domain and Jicofo gives the domain to the client. That way with a correctly configured local DNS server local clients and VPN clients use the local IP, clients from outside the public IP.
  • Jicofo does not tell a IP to the client, just the info: Use the same IP you accessed the web interface. That way you would not need a DNS server, if you use 192.168… to access the webinterface that IP would be used for video/audio as well.

If at least one of these options could be configured this would probably not only solve changing dynamic IP addresses (although that should already been solved if JVB always resolves the domain again every time a client connects and doesn’t cache the IP longer than told by the DNS response), but increase performance by reducing bandwidth requirements for clients in the same local network or connected using VPN to the local network.