Setting up firewall for TURN server

Hi,
I’m having a hard time setting up TURN server for Talk app. So far I’ve been able to make calls to outside only when they are not running behind a NAT/firewall. In that case, I only see a black screen and no sound.

As this post lines out, you need to have a TURN server, which I’ve installed on the same server as Nextcloud (Ubuntu - Coturn).
I think I’ve set it up properly.
When using this command from outside stun mydomain.com:3478 I got the following output:

STUN client version 0.97
Primary: Independent Mapping, Independent Filter, preserves ports, no hairpin 
Return value is 0x000013

So I guess everything is up and running.

Here is my turnserver.conf:

listening-port=3478
lt-cred-mech
use-auth-secret
static-auth-secret=<mysecret>
realm=mydomain.com
total-quota=100
bps-capacity=0
stale-nonce
log-file=/var/log/turn.log
no-loopback-peers
no-multicast-peers
external-ip=<my external-ip>
server-name=mydomain.com
fingerprint
min-port=59000
max-port=59100

My network layout:

Explanation:

INTERNET-to-DMZ (GREEN): Port 3478 forwarded to NC-server
DMZ-to-LAN: (PURPLE): UDP source pourts 59000 - 59100 allowed to destination ports 40000 - 65535 (explanation: turn server is allowed to use ports 59000 - 59100 see turnserver.conf)
LAN-to-DMZ: (RED) Port 3478 allowed to NC-server
DMZ-to-INTERNET (YELLOW): UDP port 3478 allowed & UDP source pourts 59000 - 59100 allowed to destination ports 40000 - 65535

When I try to call to someone behind a NAT, my pc is trying to connect directly to my peer through a high UDP port (fi 63408) so hence my call is not coming through. No log in my turnserver, so I guess something else needs to be set up in order to use my turnserver for this kind of calls?
Could someone help me please? I don’t think I need to open up another high range of UDP ports from my Lan to internet?
Also, is it a good idea to set up this range for UDP from my DMZ to LAN & INTERNET (limited through source ports 59000 until 59100)?

kr,

Wouter

You mean that is all content of the file or this is what you changed? I how latter is the case, since there are many other settings defined by default, which I would suggest to leave untouched (besides logging and TLS related, if required).

From what I leaned, at first always a direct P2P connection is attempted by Nextcloud Talk “clients”. If not possible, with STUN, then TURN as last resort. Obviously fallback to TURN in your case not work? How exactly did you configure it within Nextcloud admin settings?

Next is course would to checking coturn status carefully, but since you check the logs already, I guess all up and running without error?

This is my complete turnserver.conf file indeed (that is to say: I left everything that is commented out).
What other things would I need to leave in?

In NC admin settings I typed my.domain.com:3478 (notice: no https in front) andUDP & TCP and my secret
When connecting to someone behind a normal router, I have output in my turnserver log so I guess it’s working properly?

Does using TLS matter for this case? Now I’m not using it.

Open desired port in your firewall via NAT and run this script:https://github.com/nextcloud/vm/blob/master/apps/talk.sh

It looks like this:

Ah sorry, mixed it up with Redis server conf. Jep in turnserver.conf, everything is commented by default so yours should be fine.

However please try to comment external-ip. Setting any IP in the config caused issues during my tests. I think this is only required, if your TURN server is directly connected to www (not behind NAT) and/or the Nextcloud server is on a different local network.

For comparison, this works in my case (TURN server + Nextcloud on same machine behind NAT) with TLS enabled:

2018-12-07 20:33:22 root@micha:/var/log# grep '^[^#[:blank:]]' /etc/turnserver.conf
tls-listening-port=5349
fingerprint
use-auth-secret
static-auth-secret=my_secret
realm=my.domain.org
total-quota=100
bps-capacity=0
stale-nonce
cert=/etc/letsencrypt/live/my.domain.org/cert.pem
pkey=/etc/letsencrypt/live/my.domain.org/privkey.pem
cipher-list="ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AES:RSA+3DES:!ADH:!AECDH:!MD5"
dh-file=/etc/letsencrypt/live/my.domain.org/dhparams_4096.pem
no-loopback-peers
no-multicast-peers
no-tlsv1
no-tlsv1_1
1 Like

