TURN Setup for Distribution Hubs
Configure a TURN endpoint so your Distribution Hubs can reach each other across the public internet when direct connections and peer-hub relays are not enough.
Background: what TURN does, briefly
When two computers on different networks need to talk directly, both sides have to find a path through their respective NATs and firewalls. ET Ducky's first two layers handle most cases — Layer 1 uses STUN and hole-punching to negotiate a direct connection, Layer 2 lets a well-connected hub in your organization relay for an unreachable peer with end-to-end TLS so the relay never sees plaintext. But some network combinations defeat both — most commonly: symmetric NAT on both sides with no publicly-reachable hub in between.
TURN (Traversal Using Relays around NAT) is the fallback. It's a small relay server that both endpoints connect to with outbound connections — and because both directions are outbound, NATs and firewalls don't get in the way. The TURN server forwards encrypted bytes between them. It always works, at the cost of paying for the relay's bandwidth.
You run the TURN, not us. The whole point of Distribution Hubs is that your data stays in your domain. Layer 3 keeps it that way — the TURN endpoint is yours (or one you've contracted with), not ours. We never see the bytes.
Three options, in order of effort
Cloudflare TURN Recommended
Cloudflare runs a global TURN service with a generous free tier (1 TB egress per month at the time of writing). Best balance of "easy to set up" and "actually free for most customers."
- Sign in to the Cloudflare dashboard. A free Cloudflare account is enough — no domain required.
- Go to Calls in the left nav, then TURN Service. Click Create TURN App.
-
Give it a name (e.g.,
etducky-hubs). Cloudflare shows you an App ID and an App Token. The App Token is shown once — copy it now. -
In ET Ducky, open Integrations → Distribution Servers, click your hub connection, scroll to the TURN section, and paste:
- TURN URL:
turns:turn.cloudflare.com:5349?transport=tcp - Username: your Cloudflare App ID
- Credential: your Cloudflare App Token
- Provider:
cloudflare(selects short-lived credential refresh)
- TURN URL:
- Click Test connection. ET Ducky will probe the TURN endpoint with a no-op allocation and confirm it works. You'll see a green check on the reach-state panel.
Cloudflare's TURN credentials are short-lived (1-hour TTL). ET Ducky refreshes them automatically using the App ID + App Token; you don't need to rotate anything manually.
Self-hosted Coturn Self-host
If you want the TURN server entirely under your control — running on your own infrastructure, with traffic auditable — Coturn is the standard open-source TURN implementation. Plan on a small VPS or VM with a static public IP.
- Provision a small Linux server with a static public IP. Anything in the $5/month tier on DigitalOcean, Linode, Hetzner, etc. is plenty for typical traffic; bump up if you expect heavy throughput. Ubuntu 24.04 LTS is fine.
-
Install Coturn:
sudo apt-get update sudo apt-get install -y coturn sudo sed -i 's/^#TURNSERVER_ENABLED/TURNSERVER_ENABLED/' /etc/default/coturn
-
Configure
/etc/turnserver.confwith your realm, a long random secret, and your public IP:listening-port=3478 tls-listening-port=5349 listening-ip=0.0.0.0 external-ip=<YOUR-PUBLIC-IP> realm=hubs.example.com fingerprint use-auth-secret static-auth-secret=<GENERATE-A-LONG-RANDOM-STRING> total-quota=100 no-cli no-multicast-peers no-loopback-peers denied-peer-ip=10.0.0.0-10.255.255.255 denied-peer-ip=172.16.0.0-172.31.255.255 denied-peer-ip=192.168.0.0-192.168.255.255 cert=/etc/letsencrypt/live/hubs.example.com/fullchain.pem pkey=/etc/letsencrypt/live/hubs.example.com/privkey.pem log-file=/var/log/turnserver.log
Note thedenied-peer-ipranges. They block Coturn from being used to bounce traffic into your internal network — a classic TURN misconfiguration. Don't omit them. -
Get a real TLS cert. The simplest route is certbot for a dedicated DNS name pointing at this box:
sudo apt-get install -y certbot sudo certbot certonly --standalone -d hubs.example.com
-
Open the firewall: TCP/UDP 3478 (TURN), TCP/UDP 5349 (TURNS over TLS), and the relay port range (defaults 49152-65535).
sudo ufw allow 3478 sudo ufw allow 5349 sudo ufw allow 49152:65535/udp
-
sudo systemctl restart coturn. Confirmsudo systemctl status coturnshows it running and logs look clean. -
In ET Ducky, configure the TURN section of your Distribution Hub connection with:
- TURN URL:
turns:hubs.example.com:5349?transport=tcp - Username: any short string (used as the timestamp prefix in Coturn's auth-secret scheme; ET Ducky picks
etducky) - Credential: the
static-auth-secretfrom yourturnserver.conf - Provider:
coturn-shared-secret
- TURN URL:
- Click Test connection to verify.
Coturn is the most flexible option and the one with the least third-party visibility into your traffic. The trade-off is operational: you're responsible for cert renewal (certbot can automate this with a cron job), patching the host, and watching for log anomalies.
Twilio Network Traversal Service Paid
Twilio offers a managed STUN/TURN service. Reliable, globally distributed, fully managed — but you pay per GB of relayed traffic. Best for orgs that already use Twilio and want one less vendor relationship to manage.
- Sign in to the Twilio Console.
- Go to Develop → Voice → Network Traversal Service, click Get a token. Twilio returns a TURN URL, a time-limited username, and a credential.
-
In ET Ducky, configure the TURN section with the values Twilio returned, plus Provider:
twilio. ET Ducky will refresh the time-limited credential periodically via the Twilio API — you'll need to add a Twilio Account SID + Auth Token in the connection settings for this to work automatically. - Click Test connection.
Twilio charges per GB. Plan on ~$0.40 per GB for typical egress at the time of writing; check Twilio's pricing page for current rates.
Comparison at a glance
| Option | Setup time | Ongoing cost | Bytes visible to vendor | Best for |
|---|---|---|---|---|
| Cloudflare TURN | 10 minutes | Free up to 1 TB/mo; ~$0.05/GB after | Cloudflare (encrypted only) | Most customers — fastest path to "it works." |
| Coturn (self-hosted) | 1-2 hours | VPS cost (~$5-20/mo) | Only you | Customers with strict no-third-party-traffic requirements. |
| Twilio | 15 minutes | ~$0.40/GB | Twilio (encrypted only) | Customers already using Twilio elsewhere. |
Verifying TURN is working
After saving the TURN configuration, the Distribution Server connection page's Reach State panel shows:
- Layer 1 (Direct): Working / Not working / Untested.
- Layer 2 (Peer-hub relay): Working / Not available / Untested.
- Layer 3 (TURN): Working / Test failed / Not configured.
If Layer 3 shows "Test failed," click the row for diagnostic detail. The most common causes are:
- Wrong port — TLS TURN runs on 5349, not 3478.
- Firewall blocking the relay port range (Coturn) — open UDP 49152-65535 if you haven't.
- Cert mismatch — the TURN URL's hostname must match the cert's CN/SAN exactly.
- Stale Cloudflare App Token — regenerate in the Cloudflare dashboard, paste the new value.
Credential rotation
All three providers issue short-lived credentials, which ET Ducky refreshes automatically. You don't need to rotate manually unless a credential is compromised. If that happens:
- Cloudflare: regenerate the App Token in the dashboard, paste the new value in the Distribution Hub connection.
- Coturn: generate a new
static-auth-secret, restart Coturn, paste the new value in ET Ducky. Existing in-flight transfers will fail and retry with the new credentials. - Twilio: rotate the Account SID/Auth Token in the Twilio console; update the values in ET Ducky.
FAQ
Do I actually need TURN?
Probably not. With Layer 1 (direct) and Layer 2 (peer-hub relay) alone, most multi-location organizations get effectively 100% WAN reach as long as at least one hub has a publicly-reachable endpoint (either via UPnP, port-forwarding, or a static public IP). Check your Distribution Server connection page's reach-state panel — if it shows "Estimated coverage: 100%" without TURN, you're done. Configure TURN only if the panel says you need it.
Will my bytes go through Cloudflare/Twilio if I use them?
Bytes traverse the TURN server, but the TURN server only sees encrypted TLS frames between the requesting agent and the destination hub. The end-to-end TLS connection terminates at the two ET Ducky agents, not at the TURN. Cloudflare and Twilio can see traffic volume and timing but not file content.
If even encrypted-traffic-visibility is unacceptable to your compliance posture, run Coturn yourself.
Can I configure multiple TURN endpoints for failover?
Yes. ET Ducky supports up to three TURN URLs per Distribution Hub connection (primary, secondary, tertiary). Agents try them in order. Most customers don't need more than one; multi-region deployments occasionally configure a TURN per region.
What ports does Coturn need open?
TCP/UDP 3478 (STUN/TURN), TCP/UDP 5349 (TURN over TLS), and the UDP relay range — Coturn's default is 49152-65535. You can narrow the relay range in turnserver.conf with min-port and max-port if your firewall policy requires a smaller range; just don't make it too small (a single transfer can use multiple ports).
Does ET Ducky see my TURN credentials?
We store them encrypted at rest in our database (AES-256-GCM, separate key per environment) and only decrypt them in memory when issuing a Layer 3 grant to one of your agents. They never appear in logs or telemetry. You can verify by inspecting your Security documentation page for our secrets-handling policy.