Merge pull request #321 from outis1one/claude/extensions-qr-code-popup-6jlkcp

Claude/extensions qr code popup 6jlkcp
This commit is contained in:
Outis
2026-08-12 17:35:27 -04:00
committed by GitHub
2 changed files with 75 additions and 3 deletions
+67 -2
View File
@@ -385,6 +385,30 @@ _asterisk_refresh_vendor_files() {
else
log_warning "entrypoint.sh logger.conf template changed upstream — security events won't be logged to a file. Update the sed patch in this installer."
fi
# Regenerate the self-signed TLS cert when it doesn't match the current
# DOMAIN_NAME. Vendor's own check only asks "does the file exist" and
# "does it have a SAN extension" -- never "does the SAN match the domain
# actually configured now" -- so a domain entered once (even a
# placeholder, or one later changed) sticks in the cert FOREVER: it
# survives every subsequent update *and* full reinstall, because
# /etc/asterisk/certs is a bind-mounted host directory neither install
# mode ever wipes (the same reason pjsip.conf/devices survive reinstalls
# too). Confirmed live: a box's TLS transport kept presenting a cert for
# a stale, originally-entered domain long after DOMAIN_NAME had changed
# and a full reinstall had been run in between -- most SIP/TLS clients
# refuse a cert like that outright with no clear error, and this was the
# actual cause of a "port's open but registration still fails" case that
# every other check (firewall, coturn, DNS) had already come back clean.
if grep -q '^if \$regen_cert; then$' ./docker/entrypoint.sh; then
sed -i '/^if \$regen_cert; then$/i\
if [[ "$regen_cert" != true && -n "${DOMAIN_NAME:-}" ]] && ! openssl x509 -in /etc/asterisk/certs/server.crt -noout -ext subjectAltName 2>/dev/null | grep -q "DNS:${DOMAIN_NAME}"; then\
log_info "Existing TLS cert does not match current DOMAIN_NAME (${DOMAIN_NAME}) -- regenerating"\
regen_cert=true\
fi' ./docker/entrypoint.sh
else
log_warning "entrypoint.sh cert-regen check changed upstream — a stale-domain cert won't auto-regenerate. Update the sed patch in this installer."
fi
}
# ── Shared: log rotation for logs/full (unbounded otherwise) ──────────────
@@ -1310,6 +1334,44 @@ _asterisk_configure_do_cloud_firewall() {
fi
}
# ── Non-DO public VPS: no automated network-edge firewall step exists for
# arbitrary providers the way _asterisk_configure_do_cloud_firewall automates
# DigitalOcean via doctl -- there's no universal API to drive. But a box set
# up with a public FQDN is, in practice, almost always sitting behind some
# provider-managed firewall anyway, and skipping this reminder left it
# entirely unmentioned. Confirmed live on an IONOS VPS: UFW showed every SIP/
# TURN/RTP port as ALLOW, Asterisk's own PJSIP logger showed zero incoming
# packets of any kind, and nothing in this installer's own output pointed at
# the actual cause -- IONOS's separate network-level firewall (Cloud Panel ->
# Networking -> Firewall Policies) only allowed 22/80/443/8443/8447 and
# silently dropped everything else before it ever reached the box. UFW being
# wide open proves nothing about a layer in front of it that UFW can't see.
_asterisk_remind_non_do_firewall() {
local WEB_ADMIN_PORT_VAL="$1" WEB_ADMIN_PUBLIC_ACCESS_NEEDED="$2" USE_EMBEDDED_COTURN_VAL="${3:-true}"
echo ""
log_warning "This box is reachable via FQDN but wasn't set up as a DigitalOcean droplet,"
log_warning "so no automatic network-edge firewall was configured (that step only exists"
log_warning "for DO, via doctl). Most VPS/cloud providers run their OWN network-level"
log_warning "firewall in front of the box, separate from UFW and invisible to it — UFW can"
log_warning "show every port as ALLOW while traffic still gets silently dropped before it"
log_warning "ever reaches this box. Check your provider's console for it (e.g. IONOS: Cloud"
log_warning "Panel -> Networking -> Firewall Policies) and allow inbound, matching what UFW"
log_warning "just opened on this box:"
echo " TCP 22 (SSH)"
echo " UDP/TCP 5060 (SIP)"
echo " TCP 5061 (SIP TLS)"
[[ "$WEB_ADMIN_PUBLIC_ACCESS_NEEDED" == true ]] && echo " TCP ${WEB_ADMIN_PORT_VAL} (web admin)"
echo " TCP 8088, 8089 (Asterisk HTTP/HTTPS)"
echo " UDP 10000-20000 (RTP media)"
if [[ "$USE_EMBEDDED_COTURN_VAL" == true ]]; then
echo " UDP/TCP 3478 (TURN/STUN)"
echo " UDP 49152-49252 (TURN relay)"
else
echo " UDP/TCP 3478 and UDP 49152-49252 too, if the shared coturn instance"
echo " (services/coturn.sh) lives on this same box."
fi
}
# ── Shared: README ─────────────────────────────────────────────────────────
# One document with a droplet-only section appended in public-cloud mode, so
# the two deployment shapes can't document themselves differently by accident.
@@ -1964,9 +2026,12 @@ ENV
log_success "UFW rules added."
fi
# ── DigitalOcean Cloud Firewall (network edge) ────────────────────────────
[[ "$IS_DO" == true ]] && \
# ── Network-edge firewall (in front of the box, not UFW) ──────────────────
if [[ "$IS_DO" == true ]]; then
_asterisk_configure_do_cloud_firewall "$DROPLET_ID" "$WEB_ADMIN_PORT_VAL" "$WEB_ADMIN_PUBLIC_ACCESS_NEEDED"
elif [[ -n "$DOMAIN_NAME" ]]; then
_asterisk_remind_non_do_firewall "$WEB_ADMIN_PORT_VAL" "$WEB_ADMIN_PUBLIC_ACCESS_NEEDED" "$USE_EMBEDDED_COTURN"
fi
# ── CrowdSec note ──────────────────────────────────────────────────────────
# Not installed here — select it separately from the whiptail menu, or
+8 -1
View File
@@ -3632,7 +3632,14 @@ INDEX_HTML = """<!doctype html>
}
nav button:hover { color: var(--text); }
nav button.active { color: var(--text); border-bottom-color: var(--accent); }
main { padding: var(--sp-6); max-width: 1180px; margin: 0 auto; }
/* 1180 was too narrow for the Extensions table specifically (Ext, Name,
Mobile, Status, Transport, PSTN, Whitelist, Messaging, Voicemail, plus
the row-action column) -- ten columns including a dropdown and a free-text
whitelist field forced .table-wrap's horizontal scrollbar even on a normal
desktop viewport. 1600 gives every tab's tables room without it; narrow
viewports still fall back to that same scrollbar (.table-wrap already
handles it), this only raises the ceiling for wide ones. */
main { padding: var(--sp-6); max-width: 1600px; margin: 0 auto; }
/* ── Cards ────────────────────────────────────────────────────────────── */
.card {