Sry for my late reply, I had other things I need to settle first.

Thanks for your suggestion; I’ve commented
external-ip, guess this is indeed for the case the TURN server is directly connected to the internet.
I’ll do a test with these new settings.

Another question regarding enabling TLS: I see you use a Letsencrypt certificate, do you need to renew this one every 90 days? Could you also use a self-signed certificate for this application?

kr,
wouter

Jep, letsencrypt certs need to be renewed every 90 days. With Debian/Raspbian package in my case, this is automatically done via systemd timer. You can also easily add a cron job, that e.g. runs certbot renew weekly, so no big deal.

If you anyway run Nextcloud, which you, I guess also want to access HTTPS, I strongly recommend to not use self-signed certificates anyway, since they can cause access issues with browsers and other clients, prompt warnings or deny access at all, since you are no trusted CA (certificate authority). And when the certificates are in place anyway, why not use them for coturn as well?
But coturn (and all clients I tested with) also run fine with a self-signed certificates.


The stronger (4096 bit) than default DH file also enhances security btw., but increases access delay of course. I just have this in place, since playing around with 100% https://www.ssllabs.com result :wink:. Surely overkill, but speed doesn’t play a big role in my home server case.
cipher-list above is an old example that is just still mentioned in all found cuturn + Nextcloud Talk guides. But this is actually a bid weak. You can e.g. use a stronger list, e.g. based on: https://mozilla.github.io/server-side-tls/ssl-config-generator/ modern option, that matches the one for your webserver then. Test this with all your clients to assure they support it. E.g. old Android versions might not support the “modern” cipher. Oldest supported versions are also mentioned on the mozilla generator page.

Off course, I’m already usiing Letsencrypt for my https-certificate, didn’t think of that I can re-use this certifiate for TURN if I want (as your configuration describes). I think I’ll implement this in the beginning of next year, first see if it’s working now.

kr,
wouter

Hey @Michalng and thank you for your support!

I think I have the same issue as described above. Talk works only when iptables is “deactivated”. I am not sure if I where I did smth wrong (I used your configuration file example).

I run Nextcloud 15.0.4 with the latest Talk version. I have the TURN server set up on the same server (shared VPS)

My conf file:

tls-listening-port=5349
fingerprint
lt-cred-mech
use-auth-secret
static-auth-secret=5df0c0baa13bcb094a6a83b9a0bf6330c9602048fa70a7898085ba2771eb04be
realm=xxxx
total-quota=100
bps-capacity=0
stale-nonce
cert=/etc/letsencrypt/live/xxx/cert.pem
pkey=/etc/letsencrypt/live/xxx/privkey.pem
cipher-list="ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:$
no-loopback-peers
no-multicast-peers
no-tlsv1
no-tlsv1_1

My iptables:

xxxx:~$ sudo iptables --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
f2b-sshd   tcp  --  anywhere             anywhere             multiport dports ssh
VSFW-10249842-INPUT  all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
VSFW-10249842-OUTPUT  all  --  anywhere             anywhere            

