Commit Graph
8 Commits
Author SHA1 Message Date
Claude 61b9235f60 Make TURN/STUN port configurable via TURN_PORT env var
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
2026-02-24 01:58:04 +00:00
Claude f71bec27e5 Fix coturn crash: image runs as nobody, can't create pidfile
The coturn/coturn:latest image sets USER nobody:nogroup. On startup,
turnserver tries to create /var/run/turnserver.pid which nobody can't
write to, causing an immediate crash (the 2.2s "Error" in compose).

Fix: add user: root to the coturn service. Since we already use
network_mode: host, the container has broad host access anyway.

Also adds DETECT_EXTERNAL_IP=yes which is the image's native way
to auto-detect and set --external-ip, replacing our shell script.

https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
2026-02-24 00:27:46 +00:00
Claude 8a14b3eded Remove shell entrypoint override from coturn - use native image entrypoint
The coturn/coturn image has its own docker-entrypoint.sh that handles
arg parsing. Overriding it with /bin/sh -c adds a failure point.
Now passing args as a clean list directly to the native entrypoint.

Also drops --external-ip for now (added back once coturn starts).

https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
2026-02-23 20:18:22 +00:00
Claude 37765f4569 Rewrite coturn service to fix startup crash
Three changes to fix coturn failing to start:

1. Use environment vars instead of mixing Compose interpolation
   (${VAR}) with shell escaping ($$ARGS) in the command - the
   old approach was fragile and could produce broken shell scripts

2. Remove --no-loopback-peers - since Asterisk runs on the same
   host (network_mode: host), coturn must allow relay to localhost
   otherwise it refuses to relay media to Asterisk

3. Health check: redirect output to /dev/null to avoid noise

https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
2026-02-23 20:09:02 +00:00
Claude a5e6e18015 Use turnutils_stunclient for coturn healthcheck
The coturn/coturn Alpine image doesn't include ss or netstat.
Use turnutils_stunclient (included in the coturn image) which
actually verifies the STUN server is responding, not just that
a port is open. Also add start_period to avoid false failures
during startup.

https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
2026-02-23 20:04:38 +00:00
Claude 854261bf98 Fix coturn healthcheck: use netstat instead of ss
The coturn/coturn Docker image is Alpine-based and doesn't include
iproute2 (which provides ss). This caused the healthcheck to fail
immediately, marking coturn as unhealthy and preventing the asterisk
container from starting due to its service_healthy dependency.

Alpine's busybox includes netstat, so use that instead.

https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
2026-02-23 18:42:30 +00:00
Claude 8934d71391 Add full TURN relay support for reliable calls from any network
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
2026-02-21 16:09:50 +00:00
Claude 9caa795a78 Add Docker containerization, VPN STUN/ICE support, and DNS whitelist tools
- 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
2026-02-21 13:08:34 +00:00