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.

When does this matter? ET Ducky tries three WAN connectivity layers in order, cheapest first. Most networks succeed at Layer 1 (direct) or Layer 2 (peer-hub relay) without any extra setup. You only need TURN when neither of those works — typically because every hub in your organization sits behind a symmetric NAT or strict corporate firewall and no single location has a publicly-reachable hub. The Distribution Server connection page tells you exactly which layers are working and whether you need to add TURN.

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."

  1. Sign in to the Cloudflare dashboard. A free Cloudflare account is enough — no domain required.
  2. Go to Calls in the left nav, then TURN Service. Click Create TURN App.
  3. 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.
  4. 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)
  5. 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.

  1. 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.
  2. Install Coturn:
    sudo apt-get update
    sudo apt-get install -y coturn
    sudo sed -i 's/^#TURNSERVER_ENABLED/TURNSERVER_ENABLED/' /etc/default/coturn
  3. Configure /etc/turnserver.conf with 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 the denied-peer-ip ranges. They block Coturn from being used to bounce traffic into your internal network — a classic TURN misconfiguration. Don't omit them.
  4. 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
  5. 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
  6. sudo systemctl restart coturn. Confirm sudo systemctl status coturn shows it running and logs look clean.
  7. 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-secret from your turnserver.conf
    • Provider: coturn-shared-secret
  8. 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

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.

  1. Sign in to the Twilio Console.
  2. Go to Develop → Voice → Network Traversal Service, click Get a token. Twilio returns a TURN URL, a time-limited username, and a credential.
  3. 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.
  4. 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.

Still stuck? The reach-state panel's diagnostic detail is the fastest path to a fix in most cases. If you've checked it and still can't get Layer 3 working, contact [email protected] with a screenshot of the reach-state panel and the relevant TURN provider error message. We can't see your TURN logs, so the more context the better.