From 06c75371d0d174393c19d5bf9aea6c87a5b10a99 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 24 Feb 2026 14:10:49 +0000 Subject: [PATCH] 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 --- docker/entrypoint.sh | 39 ++++++++++++++++++++++++++++++++++++--- easy-asterisk-v0.10.0.sh | 20 +++++++++++++++++--- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 1f37487..c0349d8 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -214,6 +214,40 @@ else fi fi +# ── Sanitize pjsip.conf: remove endpoint-only options from aor sections ── +if [[ -f /etc/asterisk/pjsip.conf ]]; then + # Options that are only valid in [endpoint] sections, not in [aor] sections + endpoint_only_opts="direct_media|rtp_symmetric|force_rport|rewrite_contact|rtp_keepalive|rtp_timeout|rtp_timeout_hold|ice_support|context|disallow|allow|auth|aors|callerid|media_encryption|transport" + current_type="" + needs_fix=false + while IFS= read -r line; do + if [[ "$line" =~ ^type=(.*) ]]; then + current_type="${BASH_REMATCH[1]}" + fi + if [[ "$current_type" == "aor" ]] && echo "$line" | grep -qE "^(${endpoint_only_opts})="; then + needs_fix=true + break + fi + done < /etc/asterisk/pjsip.conf + + if $needs_fix; then + log_info "Sanitizing pjsip.conf (removing misplaced options from aor sections)..." + awk -v opts="$endpoint_only_opts" ' + BEGIN { split(opts, arr, "|"); for (i in arr) bad[arr[i]]=1 } + /^type=/ { current_type = substr($0, 6) } + { + if (current_type == "aor") { + split($0, kv, "=") + if (kv[1] in bad) next + } + print + } + ' /etc/asterisk/pjsip.conf > /tmp/pjsip_sanitized.conf + mv /tmp/pjsip_sanitized.conf /etc/asterisk/pjsip.conf + chown asterisk:asterisk /etc/asterisk/pjsip.conf + fi +fi + # ── rtp.conf (always regenerated - includes TURN credentials) ── log_info "Configuring RTP with ICE + STUN + TURN..." cat > /etc/asterisk/rtp.conf << EOF @@ -261,8 +295,8 @@ console => notice,warning,error EOF fi -if [[ ! -f /etc/asterisk/modules.conf ]]; then - cat > /etc/asterisk/modules.conf << 'EOF' +# ── modules.conf (always regenerated - ensures chan_sip stays disabled) ── +cat > /etc/asterisk/modules.conf << 'EOF' [modules] autoload=yes noload => chan_sip.so @@ -280,7 +314,6 @@ load => app_dial.so load => app_page.so load => pbx_config.so EOF -fi # ── 9. Fix permissions ─────────────────────────────────────── chown -R asterisk:asterisk /etc/asterisk /var/lib/asterisk /var/log/asterisk /var/spool/asterisk /var/run/asterisk 2>/dev/null || true diff --git a/easy-asterisk-v0.10.0.sh b/easy-asterisk-v0.10.0.sh index 6b7230e..d4773bf 100644 --- a/easy-asterisk-v0.10.0.sh +++ b/easy-asterisk-v0.10.0.sh @@ -3174,6 +3174,7 @@ exten => _X.,1,Hangup() EOF local dev_name="" dev_cat="" dev_auto="" dev_aa_override="" + local -A device_extensions=() while IFS= read -r line; do if [[ "$line" == *"; === Device:"* ]]; then dev_aa_override="" @@ -3198,6 +3199,7 @@ EOF if [[ "$line" =~ ^\[([0-9]+)\] ]]; then local ext="${BASH_REMATCH[1]}" if [[ -n "$dev_name" ]]; then + device_extensions[$ext]=1 if [[ "$dev_auto" == "yes" ]]; then cat >> "$conf_file" << EOF exten => ${ext},1,NoOp(Auto-Answer ${ext}) @@ -3220,11 +3222,15 @@ EOF fi done < /etc/asterisk/pjsip.conf - # Add rooms + # Add rooms (skip if extension already used by a device) if [[ -f "$ROOMS_FILE" ]]; then while IFS='|' read -r rext rname rmem rtime rtype; do [[ "$rext" =~ ^# ]] && continue [[ -z "$rext" ]] && continue + if [[ -n "${device_extensions[$rext]:-}" ]]; then + [[ "$quiet" != "quiet" ]] && print_warn "Room '$rname' ext $rext conflicts with device — skipping" + continue + fi local dial_list="" IFS=',' read -ra EXTS <<< "$rmem" for ext in "${EXTS[@]}"; do @@ -6663,17 +6669,25 @@ import_clients() { echo "Importing non-conflicting devices..." local temp_import="/tmp/import_filtered_${timestamp}.conf" local skip_device=0 + local pending_header="" while IFS= read -r line; do if [[ "$line" == "; === Device:"* ]]; then skip_device=0 - echo "$line" >> "$temp_import" + pending_header="$line" elif [[ "$line" =~ ^\[([0-9]+)\]$ ]]; then local ext="${BASH_REMATCH[1]}" if grep -q "^\[${ext}\]" /etc/asterisk/pjsip.conf 2>/dev/null; then skip_device=1 - echo " Skipping extension $ext (already exists)" + if [[ -n "$pending_header" ]]; then + echo " Skipping extension $ext (already exists)" + pending_header="" + fi else + if [[ -n "$pending_header" ]]; then + echo "$pending_header" >> "$temp_import" + pending_header="" + fi echo "$line" >> "$temp_import" fi elif [[ $skip_device -eq 0 ]]; then