Jitsi Meet Docker - Use 443 TCP Only in case of corporate firewalls

Use the public IP for the turn service. The loopback is blocked because of the following line

denied-peer-ip=127.0.0.0-127.255.255.255
1 Like

Hi thanks for your reply. Wouldn’t i be better (and safer) to just delete:

denied-peer-ip=127.0.0.0-127.255.255.255

and keeping it this way, so that every connection remains in the internal network, since jitsi and coturn are on the same machine? Would it work?

All internal services become accessible from the outside through TURN

1 Like

Ok, I’ve tried commenting the line:

denied-peer-ip=10.0.0.0-10.255.255.255

and putting in nginx turn module conf the internal IP and everything works so far in TURN mode.

I tried then with the public IP but the problems appear again, no audio nor video with more than 2 partecipants. And I’m sure that the required TCP and UDP ports are forwarded from the outside.

Any suggestions?

It’s needed some extra rules on the firewall/router. The firewall should handle correctly the internal requests when the destination is its public IP.

Try this from jitsi

curl https://public_ip/

Ok, I’ve tried it. If I do that from the Jitsi VM, the curl just gets stuck:

root@jitsi:/tmp# curl https://public_ip/
curl: (7) Failed to connect to ... port 443: Connection refused

Also tried telnetting public_ip 443 from jitsi’s VM: it doesn’t work.

If I do that from my local mobaxterm terminal on my pc:

[myPC] ➤ curl https://public_ip/
curl: (77) error setting certificate verify locations:
CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none

This means that the router can not handle the internal requests

Instead of deleting this, you can add the following lines to the TURN config

listening-ip=INTERNAL-IP
allowed-peer-ip=INTERNAL-IP
no-udp
1 Like

Thanks very much for the help. Which way do you think would be safer/better? Adding these rules on coturn or properly set my company’s firewall?

The setting firewall rules is better. The denied-peer-ip lines prevent to access to the internal IP blocks through the TURN service.

1 Like

Thanks very much emrah. I will ask the firewall team to properly setup the rules.

One more question: my company is pushing towards docker deploys of Jitsi, which we have been using for a while and they work amazingly and they’re a lot more hassle free than the standard deployment.

is there a way to setup the also dockerized installation of Jitsi to use 443 TCP only, just as we did with the manual install?

No idea for the Docker case

1 Like

Thanks anyway. @damencho any insight about the docker installation? Does it integrate coturn just like the non-docker installation?

There are few PRs for that, but not merged yet.

I’m trying to use CoTurn in docker installation behind a Nginx Reverse Proxy.

I have my Jitsi working (with custom auth) on the DNS mydomain.fr and the DNS turn-mydomain.fr was created for CoTurn. Both redirecting on the same IP.

In my docker-compose.yml , I put ‘127.0.0.1:’ to block the 10000/udp communication from external :

# Video bridge
jvb:
   image: jitsi/jvb:latest
   restart: ${RESTART_POLICY}
   ports:
       - '127.0.0.1:${JVB_PORT}:${JVB_PORT}/udp'
       - '127.0.0.1:${JVB_TCP_PORT}:${JVB_TCP_PORT}'

My turnserver.conf contains :

TURN server name and realm

realm=turn-mydomain.fr
server-name=turn-mydomain.fr

Use fingerprint in TURN message

fingerprint

IPs the TURN server listens to

listening-ip=127.0.1.1
relay-ip=127.0.1.1

External IP-Address of the TURN server

external-ip=127.0.0.1

Main listening port

listening-port=3478

Further ports that are open for communication

min-port=10000
max-port=11000

Log file path

log-file=stdout

Enable verbose logging

verbose

use-auth-secret
static-auth-secret=keepthissecret

prod
no-tlsv1
no-tlsv1_1
no-stun
no-cli
cli-password=changeme

My docker-compose.yml for CoTurn :

version: ‘3’
services:
coturn_server:
image: instrumentisto/coturn:latest
restart: always
volumes:
- ./turnserver.conf:/etc/coturn/turnserver.conf
environment:
- LETSENCRYPT_HOST=turn-mydomain.fr
- LETSENCRYPT_EMAIL=me@mydomain.fr
- VIRTUAL_HOST=turn-mydomain.fr
- VIRTUAL_PORT=3478
networks:
nginx_https_proxy:
ports:
- ‘3478:3478/tcp’
- ‘3478:3478/udp’

