Turn Server Configuration Not Working After Docker Install Upgrade

I was running an old version of the docker installation and hit the deprecation error in Chrome regarding Plan B SDP semantics so thought it was time to upgrade.

I’ve upgraded to the latest version but now can’t seem to get it working with the TURN server (I have currently blocked UDP 10000 on the AWS security group for the EC2 instance jitsi is running on).

Most of the file locations and contents seems the same as before but there does seem to be some things that are different now so just trying to figure out if what I have done below is still correct for the latest version.

The config changes are the same as in this thread Have a working setup with TURN, but some users are still having issues

/etc/turnserver.conf

listening-port=80
tls-listening-port=443
external-ip=[public ip]/[private ip]
use-auth-secret
static-auth-secret=[my static auth secret]
server-name=[turn.mydomain.com]
realm=[turn.mydomain.com]
cert=/etc/letsencrypt/live/[turn.mydomain.com]/fullchain.pem
pkey=/etc/letsencrypt/live/[turn.mydomain.com]/privkey.pem

~/docker-jitsi-meet/.jitsi-meet-cfg/webconfig.js

    useStunTurn: true,

    p2p: {

        useStunTurn: true,

.jitsi-meet-cfg/prosody/config/prosody.cfg.lua

modules_enabled = {

        -- Generally required
                "roster"; -- Allow users to have a roster. Recommended ;)
                "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in.
                "tls"; -- Add support for secure TLS on c2s/s2s connections
                "dialback"; -- s2s dialback support
                "disco"; -- Service discovery
                "turncredentials"; -- Turn Credentials

.jitsi-meet-cfg/prosody/config/conf.d/jitsi-meet.cfg.lua

turncredentials_host = "turn.domain.co.uk"
turncredentials_secret = "my static auth secret";
turncredentials_port = 443;
turncredentials_ttl = 86400;
turncredentials = {
    { type = "stun", host = "turn.domain.co.uk", port = "443" },
    { type = "turn", host = "turn.domain.co.uk", port = "443", transport = "udp" },
    { type = "turns", host = "turn.domain.co.uk", port = "443", transport = "tcp" }
}


....

VirtualHost "meet.jitsi"
    
    ....
    modules_enabled = {
        ....
        "turncredentials";
        ....
    }

VirtualHost "auth.meet.jitsi"

    ....

    modules_enabled = {
        "limits_exception";
        "turncredentials";
    }

is there anything else that I am missing?

NOTE

Not too sure if cross domain is an issue - I am currently testing on the staging jitsi instance with our live turn server, but they both use the same subdomain so I don’t think that would be a problem?

e.g. instead of implementing this on meet.domain.co.uk I am experimenting on staging-meet.domain.co.uk until I know it is working as before.

Any help greatly appreciated.

If I’m not mistaken, recent Jitsi versions use external_services to propagate turn credentials.

Also, it might be worth incorporating these additions to /etc/turnserver.conf which ensures that malicious actors cannot use coturn as a proxy to access internal resources:

You may need to whitelist jvb IPs using allowed-peer-ip if you plan to have users connected from internal network.

Example of potential exploit if internal IPs not blocked: How we abused Slack's TURN servers to gain access to internal services

1 Like

Hi Shawn,

Thank you so much for the detailed answer, still not working unfortunately but guessing it’s something stupid and I can’t figure out what it is yet.

I’ve changed the following:

.jitsi-meet-cfg/prosody/config/prosody.cfg.lua

    modules_enabled = {
        ...
       "external_services"; -- External Services
       ....
    }

.jitsi-meet-cfg/prosody/config/conf.d/jitsi-meet.cfg.lua

external_service_secret = "my static auth secret";
external_services = {
     { type = "stun", host = "turn.productguru.co.uk", port = 3478 },
     { type = "turn", host = "turn.productguru.co.uk", port = 3478, transport = "udp", secret = true, ttl = 86400, algorithm = "turn" },
     { type = "turns", host = "turn.productguru.co.uk", port = 5349, transport = "tcp", secret = true, ttl = 86400, algorithm = "turn" }
};

VirtualHost "meet.jitsi"
    
    ....
    modules_enabled = {
        ....
        "external_services";
        ....
    }

VirtualHost "auth.meet.jitsi"

    ....

    modules_enabled = {
        "limits_exception";
        "external_services";
    }

I also tried changing the ports above to 443 since that’s what the turn server is listening on but not sure if I’m getting confused here.

I’m guessing I don’t need the turncredentials module loaded anymore and it’s now just external_services?

I did have the ips in the /etc/turnserver.conf but updated them from the link you sent just in case, thanks.

Not too sure about whether I need to whitelist ips or not, the jitsi and coturn instances are both running on ec2 instances.

Thanks again,
Martin

This should be external_service_secret. And yes, it is indeed inconsistent with other vars and module name :pensive:

Yup. mod_turncredentials.lua is deprecated and I believe was left behind so old configs could still work but over time things will drift and it will eventually be incompatible (if not already).

FYI, here’s the PR that introduced that change - feat: Uses mod_external_services supporting urn:xmpp:extdisco:2. by damencho · Pull Request #8455 · jitsi/jitsi-meet · GitHub

Probably not. As long as coturn can access public IP of jvb you should be fine.

Thank you!

I did notice the typo in external_services_secret but forgot to update my post - sorry about that but good catch!

I forgot that since I was making changes on the test jitsi site that I didn’t have UDP 10000 open on it for the turn server IP but have updated that now, but still no luck I’m afraid.

I don’t suppose if you know useStunTurn: true, is still required in config.js? p2p mode seems to work fine.

I noticed there’s a new (to me) option called useTurnUdp too but need to read what it does.

Must be close but don’t know what the problem is, nothing interesting in turn server logos which makes me doubt it’s even being used by jitsi.

useStunTurn is no longer used. See fix(config) drop useStunTurn · jitsi/jitsi-meet@1d9daa8 · GitHub

You’ll only need that if you want to use want to use Turn over UDP. By default, Jitsi Meet will ignore TURN/UDP.

I’m out of ideas re what might be your issue. Any errors in /var/log/prosody/prosody.log after a restart of prosody service?

Looking at your config again, IIRC you should only need to add external_services module to VirtualHost "meet.jitsi".

Not sure if this makes a difference, but perhaps try removing it from VirtualHost "auth.meet.jitsi" and from prosody.cfg.lua?

ah ok, thank you!

I will take another look at the logs, if I restart the containers (using docker installation) then the changes made to the config files are lost, so I don’t think I can do that, from previous experience the changes that were made didn’t seem to require a container restart, assuming it’s the case case here otherwise I don’t know how it would be possible to persist any changes to config.

Let me try and look in to the logs some more - really appreciate the help!

nothing insightful when running docker logs -f docker-jitsi-meet_prosody_1

apologies for spam.

Just checked the jvb logs and there’s a warning about a password, but not sure if it’s meaning the static auth password for the turn server as those definitely match.

After restarting coturn there’s nothing happening in there:

I am using port 443 as that’s what I was using before

external_services = {
     { type = "stun", host = "turn.productguru.co.uk", port = 443 },
     { type = "turn", host = "turn.productguru.co.uk", port = 443, transport = "udp", secret = true, ttl = 86400, algorithm = "turn" },
     { type = "turns", host = "turn.productguru.co.uk", port = 443, transport = "tcp", secret = true, ttl = 86400, algorithm = "turn" }
};

and that’s what the turn server is listening on:

tls-listening-port=443

I tried external_services with ports 3478 and 5349 as well but that didn’t work either, but it really would need to work over port 443 for corporate firewalls.

I’m not familir with docker-jitsi-meet so this will probably be a dumb question, but doesn’t it come preconfigure to handle external TURN and you just need to give it the relevant env vars? Or are you overwriting with custom configs?

1 Like

Have you tried this? No difference?

Ha - there’s no dumb questions!

I can’t believe I missed those environment variables for the turn server.

I have now set them and restarted - still no joy!

Since I restarted, all the changes to prosody.cfg.lua are gone. I am going to try some more things now that I know those turn environment variables exist, thanks so much for spotting that, I probably wouldn’t have noticed!

Did you take the time to test the network path between your workstation and jvb through turn ? IMO you have to make sure that the network part is correct. Setting aside the pecularities of Docker, if I was using a standard computer (or Linux containers) I’d first run tcpdump on the computer running turn and check that packets are coming in on port 443 when trying to open a meeting. Best idea is to run a meeting with 2 computers that are not blocked on port 10000, and a computer that is blocked, this way the packets coming in should come from the IP address of this computer. If no packet is coming in, either firewall is the culprit, or the config is wrong. It’s easy to check that on the workstation itself with tcpdump (are packets going in the right direction ?)
Then if packets are coming correctly on port 443 for Turn, it’s time to check the connection between Turn and jvb: UDP port 10000. I’d test this with nc (stop videobridge, launch nc -l 10000 -u on the bridge and run echo “123” | nc -u (jvb IP) 10000. If it works, time to check the turn configuration and logs. If it don’t, network path is blocked.

1 Like

thank you, that’s great, so far I have ran tcpdump on the turn server and getting this, so I’m assuming that is working.

I currently have udp 10000 blocked in the jitsi security group in AWS, still parsing how to do those other tests you mentioned.

Cheers,
Martin

You need to run tcpdump -i eth0 port 443 (replace eth0 by your network interface of course) ! you are testing that your ssh connexion to the server is working, well, if you are connected, it’s to be assumed that it works.
If you are blocking the port 10000 udp on the videobridge for everyone, the turn server will not work. It needs it. From Jitsi-meet POV, Coturn is a system to transmogrify TCP to UDP.

Thanks for the help everyone, the jitsi config was fine, my turnserver config wasn’t, changing it to this made it work:

listening-port=80
tls-listening-port=443

fingerprint
lt-cred-mech
use-auth-secret
static-auth-secret=secret

server-name=turn.domain.co.uk
realm=turn.domain.co.uk

user=guest:password

total-quota=100
stale-nonce=600

cert=/etc/letsencrypt/live/turn.domain.co.uk/fullchain.pem
pkey=/etc/letsencrypt/live/turn.domain.co.uk/privkey.pem

cipher-list="ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384"

proc-user=turnserver
proc-group=turnserver

Cheers,
Martin