TURN-Server not used in conference mode

Hi,

we have a self-hosted jitsi meet server next to a self-hosted turn server behind a corporate firewall. Our problem is that a conference (more than 2 people) with someone outside of our corporate network (aka my phone via LTE) is not possible. Audio and Video is getting dropped as soon as a third participant enters the room. P2P is working fine. Opening 10000 UDP is not an option. Therefore, we installed the mentioned TURN server with coturn.

We are using Apache on the jitsi server.

external IP Jitsi: AAA.BBB.CCC.88
external IP Turn: AAA.BBB.CCC.89

We can see in the coturn log that it is being used with a p2p connection but the connection gets dropped when another user enters.

In chrome://webrtc-internals we can see that our turn server is listed in the iceServers section for all tabs.

Here is our configuration:

JITSI SERVER

/etc/hosts

127.0.0.1 localhost meet.example.org
127.0.1.1 <localHostName>

/etc/prosody/conf.avail/meet.example.org.cfg.lua

plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }
muc_mapper_domain_base = "meet.example.org";
turncredentials_secret = "secret";
turncredentials_port = 443;
turncredentials_ttl = 86400;
consider_bosh_secure = true;
turncredentials = {
  { type = "stun", host = "turn.meet.example.org", port = "443" },
  { type = "turn", host = "turn.meet.example.org", port = "443", transport = "udp" },
  { type = "turns", host = "turn.meet.example.org", port = "443", transport = "tcp" }
};
cross_domain_bosh = false;
VirtualHost "meet.example.org"
        authentication = "cyrus"
        ssl = {
                key = "/etc/prosody/certs/meet.example.org.key";
                certificate = "/etc/prosody/certs/meet.example.org.pem";
        }
        cyrus_application_name = "xmpp"
        allow_unencrypted_plain_auth = true
        speakerstats_component = "speakerstats.meet.example.org"
        conference_duration_component = "conferenceduration.meet.example.org"
        modules_enabled = {
            "bosh";
            "pubsub";
            "ping"; -- Enable mod_ping
            "speakerstats";
            "turncredentials";
            "conference_duration";
            "auth_cyrus";
        }
        c2s_require_encryption = false
Component "conference.meet.example.org" "muc"
    storage = "none"
    modules_enabled = {
        "muc_meeting_id";
        "muc_domain_mapper";
    }
    admins = { "focus@auth.meet.example.org" }
    muc_room_locking = false
    muc_room_default_public_jids = true
Component "internal.auth.meet.example.org" "muc"
    storage = "none"
    modules_enabled = {
      "ping";
    }
    admins = { "focus@auth.meet.example.org", "jvb@auth.meet.example.org" }
    muc_room_locking = false
    muc_room_default_public_jids = true
VirtualHost "auth.meet.example.org"
    ssl = {
        key = "/etc/prosody/certs/auth.meet.example.org.key";
        certificate = "/etc/prosody/certs/auth.meet.example.org.crt";
    }
    authentication = "internal_plain"
Component "focus.meet.example.org"
    component_secret = "0l14DAWE"
Component "speakerstats.meet.example.org" "speakerstats_component"
    muc_component = "conference.meet.example.org"
Component "conferenceduration.meet.example.org" "conference_duration_component"
    muc_component = "conference.meet.example.org"
VirtualHost "guest.meet.example.org"
    authentication = "anonymous"
    c2s_require_encryption = false
    modules_enabled = {
        "bosh";
        "pubsub";
        "ping"; -- Enable mod_ping
        "speakerstats";
        "turncredentials";
        "conference_duration";
    }

/etc/jitsi/videobridge/sip-communicator.properties

org.ice4j.ice.harvest.DISABLE_AWS_HARVESTER=true
org.ice4j.ice.harvest.STUN_MAPPING_HARVESTER_ADDRESSES=turn.meet.example.org:443
org.jitsi.videobridge.ENABLE_STATISTICS=true
org.jitsi.videobridge.STATISTICS_TRANSPORT=muc
org.jitsi.videobridge.xmpp.user.shard.HOSTNAME=meet.example.org
org.jitsi.videobridge.xmpp.user.shard.DOMAIN=auth.meet.example.org
org.jitsi.videobridge.xmpp.user.shard.USERNAME=jvb
org.jitsi.videobridge.xmpp.user.shard.PASSWORD=12345678
org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS=JvbBrewery@internal.auth.meet.example.org
org.jitsi.videobridge.xmpp.user.shard.MUC_NICKNAME=58b590d6-da4e-415e-ba0b-900e0e24fdad
org.ice4j.ice.harvest.NAT_HARVESTER_LOCAL_ADDRESS=192.168.168.20
org.ice4j.ice.harvest.NAT_HARVESTER_PUBLIC_ADDRESS=AAA.BBB.CCC.88
org.jitis.videobridge.DISABLE_TCP_HARVESTER=true

