Jitsi and a turnserver

Forum home -> Tech Talk -> View topic

Post

Posted
Rating:
#953 (In Topic #422)
Avatar
Nerd Club Member

getting Jitsi to work through a restrictive firewall

Hi,

I have a customer that is not able to send or receive audio or video when he uses my Jitsi installation from his PC. He can use Google Meet with me fine: so his setup can work with WebRTC.

It seems that the problem is that my jitsi implementation tries to send media packets via high numbered UDP ports and many restrictive firewalls will not allow that. What is needed is a solution so that a restricted client can do all of their Jitsi meeting business over an openable port, likely port 443.

The orthodox position seems to be that Jitsi can 'fall back' to the use of a turnserver. This server communicates with the client over trusted ports like 443, before sending the data on to the videobridge as UDP packets, which are then returned to the turnserver etc.

There are guides such as this one: https://jitsi.github.io/handbook/docs/devops-guide/turn/

but I find that any guides on this topic are frequently incomplete. One requirement is that user credentials are ephemeral

"The usage of ephemeral credentials ensures that access to the TURN server can be controlled even if the credentials can be discovered by the user. Jitsi Meet can fetch the TURN credentials from the XMPP server via XEP-0215 and this is configured by default using mod_external_services."

but I have not been able to get my implementation working.

I have a turnserver on one machine. xmpp (prosody), the videobridge etc. on another as per Jacob's excellent guide. Let's call that machine the jitsi server. Both are on amazon lightsail instances.

To be clear, calls work in all circumstances except in a restricted environment.

Using a python script on the jitsi server I can generate ephemeral credentials on the command line. These can then be entered into a tool such as Trickle ICE here: https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

A connection is made with the turnserver and there is packet exchange. This can be observed from the turnserver logs.

The websocket specified in jvb.conf can be tested successfully from a client using wscat. A dialogue is opened.

My problem is that in a restricted environment, jitsi does not seem to be trying to use the turnserver. I see no communication logged in the turnserver log or jvb.log.

Testing this is especially problematic due to the need for another operator to test outside peer to peer mode.

In my example, I have a Jitsi installation 'behind' nginx. I have a domain myturnserver-example.com with an A record that points to the IP address of my jitsi server. Via the .conf file in nginx, traffic to port 443 of myturnserver-example.com is sent to port 5349 (tls port) at the IP address of my turnserver lightsail instance. These port numbers and IP addressess match my turnserver.conf file.

Having written that out and thinking about it, it would make sense that any traffic intended from my jitsi server for my turnserver must be sent, not to the domain atrtributed to the turnserve in the A record, but to the IP address of the turnserver. Thus a configuration like that suggested in the guide above only works if the turnserver and xmpp are on the same machine, thus the domain resolves to the same IP address.

Any ideas please fire them over. Thanks in advance.

LethalProtector

 
Online now: No Back to the top

Post

Posted
Rating:
#954
Avatar
NOTS Staff
I haven't dug into this far, but this:

LethalProtector said

it would make sense that any traffic intended from my jitsi server for my turnserver must be sent, not to the domain atrtributed to the turnserve in the A record, but to the IP address of the turnserver.
 

Doesn't make sense to me. If the domain name had an A record to the TURN server, then it would resolve to the IP address and traffic would be sent to the IP address.

LethalProtector said

I have a domain myturnserver-example.com with an A record that points to the IP address of my jitsi server.
 

Reading the Jitsi documentation page, it sounds like myturnserver-example.com should point to the IP address of the TURN server (they say a second DNS record is needed for the turn domain). Am I missing something?
Online now: No Back to the top

Post

Posted
Rating:
#955
Avatar
Nerd Club Member
Am I missing something?

what I didn't say is that the thing is multiplexed/behind nginx. nginx runs on the machine that hosts the videobridge.

Thus, a restricted user that sends traffic to myturnserver-example.com port 443 gets picked up by a stream block in nginx and sent over to the public IP of the machine that hosts the turnserver, port 443.