networks:
nginx_https_proxy:
external: true

My /config/conf.d/jitsi-meet.cfg.lua contains :

turncredentials_secret = “keepthissecret”;
turncredentials_port = 443;
turncredentials_ttl = “86400”;
turncredentials = {
{ type = “stun”, host =turn-mydomain.fr”, port = “443” } ,
{ type = “turn”, host =turn-mydomain.fr”, port = “443”, transport = “udp” } ,
{ type = “turns”, host =turn-mydomain.fr”, port = “443”, transport = “tcp” }
}

VirtualHost “meet.jitsi”

modules_enabled = {

“turncredentials”;

}

VirtualHost “guest.meet.jitsi”

modules_enabled = {

“turncredentials”;

}

The mod_turncredentials.lua seems to work but I’m not sure…
I tricked the script to put some lines on the log and some calls seems to be done!

module:hook(“iq-get/host/urn:xmpp:extdisco:1:services”, function(event)
local origin, stanza = event.origin, event.stanza;
if origin.type ~= “c2s” then
return;
end
local now = os_time() + ttl;
local userpart = tostring(now);
local nonce = base64.encode(hmac_sha1(secret, tostring(userpart), false));
local reply = st.reply(stanza):tag(“services”, {xmlns = “urn:xmpp:extdisco:1”})
for idx, item in pairs(hosts) do
module:log(“TURN_CRED”, “IDX”, idx);
if item.type == “stun” or item.type == “stuns” then
module:log(“error” “TURN_CRED - STUN(S) TYPE = ‘%s’”, item.type);**
– stun items need host and port (defaults to 3478)
reply:tag(“service”,
{ type = item.type, host = item.host, port = tostring(item.port) or “3478” }
):up();
elseif item.type == “turn” or item.type == “turns” then
module:log(“error”, “TURN_CRED - TURN(S) TYPE = ‘%s’”, item.type);
local turn = {}
– turn items need host, port (defaults to 3478),
– transport (defaults to udp)
– username, password, ttl
turn.type = item.type;
turn.port = tostring(item.port);
turn.transport = item.transport;
turn.username = userpart;
turn.password = nonce;
turn.ttl = tostring(ttl);
if item.hosts then
turn.host = random(item.hosts)
else
turn.host = item.host
end
module:log(“error”, “TURN_CRED - TURN(S) HOST = ‘%s’”, turn.host);
reply:tag(“service”, turn):up();
end
end
origin.send(reply);
return true;
end);

So I see something like this :

meet.jitsi:turncredentials error TURN_CRED - STUN(S) TYPE = ‘stun’
meet.jitsi:turncredentials error TURN_CRED - TURN(S) TYPE = ‘turn’
meet.jitsi:turncredentials error TURN_CRED - TURN(S) HOST = ‘turn-mydomain.fr
meet.jitsi:turncredentials error TURN_CRED - TURN(S) TYPE = ‘turns’
meet.jitsi:turncredentials error TURN_CRED - TURN(S) HOST = ‘turn-mydomain.fr

In my config.js , I have :

useTurnUdp: false,
useStunTurn: true, // Using Turn Server with JVB
p2p: {
    enabled: true,
    useStunTurn: true,
    stunServers: [
    { urls: 'stun:turn-mydomain.fr:443' },
    { urls: 'turn:turn-mydomain.fr:443', transport: 'udp' },
    { urls: 'turns:turn-mydomain.fr:443', transport: 'tcp' },
    ],

    disableH264: true,
},

In chrome://webrtc-internals/ I can see :

iceServers: [stun:turn-mydomain.fr:443, turn:turn-mydomain.fr:443, turns:turn-mydomain.fr:443?transport=tcp]

I tried to use https://icetest.info/ without being sure how it works…

I’m not sure what I can test now…

Happy to see I’m not alone to trying to get this done :wink:

Thanks for your help!

NB : Sorry for the re-post, I could not edit the post with the right prosody plugin (turncredentials)… and the copy/paste is not really awesome :grimacing: # and TAB are not interpreted correctly

Anybody ? :grimacing:

I don’t think reverse proxy will work.

You need to configure the nginx fronting coturn the way it is explained here: Setting up TURN · Jitsi Meet Handbook with streams.

Tried it and no more result…

The 443 is working but no video/no audio :grimacing: