processone / eturnal

STUN / TURN standalone server
https://eturnal.net
Apache License 2.0
225 stars 22 forks source link

eturnal with TLS #57

Closed docjojo closed 9 months ago

docjojo commented 9 months ago

Hello,

I have coturn running on port 3478 and 5349 TLS. Works well, but sometimes I get "WebRTC: ICE failed, see about:webrtc for more details" errors.

Running eturnal works well on port 3478 but not on port 5349 TLS.

Coturn and eturnal are both running on my server now, with eturnal using ports 3479 and 5350. I can

telnet foxy.tel 3479 and telnet foxy.tel 5350

but when I test with [https://icetest.info/]

URL: stun:foxy.tel:3479
URL: stun:foxy.tel:5350

I can not get "srflx"response on port 5350, only on 3479.

So how can I get TLS to work?

Thank you. eturnal.txt

sando38 commented 9 months ago

Hello,

when I use turns:foxy.tel:5350 Username: turnuser Credential: turn2048 in [https://icetest.info/], I get the expected relay candidates, but no srflx.

My assumption - known that [https://icetest.info/] does not speak STUN via TLS - is, that eturnal's TLS listener does not provide a srflx, because [https://icetest.info/] sends a UDP query to the TCP/TLS listener, which does not work.

Let's see if @weiss has another idea or if he actually confirms it.

NB: You may want to experiment and use for eturnal's TCP listener the transport auto (multiplexing) instead of tcp or tls and use the port 3479. If my assumption is correct, after apply the changes, you should get a srflx candidate when using turns:foxy.tel:3479 Username: turnuser Credential: turn2048, because the UDP query from [https://icetest.info/] does reach eturnal on port 3479 as well.

docjojo commented 9 months ago

Thank you for your answer. I have set

    -
      ip: "::"
      port: 5350
      transport: auto

And now

URL: turns:foxy.tel:5350 Username: turnuser Credential: turn2048

returns a "relay". Great.

I Tried "auto" on port 3479 with STUN, with no luck. STUN on port 5350 doesn't work.

Coturn is set to tls-listening-port=5349 and with https://icetest.info/ it returns "srflx" on

URL: stun:emdr.chat:5349

So icetest is does speak STUN via TLS? But eturnal does not?

Thank you.

weiss commented 9 months ago

Basically just confirming what @sando38 wrote above:

So icetest is does speak STUN via TLS?

It's actually your browser that's performing the STUN request, so in theory, the results could depend on the browser. In practice, none of the popular WebRTC stacks support STUN via TLS (as there's no practical value in using TLS for STUN). Even if you specify a stuns: URI such as stuns:emdr.chat:5349, you'll see in the icetest output that your client silently falls back to UDP for STUN (srflx) results.

Why does this fallback work with Coturn, but not with your eturnal setup? That's mentioned in Coturn's example configuration file:

actually, "plain" TCP & UDP sessions can connect to the TLS & DTLS port(s), too - if allowed by configuration. The TURN server "automatically" recognizes the type of traffic.

eturnal doesn't behave this way, precisely to avoid this kind of confusion. If you want eturnal to support UDP, unencrypted TCP and TLS on a single port, you'll need to configure that explicitly:

eturnal:
  listen:
    -
      ip: "::"
      port: 5350
      transport: udp
    -
      ip: "::"
      port: 5350
      transport: auto # Accept unencrypted TCP and TLS.

With this configuration, eturnal should behave like Coturn does.

docjojo commented 9 months ago

Thank you, for your response.

1) Can you explain shortly why STUN over TLS is of no sense?

2) I have added settings like you said and it looks like STUN and TURN both work on port 5350. Great.

3) I do however get WebRTC: ICE failed, see about:webrtc for more details errors. Any idea, what I can do to fix this?

4) Is there any way to keep track of the traffic/bandwidth used by eturnal?

Thank you for your help! Regards Chris

docjojo commented 9 months ago

Just build my own ICE Test Site, if you want to have a look:

https://ice.atec-systems.com/

Any feature you would add to the site?

docjojo commented 9 months ago
Bildschirmfoto 2023-10-10 um 01 40 26
docjojo commented 9 months ago

I would like to ask for help one more time:

From the docs: In a nutshell: If you’re creating your own WebRTC service, all you have to do is give your clients a username that’s comprised of the expiry timestamp and a password that’s derived from a secret shared with eturnal. To generate the password, you perform a Base64(HMAC-SHA1($secret, $timestamp)) operation, and eturnal does the same to verify the credentials.

I can set the $secret in eturnal.yml but I don't understand the part with the expiry timestamp.

Is $timestamp what I get with time(); in PHP?

So I could create a valid username/pasword combination like this?

https://onlinephp.io/c/7553d

And then user this username:password as credentials in ice servers URL to connect to eturnal TURN instead of using credentials as defined in eturnal.yml?

Thank you.

$username=time();

weiss commented 9 months ago

Can you explain shortly why STUN over TLS is of no sense?

STUN is basically the client asking the server "what's my IP address?", and the server responds with the address. Encrypting this payload doesn't hide anything noteworthy from the attacker, as the client's IP address is part of the IP header. The other point of using TLS could be circumventing restrictive firewalls, but if the firewall won't allow unencrypted STUN, an actual RTP stream will almost certainly be blocked as well, so the clients will fall back to TURN relaying anyway. (For TURN, offering TLS as a fallback to circumvent firewalls makes sense.)

WebRTC: ICE failed, see about:webrtc for more details

Hrm, I haven't seen this. I guess you're testing with Firefox? Are Chromium-based browsers happy? If you enter about:webrtc into the URL bar, does it show any error messages?

Is there any way to keep track of the traffic/bandwidth used by eturnal?

Whenever a TURN session is closed, a line such as the following is logged (at [notice] level):

Relayed 1037 KiB (in 353627 B / 3742 packets, out 708102 B / 6781 packets), duration: 163 seconds

eturnal also ships with a Prometheus and an InfluxDB module for keeping track of such statistics. See PR #41 for how to generate graphs using Grafana with Prometheus.

weiss commented 9 months ago

I would like to ask for help one more time

No problem. For more direct feedback, you could also try our chat room, by the way.

Is $timestamp what I get with time(); in PHP?

Yes. The idea is that those credentials are temporary, and that time stamp specifies the expiry time. So if you'd like to generate credentials that are valid for the next 24 hours, you'd do $timestamp = time() + 24*60*60.

There's a little shell script example for creating credentials in the repository. And you could call eturnalctl credentials $timestamp to double-check that your PHP code and eturnal agree on the password for a given $timestamp.

And then user this username:password as credentials in ice servers URL to connect to eturnal TURN instead of using credentials as defined in eturnal.yml?

Yes. That way you'd avoid static credentials, which could be shared/published for (ab)use by others.

docjojo commented 9 months ago

Hello Holger, thanks again for your answer.

Yes, it is a firefox "problem" and difficult to tell where in the about:webrtc list the error occured. I might have found one though:

Bildschirmfoto 2023-10-10 um 15 21 46

I am using peerjs and the error occurs some time after reloading the page (within a webrtc session).

peer.on("error") webrtc
WebRTC: ICE failed, see about:webrtc for more details
Conn ERROR: Error: Negotiation of connection to ecs-foxytel-client-07pfS9 failed.

Nevertheless the connection stays intact. But the error is irritating.

C.

docjojo commented 9 months ago

I understand the timestamp concept now, thank you! The PHP code might be of help for others, so I leave it here. C.

docjojo commented 9 months ago

Just updated the ICE Test Page:

https://ice.atec-systems.com/

Bildschirmfoto 2023-10-10 um 22 01 38