There is another domain of course pointing to the IP of the jitsi machine and traffic for that domain is sent to port 8080 by nginx. Similar to the instructions here: https://jitsi.github.io/handbook/docs/devops-guide/turn/

Am I doing something stupid?

 
Online now: No Back to the top

Post

Posted
Rating:
#956
Avatar
NOTS Staff
If the TURN server has its own public IP address, why not just point myturnserver-example.com directly to that IP address? That's what I'm not understanding.

The documentation you linked directs you to do it that way, from my understanding– it instructs you to install NGINX for multiplexing on the TURN server, which it sounds like you've possibly done, but why does traffic bound for the TURN server need to bounce off of another server first?
Online now: No Back to the top

Post

Posted
Rating:
#957
Avatar
Nerd Club Member
Hello Jacob and thanks for engaging. You are better that this than me.


My reading of this:
stream {
    map $ssl_preread_server_name $name {
          jitsi-meet.example.com web_backend;
          turn-jitsi-meet.example.com turn_backend;
    }

  upstream web_backend {
        server 127.0.0.1:4444;
  }
is that traffic to port 443 of the machine hosting the videobridge is redirected, depending on the domain specified. I think this is called SNI.

Thus port 443 traffic to jits-meet.example.com is sent to localhost port 4444 and port 443 traffic sent to turn-jitsi-meet.example.com is sent to the turnserver machine port 5349. Not 127.0.0.1:5349 but your_public_ip:5349.

Does it not follow that the turnserver in this scenario is on a different machine to that hosting the website? I've come to the understanding that this is regarded as a more secure setup, hence this is what I have pursued.

I've asked Google AI Studio for the answer to your question and after reading through some pretty bland comment ended up coming up with my own explanation that perhaps this setup assumes that on its own machine, the turnserver software e.g. coturn is not able to bind port 443, only the standard high numbered ports 5349 (TLS) and 4378.

5349 and 3478 are port numbers that a Jitsi user in a restrictive environment would not be able to access if their firewall bans stuff other than DNS, email, SSH, ports 80 and 443 for web traffic. Is that a good answer to your question?

Of course it then raises the other question of why not put nginx on the turnserver machine and send traffic for port 443 to port 5349.

The method that I thought was being proposed needs two machines and just one implementation of nginx. AIStudio suggests that might help with load balancing, which I regarded as it most sensible suggestion.

I hope that explains my reasoning behind choosing this strategy and why I am keen to get it to work on this basis.

Again you might be wondering why not just use the public IP address of the turnserver, why the extra domain. As this is supposed to be secure traffic over port 443, I expect that a domain name might help with certificate verification? Maybe?

Thanks again for engaging.
Online now: No Back to the top

Post

Posted
Rating:
#958
Avatar
NOTS Staff
I don't know what Google AI Studio or any other AI chatbot would say about the situation. My experience with state-of-the-art AI chatbots so far has been that they often make things up, especially for technical topics (even when repeatedly told they got something wrong and specifically instructed not to make guesses).

Why do you think your setup is "more secure?"

You are correct that a domain name is required for a Let's Encrypt TLS certificate to be issued. I'm not saying the TURN server shouldn't have a domain name. I'm saying its domain name should point to its IP address.

Based on only the information you've provided (you didn't include your `upstream turn_backend` block or of course the rest of your setup), I understand your theory and agree that traffic to turn-jitsi-meet.example.com on port 443 directed at the machine you have that config on should be redirected to wherever you've specified that backend to be. If you'd like to troubleshoot whether that's happening, then I guess I'd suggest setting up packet captures on both servers using tcpdump to see exactly what traffic's coming in, out, and on which ports when you attempt to use Jitsi. But I would highly recommend starting by simply following the documentation and pointing the TURN domain to the TURN IP address.

You don't want the video traffic to have to bounce from the end user's machine to your videobridge to the TURN server to the other user if it's not necessary. The entire point of this setup is to have the traffic go from the end user to the TURN server and then to the other user. If nothing else, fewer hops will mean lower latency.

