Commit Graph
11 Commits
Author SHA1 Message Date
Claude de46202ab4 Fix 27s call ringing delay: TURN credential mismatch and STUN DNS TTL=0
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
2026-02-24 22:07:33 +00:00
Claude 376a99b768 Fix TLS transport: remove ca_list_file that breaks transport on Docker
The ca_list_file option requires /etc/ssl/certs/ca-certificates.crt to
exist and be readable.  That file is created by the ca-certificates
package, which was only a Recommends dep (not installed via
--no-install-recommends), so the file was absent in the container image
and Asterisk rejected the entire transport-tls config with:

  ERROR: ca_list_file /etc/ssl/certs/ca-certificates.crt is either
         missing or not readable

ca_list_file is only consulted when verify_client=yes (mutual TLS /
client certificate auth).  Since we never set that option, the line
serves no purpose and is removed from both the fresh-config generator
and the upgrade-injection block.

Also add ca-certificates explicitly to the Dockerfile apt-get install
so the package is always present for any future use.

https://claude.ai/code/session_01PTzYWkePEG3tDCMSLfWrXE
2026-02-24 21:25:44 +00:00
Claude 1a3d409d50 Fix mobile registration: inject transport-tls when missing from pjsip.conf
pjsip.conf is intentionally preserved across container restarts to protect
device configurations.  When the file was created by an older version of the
setup script, or by the non-Docker bare-metal installer, it has no
[transport-tls] section.  Asterisk then starts without a TLS transport,
silently, which means nothing listens on port 5061 — causing every mobile
client configured for TLS to fail registration while the server appears
otherwise healthy.

The entrypoint now checks for the presence of [transport-tls] in an existing
pjsip.conf and injects the section (with current NAT/cert settings) if it is
absent.  A fresh install is unaffected because pjsip.conf is generated from
scratch with the TLS transport included.

https://claude.ai/code/session_01PTzYWkePEG3tDCMSLfWrXE
2026-02-24 21:00:46 +00:00
Claude 7ffa5f6e6f Fix TLS cert (add SANs) and enhance logging for registration debugging
Phones were not registering with zero log entries — two root causes:

1. Self-signed cert lacked Subject Alternative Names (SANs). Modern TLS
   clients (iOS/Android SIP apps) require SANs and ignore CN-only certs,
   causing silent TLS handshake rejection. Cert generation now includes
   SANs (DNS + IP), and existing certs without SANs are auto-regenerated.

2. Logger only captured notice/warning/error — TLS handshake failures
   are logged at the security level. Added security to console logging.

Also added:
- Startup check verifying port 5061 is actually bound
- TLS/cert diagnostics in vpn-diagnostics (SAN check, port check,
  self-signed warning with guidance for phone configuration)

https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
2026-02-24 18:06:34 +00:00
Claude 09f1763d5b Remove incompatible Digium codec_opus — crashes Asterisk on Ubuntu 24.04
The Digium precompiled codec_opus.so is ABI-incompatible with Ubuntu
24.04's Asterisk package build, causing "Module initialization failed.
ASTERISK EXITING!" on startup. The format_ogg_opus.so also conflicts
with the one already in asterisk-modules.

Opus pass-through (phone-to-phone when both support Opus) still works
via res_format_attr_opus.so from asterisk-modules. Only Opus<->ulaw
transcoding is unavailable, which is rarely needed since modern SIP
phones support the same codecs natively.

Changes:
- Remove Digium codec download from Dockerfile
- Add noload for codec_opus.so and format_ogg_opus.so in modules.conf
- Add startup cleanup to remove stale Digium .so files from Docker volume

https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
2026-02-24 17:12:24 +00:00
Claude 8405238fa1 Add Opus codec, show management info after Asterisk startup
- Install Digium precompiled codec_opus.so in Docker image since Ubuntu
  24.04's asterisk-modules package doesn't include it (bug #2044135).
  Opus is the best codec for mobile VoIP (adaptive bitrate, packet loss
  resilience).
- Rework entrypoint to print the management info banner AFTER Asterisk
  finishes loading, so the CLI command isn't buried in startup log noise.
  The management command is now highlighted in yellow.
- Remove explicit load directive for codec_opus.so from modules.conf;
  autoload=yes handles it when the .so exists, and silently skips when
  it doesn't (no more error log noise on systems without Opus).

https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
2026-02-24 17:05:22 +00:00
Claude 06c75371d0 Fix chan_sip intercepting registrations and pjsip.conf corruption after import
Three fixes:
- Always regenerate modules.conf on startup to ensure chan_sip stays disabled.
  Previously it was only written if missing, so a persisted Docker volume with
  an old modules.conf would load chan_sip, causing all pjsip registrations to
  fail with "Wrong password".
- Add pjsip.conf sanitization on startup to remove endpoint-only options
  (like direct_media) that end up in aor sections after a corrupted import.
- Fix dialplan rebuild to skip room extensions that conflict with device
  extensions, preventing duplicate extension registration warnings.
- Fix import merge to not write orphaned device comment headers for skipped
  (conflicting) devices.

https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
2026-02-24 14:10:49 +00:00
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 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 d05f1f9e3b Refactor entire project for Docker-native operation
Complete Docker-first refactor of the 6,800-line management script:

Core Architecture:
- Added is_docker() detection (/.dockerenv + /proc/1/cgroup check)
- Added asterisk_running() helper replacing all systemctl is-active calls
- Moved restart_asterisk_safe() to top-level with Docker/bare-metal branches
- Added webadmin_running(), start_webadmin(), stop_webadmin(), restart_webadmin()
  for process-based web admin management (replaces systemd service)

Functions Refactored (Docker-aware):
- fix_asterisk_systemd(): no-op in Docker (no systemd)
- install_asterisk_packages(): skips apt in Docker (pre-installed)
- install_baresip_packages(): skips in Docker (no local audio client)
- open_firewall_ports(): skips ufw in Docker (host responsibility)
- configure_asterisk(): skips systemctl enable in Docker
- enable_client_services(): skips entirely in Docker (no kiosk client)
- configure_baresip(): skips entirely in Docker
- configure_local_client(): shows error with guidance to use mobile clients
- run_client_diagnostics(): redirects to vpn-diagnostics
- fix_audio_manually(): not available in Docker (no audio hardware)
- uninstall_menu(): shows Docker-specific reset options
- manual_update_asterisk(): shows Docker rebuild instructions
- create_web_admin_service(): no-op in Docker (process-managed)
- web_admin_menu(): uses start/stop/restart_webadmin() instead of systemctl

Menu System:
- show_main_menu(): Docker-specific status display (Asterisk, Web Admin,
  VPN ICE status) with streamlined menu (no Client Settings option)
- submenu_install(): Docker shows Configure/Reset instead of Install/Uninstall
- submenu_tools(): Docker shows Room Directory, Update, VPN Diagnostics,
  DNS Whitelist (hides audio tools that need hardware)

Entrypoint:
- Proper signal trapping (SIGTERM/SIGINT) for clean shutdown
- Generates all Asterisk configs with STUN/ICE support from env vars
- Creates default device categories on first run
- Starts web admin as background process with env-based config

Dockerfile:
- Added lsof dependency (needed for port management)
- Added STUN port 3478 exposure
- Ensured /.dockerenv marker exists

Backward compatible: bare-metal installs work exactly as before.

https://claude.ai/code/session_01Vm6NLaQuzM4VosAotqS1q8
2026-02-21 14:39:38 +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