**/etc/jitsi/meet/meet.example.org-config.js**

var config = {
hosts: {
    domain: 'meet.example.org',
    anonymousdomain: 'guest.meet.example.org',
    muc: 'conference.meet.example.org'
},
bosh: '//meet.example.org/http-bind',
clientNode: 'http://jitsi.org/jitsimeet',
testing: {
    p2pTestMode: false
},
enableNoAudioDetection: true,
enableNoisyMicDetection: true,
desktopSharingChromeExtId: null,
desktopSharingChromeSources: [ 'screen', 'window', 'tab' ],
desktopSharingChromeMinExtVersion: '0.1',
channelLastN: -1,
useStunTurn: true,
enableWelcomePage: true,
defaultLanguage: 'de',
enableUserRolesBasedOnToken: false,
disableThirdPartyRequests: true,
p2p: {
    enabled: true,
    useStunTurn: true,
    stunServers: [
        { urls: 'turn.meet.example.org:443' }
    ],
    preferH264: true
},
analytics: {
deploymentInfo: {
makeJsonParserHappy: 'even if last key had a trailing comma'
};

TURN SERVER

/etc/turnserver.conf

external-ip=AAA.BBB.CCC.89
listening-port=3478
tls-listening-port=443
realm=turn.meet.example.org
cert=/etc/coturn/certs/cert.pem
pkey=/etc/coturn/certs/turn.meet.example.org.privkey.pem
no-tlsv1
no-tlsv1_1
cipher-list="ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-CCM8:DHE-RSA-AES256-CCM:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA"
dh-file=/etc/coturn/certs/dhparam4096.pem
lt-cred-mech
use-auth-secret
static-auth-secret=secret
no-loopback-peers
no-multicast-peers
fingerprint
total-quota=50
stale-nonce=600
bps-capacity=0
normal
log-file=/var/log/coturn/coturn.log
proc-user=turnserver
proc-group=turnserver

Any ideas what is wrong? I do not see any errors except for

2020-05-27 16:38:46.655 SCHWERWIEGEND: [19] AbstractHealthCheckService.run#174: Health check failed in PT0S:
java.lang.Exception: Address discovery through STUN failed
        at org.jitsi.videobridge.health.Health.performCheck(Health.java:195)
        at org.jitsi.health.AbstractHealthCheckService.run(AbstractHealthCheckService.kt:144)
        at org.jitsi.utils.concurrent.RecurringRunnableExecutor.run(RecurringRunnableExecutor.java:216)
        at org.jitsi.utils.concurrent.RecurringRunnableExecutor.runInThread(RecurringRunnableExecutor.java:292)
        at org.jitsi.utils.concurrent.RecurringRunnableExecutor.access$000(RecurringRunnableExecutor.java:36)
        at org.jitsi.utils.concurrent.RecurringRunnableExecutor$1.run(RecurringRunnableExecutor.java:328)

in the jvb.log which I cannot explain.

443 TCP / UDP and 3478 TCP / UDP are open in the firewall facing the turn server.

Thank you very much.

Do you have a full chain certs there, and those are valid certificates, right? Not self signed.

Mind that using tcp for media is not good idea. You may see lag and lower quality

Hi,

thank you for the reply. Yes, these are our full chain certificates which are not self signed.

What do you suggest for my configuration in order to not use tcp for media?

This is where port 10000 udp is used.

For the non working turn, not sure why is that. Does your turn server have access to 10000 udp to the bridge? If media reaches coturn on port 443, coturn should be able to forward it to the bridge over 10000 udp.

10000 UDP seems to work in both directions:

From Turn to Meet:

root@turn:~# nc -z -v -u meet.example.org 10000
Connection to meet.example.org 10000 port [udp/*] succeeded!

From Meet to Turn:

root@meet:~# nc -z -v -u turn.meet.example.org 10000
Connection to turn.meet.example.org 10000 port [udp/*] succeeded!

I don’t think the test you are doing is correct. Stop jvb/turn and run nc in listen mode and from the other place send some bytes/text. Why it succeeds on the turn server port 10000? Is there something listening on 10000?