And to that end, as long as you have port 443 set up on your TURN server (as the docs show how to do), the end user will have no problem sending traffic directly to the TURN server on port 443, because it's port 443.

Reading the documentation page again, it does appear to be talking about running the TURN server software on the same server as Jitsi (what you're calling the "videobridge server"). That is why it says the TURN domain points to "the same machine"– because it assumes the TURN server is the same machine. If your TURN server is separate, then point the TURN domain to the TURN IP address.

Separately from the TURN server questions, did you try simply disabling peer-to-peer mode in Jitsi altogether? That would send all traffic through the Jitsi server (JTB/video bridge), rather than attempting to go directly from one peer to the other (or through a TURN server). There's info about that here: https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-configuration/#p2p That's one of the same config blocks referenced on the TURN server doc page. For getting TURN working, I'd also consider ensuring you've specified :443 at the end of your stunServers URL (as shown in the P2P config doc section, but not on the TURN doc page), and I'd also consider changing the iceTransportPolicy from "all" to "relay" to see if that helps.
Online now: No Back to the top

Post

Posted
Rating:
#963
Avatar
Nerd Club Member
Hi Jacob,

You asked Why do you think your setup is "more secure?"

I am using coturn as my turnserver software on Debian. By default on install, this adds the private IP of the server to the turnserver configuration files 'denied-peer-ip' along with some other IP address e.g. 10.0.0.0 to 10.255.255.255. The reason "is to prevent an attack that tries to connect to a port on the machine running coturn (some other service, internal service, etc)".
https://github.com/coturn/coturn/issues/1407

Running my turnserver on another machine also reduces the services exposed to a single SSH key being lost.

Thus to run on the same machine, I would have to allow the local IP.

I've now got it working by running coturn on the same machine. I have followed the docs but could not get coturn to start with the public IP as the listening-ip or tls-listening-ip in turnserver.conf. I changed this to the private IP, which then needs to match the IP in the stream block. I then have to disable the line in turnserver.conf that denies the machine's private IP.

However, when I set my client to a restrictive firewall, it now works. It's a bit disatisfactory.

As for what you are calling the official docs, I would describe them instead as 'a set up that worked at some point for some user'. The instructions on how to create the certificates simply did not work on my machine, giving an error "/opt/acmesh/.acme.sh/acme.sh" does not exist. This undermines confidence in the rest of the instructions "it must be the docs again, not me" potentially leading to more errors being introduced.

You and I have had a bit of to-and-fro as to whether the instructions here: Setting up TURN | Jitsi Meet are for running a turnserver on a different machine to jitsi or not. I will repeat that it is very confusing to be specifiying an IP other than 127.0.0.1 to nginx if the turnserver is running on the same machine. I guess it is the case that what is specified in nginx needs to match how the turnserver expects the world to call it.

Moreover, I couldn't get this to work as an nginx 'module' as per the instructions and only was it working when placed as an instruction in the stream-enabled directory, which I had to create.

Substantial departures were made to get this working. If you think I'm mistaken, give it one hour of your time and see if you can make this work using what you are calling the turnserver docs. At worst, you will have a turnserver implementation.

I couldn't have done this without your brilliant youtube video, or your prompting which made me think to try another direction today. Many thanks



 
Online now: No Back to the top

Post

Posted
Rating:
#964
Avatar
Nerd Club Member
By default on install, this adds the private IP of the server to the turnserver configuration files 'denied-peer-ip'

I take that back. By default on install, coturn adds the private IP ranges to the denied-peer-ip addresses i.e.

10.0.0.0/8: 10.0.0.0 to 10.255.255.255
172.16.0.0/12: 172.16.0.0 to 172.31.255.255
and
192.168.0.0/16: 192.168.0.0 to 192.168.255.255

nevertheless it has the same effect, I can only use the turnserver if I set the jitsi implementation's private IP address to be an allowed IP.

Many thanks
Online now: No Back to the top
1 guest and 0 members have just viewed this.