Asterisk doesn't need STUN/TURN in rtp.conf for this setup because:
- It already knows its public IP via external_media_address in pjsip.conf
- Its RTP ports are port-forwarded, so host ICE candidates are sufficient
- stunaddr/turnaddr caused STUN gather timeouts (~27s) on every call,
whether pointing at the FQDN (DNS TTL=0 bug) or localhost (UDP timeout)
coturn is for SIP *clients* behind strict NAT — they configure TURN in
their own app settings, independently of Asterisk's rtp.conf.
ICE support remains enabled so Asterisk participates in ICE negotiation.
https://claude.ai/code/session_01KWVtEt9MmZdywcu7WmgchX
Two bugs caused ICE candidate gathering to fail and timeout (~27 seconds)
before falling back to direct media on every call:
1. TURN credential mismatch — when TURN_PASSWORD was empty in .env,
coturn defaulted to "changeme" but the entrypoint auto-generated a
different random password for Asterisk. Every TURN auth attempt failed
("check_stun_auth: user easyasterisk credentials are incorrect").
2. STUN DNS TTL=0 — using the FQDN as stunaddr caused DNS resolution
that returned TTL=0, making Asterisk cancel recurring STUN resolution
entirely. Since coturn runs on the same host (network_mode: host),
rtp.conf now uses 127.0.0.1 which needs no DNS at all.
Also documents the Android Call Integration audio issue (ConnectionService
routes audio through the native telephony path, breaking VoIP RTP).
https://claude.ai/code/session_01KWVtEt9MmZdywcu7WmgchX
UniFi controller uses UDP 3478 for STUN, preventing coturn from
binding. Add TURN_PORT variable (default 3478) so users can set
TURN_PORT=3479 in .env to avoid the conflict.
https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
Problem: Calls via FQDN work "sometimes" because STUN-only mode fails
behind strict NAT (cellular, Proton VPN, hotel WiFi, corporate firewalls).
STUN tells clients their public IP, but can't relay media when direct
UDP paths are blocked. TURN relays media as a fallback.
Changes:
coturn (docker-compose.yml):
- Upgraded from STUN-only to full STUN+TURN relay
- Uses long-term credential mechanism (--lt-cred-mech)
- Credentials shared between coturn and Asterisk automatically
- Relay port range 49152-49252 (configurable, ~50 concurrent relayed calls)
- Always-on (removed --profile stun gate)
- Conditional --external-ip (only set when PUBLIC_IP is provided)
Entrypoint (docker/entrypoint.sh):
- Auto-detects public IP (ifconfig.me → icanhazip.com → api.ipify.org)
- Auto-generates TURN password on first startup (saved to config)
- Configures rtp.conf with icesupport + stunaddr + turnaddr + credentials
- Updates pjsip.conf external_*_address if public IP changes
- Always enables ICE, STUN, and TURN for Docker deployments
Main script (easy-asterisk-v0.10.0.sh):
- Added TURN_ENABLED, TURN_SERVER, TURN_USERNAME, TURN_PASSWORD to
load_config/save_config
- repair_core_configs: rtp.conf now includes turnaddr/turnusername/turnpassword
when TURN is enabled
- Bash device creation: Docker mode defaults to FQDN (TLS) for all new devices
- Python device creation: reads TURN_ENABLED, auto-selects FQDN in Docker
- Main menu shows TURN status
.env.example:
- Comprehensive documentation for every setting
- DOMAIN_NAME is the only required setting
- Port forwarding requirements clearly listed
- TURN credentials and relay port range documented
The result: `docker compose up -d` gives you a fully working PBX where
any SIP client on any network can connect reliably via FQDN:5061.
https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
- Dockerfile: Containerized Asterisk PBX with Ubuntu 24.04 base,
all dependencies pre-installed, health checks, and volume persistence
- docker-compose.yml: Asterisk service with host networking (required for
RTP port range) + optional self-hosted coturn STUN server via --profile stun
- docker/entrypoint.sh: Auto-generates configs, certs, and starts
Asterisk in foreground with web admin in background
- scripts/vpn-diagnostics.sh: Detects VPN interfaces, checks PJSIP
transport config, tests STUN reachability, analyzes NAT type, and
provides STUN/TURN recommendations for third-party VPNs
- scripts/dns-whitelist.sh: Documents all domains needed per network mode
(LAN/VPN vs FQDN), per component (server, Sipnetic, Linphone), with
--check mode to test DNS resolution and reachability
- easy-asterisk script: Added VPN STUN/ICE menu (option 12 in Server
Settings) with self-hosted coturn, Google STUN, or custom STUN server
options. LAN/VPN devices now get ice_support=yes when VPN ICE is
enabled. Web admin Python code also respects VPN_ICE_ENABLED config.
Self-hosted coturn in STUN-only mode eliminates all external DNS
dependencies - everything operates by IP address, ideal for
DNS-filtered environments.
https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8