Chain VSFW-10249842-INPUT (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:5349 dpt:5349
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:5349 dpt:5349
ACCEPT     udp  --  anywhere             anywhere             udp spt:5349 dpt:5349
ACCEPT     udp  --  anywhere             anywhere             udp spt:5349 dpt:5349
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:http-alt dpt:http-alt
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:http-alt dpt:http-alt
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:3478 dpt:3478
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:3478 dpt:3478
ACCEPT     udp  --  anywhere             anywhere             udp spt:3478 dpt:3478
ACCEPT     udp  --  anywhere             anywhere             udp spt:3478 dpt:3478
ACCEPT     udp  --  anywhere             anywhere             udp spts:49152:65535 dpts:49152:65535
ACCEPT     udp  --  anywhere             anywhere             udp spts:49152:65535 dpts:49152:65535
DROP       all  --  anywhere             anywhere            

Chain VSFW-10249842-OUTPUT (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:5349 dpt:5349
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:5349 dpt:5349
ACCEPT     udp  --  anywhere             anywhere             udp spt:5349 dpt:5349
ACCEPT     udp  --  anywhere             anywhere             udp spt:5349 dpt:5349
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:http-alt dpt:http-alt
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:http-alt dpt:http-alt
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:3478 dpt:3478
ACCEPT     tcp  --  anywhere             anywhere             tcp spt:3478 dpt:3478
ACCEPT     udp  --  anywhere             anywhere             udp spt:3478 dpt:3478
ACCEPT     udp  --  anywhere             anywhere             udp spt:3478 dpt:3478
ACCEPT     udp  --  anywhere             anywhere             udp spts:49152:65535 dpts:49152:65535
ACCEPT     udp  --  anywhere             anywhere             udp spts:49152:65535 dpts:49152:65535
DROP       all  --  anywhere             anywhere            

Chain f2b-sshd (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere

I am kind of stuck and I don’t know what to do anymore :frowning:

@wouterve, any luck in solving this issue?

Quick hint: lt-cred-mech is not required and leads to warnings on coTURN startup. It does not hurt but remove it the next time you touch the config.

I am no iptables specialist, but obviously some port is still closed that is required.
I don’t see the HTTP/S ports, is this included in the tcp spt:http-alt dpt:http-alt rule?

Please try to open ports 3479 and 5350 ports as well. These are the default alt-tls-listening-port and alt-listening-port used by coTURN (one port number above the configures ones).
Actually they should not be used by Nextcloud Talk anyway, if not added there, I mean how show Nextcloud Talk know they exist, if you only configure one specific port in its TURN settings. However at least worth a try.

WebRTC on the other had seems to use any open port for the connection then, so your 49152:65535 port range seems to be fine: https://www.quora.com/What-ports-does-WebRTC-use

Perhaps you can monitor inbound and unbound connection attempts and see which ports/protocol is attempted to be used when initiating a Nextcloud Talk call?


I actually totally forgot to check my router firewall:

  • Only 80/443 TCP and 5349 TCP+UDP is forwarded to my server. This works out to allow video calls throughout my local network via coTURN :thinking:.
  • But outgoing connections are not blocked at all.

Hello and thanks for your really quick reply ^^

I removed lt-cred-mech. I still cannot call.

Yes, ports 80 and 443 are active (deleted some bits of iptables since it was quite long)

Regarding the inbound and unbound connection attempts, I get the following results:

$ netstat -nputw
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 xxx:443       xxx:46850     ESTABLISHED -               
tcp        0      0 xxx:443       xxx:46852     ESTABLISHED -               
tcp        0      0 xxx:443       xxx:15241      ESTABLISHED -               
tcp        0      0 xxx:443       xxx:46782     ESTABLISHED -               
tcp        0      0 xxx:975       xxx:44418     ESTABLISHED -               
tcp        0      0 xxx:443       xxx:15240      FIN_WAIT2   -               
tcp        0      0 xxx:443       xxx:15242      FIN_WAIT2   -               
tcp        0      0 xxx:443       xxx:46836     ESTABLISHED -               
tcp        0      0 xxx:3306          xxx:42304         ESTABLISHED -               
tcp        0      0 xxx:443       xxx:15243      FIN_WAIT2   -               
tcp        0      0 xxx:42304         xxx:3306          ESTABLISHED -               
tcp        0      0 xxx:443       xxx:15235      FIN_WAIT2   -   

Before getting the logs, I have also allowed outbound connections without any restriction - still not working.

Update: commenting out lt-cred-mech won’t make my calls work even when I deactivate the firewall.

Very strange. See what I got when not commenting the setting:

And it works perfectly fine without here. Which version of coTURN do you use? Perhaps this changed and it was/is even required on older versions.

Okay, so if inbound 5349 (+80/443) and outbound everything is open and you still don’t get a connection I am also out of ideas. But since it works without iptables, you know where to tinker around. netstat shows the established connections, it would be interesting to see the blocked connections (by iptables).

From whatever reason I was indeed doing smth wrong in iptables. “Switched” to ufw, added the necessary permissions and now everything is working :slight_smile: (allow 5349/tcp and 5349/udp). Thanks for your support!

1 Like