best turn config for NAT across ISP 2025
Find the perfect coturn config for NAT traversal that WORKS!
Best TURN Config for NAT Across ISP (2025)
Personal story
So I was recently working with WebRTC and VoIP and realized the importance of TURN servers. Actually writing a perfect TURN config which works 98% of the times on 98% of firewalls required me to do heavy research into what constitutes the perfect TURN config. After spending many, many hours, I wrote it—and let me save your time so you don't have to scratch your head on "why the hell are we not able to NAT traverse through this specific ISP?"
Why Do You Need a TURN Server?
TURN server plays a crucial role when direct peer-to-peer communication is blocked due to restrictive NAT or firewall policies.
A TURN server acts as a relay between two peers when they cannot establish a direct connection due to NAT restrictions. This happens in cases where both peers are behind symmetric NATs, carrier-grade NAT (CGNAT), or when strict firewall rules prevent peer-to-peer connectivity.
What is Coturn?
Coturn is an OSS abstraction of a TURN server implementation that helps relay media and data when p2p connectivity is not possible. It provides STUN and TURN functionalities to bypass NAT restrictions and ensure seamless real-time communication across networks.
What Problem Does TURN Solve?
- NAT Restriction: Many ISPs use symmetric NATs or CGNAT, preventing direct WebRTC connections.
- Enterprise Firewalls: Strict corporate networks block direct peer-to-peer communication.
- Mobile & Carrier Networks: Many 4G/5G and Wi-Fi networks employ aggressive NAT policies.
- Fallback Mechanism: Even when STUN and ICE fail, TURN ensures communication by relaying data.
Setting Up Coturn on AWS EC2 (Ubuntu)
We are going to use Coturn and host it on AWS EC2 (Ubuntu).
Installing Coturn
sudo apt update && sudo apt install coturn -y
Enable and start Coturn:
sudo systemctl enable coturn
sudo systemctl start coturn
NOTE
In order for your TURN server to successfully NAT traverse, make sure you add the following rules to your instance's security group:
- Inbound Rules:
- 3478 TCP 0.0.0.0/0
- 3478 UDP 0.0.0.0/0
- 3479 TCP 0.0.0.0/0
- 443 TCP 0.0.0.0/0
- 5349 TCP 0.0.0.0/0
- 80 TCP 0.0.0.0/0
- 5349 UDP 0.0.0.0/0
- 3479 UDP 0.0.0.0/0
- PORT RANGE FROM 32355 - 65535 UDP 0.0.0.0/0
- Outbound Rules:
- Allow all outbound traffic (recommended for unrestricted TURN communication).
Go to AWS Console → EC2 → Select your instance → Edit Security Group → Add the above rules.
- And whenever you make a change to your turn config at /etc/turnserver.conf MAKE SURE TO RESTART THE TURN SERVICE with
sudo systemctl restart coturn
Now lets edit and paste the turn config
sudo nano /etc/turnserver.conf
paste the below config and press ctrl x -> Y -> save and restart
listening-port=3478
tls-listening-port=5349
fingerprint
lt-cred-mech
user=<userName>:<Password>
server-name=<domain>.com
realm=<domain>.com
total-quota=100
stale-nonce=600
cert=/etc/letsencrypt/<remaining path>
pkey=/etc/letsencrypt/<remaining path>
cipher-list=ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256
no-sslv3
no-tlsv1
no-tlsv1_1
dh2066
no-stdout-log
no-loopback-peers
no-multicast-peers
proc-user=turnserver
proc-group=turnserver
min-port=49152
max-port=65535
external-ip=<ec-2 public IP>/<EC-2 private iP>
listening-ip=0.0.0.0
relay-ip=<ec-2 private ip>
restart turn after pasting and saving
sudo systemctl restart coturn
How to Verify Everything is Running
- Check Coturn service status:
sudo systemctl status coturn
● coturn.service - coTURN STUN/TURN Server
Loaded: loaded (/usr/lib/systemd/system/coturn.service; enabled; preset: enabled)
Active: active (running) since Thu 2025-03-06 06:49:15 UTC; 1 day 9h ago
Docs: man:coturn(1)
man:turnadmin(1)
man:turnserver(1)
Main PID: 22942 (turnserver)
Tasks: 25 (limit: 4676)
Memory: 12.3M (peak: 12.8M)
CPU: 1min 26.385s
CGroup: /system.slice/coturn.service
└─22942 /usr/bin/turnserver -c /etc/turnserver.conf --pidfile=
- Ensure necessary ports are open:
sudo netstat -tulpn | grep turnserver
- Test TURN server connectivity using
turnutils_uclient
:
turnutils_uclient -v -u <user name> -w <password> -p 3478 -e 8.8.8.8 -t <domain>.com
Why is this needed? This command simulates a client trying to authenticate with the TURN server and tests if the relay functionality is working.
- Ensure the TURN server is running as a process:
ps aux | grep turnserver
Using the TURN Server in Your Frontend
Once your TURN server is set up, you can use it in your WebRTC configuration like this:
{
urls: "turn:my sub domain.com:3478?transport=tcp",
username: "<user name>",
credential: "<password>",
}
This will allow your WebRTC client to use your TURN server for relaying media and data when direct peer-to-peer connections are not possible.
This configuration ensures that your TURN server can successfully NAT traverse across all major ISPs. If set up correctly, your WebRTC application will work seamlessly regardless of network restrictions.