Merge pull request #377 from outis1one/claude/frigate-authelia-openid-0l1htj

Claude/frigate authelia openid 0l1htj
This commit is contained in:
Outis
2026-08-21 23:22:07 -04:00
committed by GitHub
6 changed files with 142 additions and 38 deletions
+20 -5
View File
@@ -44,11 +44,26 @@ public-FQDN-only flow, hand-built Caddy site block, remote Authelia, Cloud
Firewall — behind that one answer. Two lessons worth reusing:
- **Don't rename a live install's directory or containers.** New installs
land in `~/docker/asterisk` with `easy-asterisk`; a pre-merge droplet keeps
`~/docker/asterisk-digital-ocean` and `easy-asterisk-do`, because its
Caddyfile block, UFW rules, Cloud Firewall, CrowdSec acquisition and PSTN
trunk all name those exact paths. `_asterisk_resolve_layout()` picks
whichever exists, and every sibling service probes both.
land in `~/docker/asterisk` with a container named `asterisk`; a pre-merge
droplet keeps `~/docker/asterisk-digital-ocean` and `easy-asterisk-do`,
because its Caddyfile block, UFW rules, Cloud Firewall, CrowdSec
acquisition and PSTN trunk all name those exact paths.
`_asterisk_resolve_layout()` picks whichever directory exists, and every
sibling service probes both. The plain container name was itself renamed
once already — from `easy-asterisk` (this repo's original choice, reusing
the vendor CLI tool's own name, `/usr/local/bin/easy-asterisk` inside the
container — unrelated, never renamed) to plain `asterisk`, matching every
other service's own `container_name == service name` convention. The same
"don't rename under a running deployment" rule applied: every resolver
(`_asterisk_resolve_layout()` and the duplicated copies in
`security-dashboard.sh`, `sms-inbound.sh`, `pstn-trunk.sh`,
`tools/pstn-test-check.sh`) reads the container name out of the box's own
`docker-compose.yml` instead of assuming it, so an existing `easy-asterisk`
install keeps working unchanged. Migrating one to the new name is a
deliberate, one-time action on that box (edit `docker-compose.yml`'s
`container_name:` for both Asterisk and its coturn sidecar, `docker compose
down` + `up -d`) — once done, every sibling service re-reads it from that
same file and follows automatically.
- **Check whether a "flavor-specific" behavior was actually flavor-specific.**
The Asterisk security-logging patch and the `logs/full` logrotate config
were droplet-only purely because that's where they got written first — the
+76 -21
View File
@@ -298,6 +298,21 @@ register_service asterisk homelab "Easy Asterisk PBX (intercom/VoIP; auto-tunes
# naming. Every sibling service in this repo (pstn-trunk, security-dashboard,
# crowdsec) already probes for both directories, so both layouts stay fully
# supported without further special-casing.
#
# Container name itself: new installs use the plain "asterisk" (matching
# every other service's own container_name == service name convention —
# "easy-" was this repo's install-time container name before, left over from
# when the vendor CLI tool's own name (`easy-asterisk`, still installed at
# /usr/local/bin/easy-asterisk inside the container — unrelated, never
# renamed) got reused for the container too. A box that already has a
# running container is read directly from its own docker-compose.yml instead
# of assumed from the directory, so an existing "easy-asterisk" install
# keeps working with no silent rename — same reasoning as the droplet-layout
# preservation above, just one level down (container name, not directory).
# Migrating an existing box to the new name is a deliberate, one-time action
# (edit docker-compose.yml's container_name + coturn, `docker compose down`
# + `up -d`) — once done, every sibling service here re-reads it from that
# same file and follows automatically, no further changes needed anywhere.
_asterisk_resolve_layout() {
if [[ -f "$DOCKER_DIR/asterisk-digital-ocean/docker-compose.yml" ]]; then
ASTERISK_DIR="$DOCKER_DIR/asterisk-digital-ocean"
@@ -306,9 +321,13 @@ _asterisk_resolve_layout() {
ASTERISK_PROJECT="asterisk-do"
else
ASTERISK_DIR="$DOCKER_DIR/asterisk"
ASTERISK_CONTAINER="easy-asterisk"
ASTERISK_COTURN="easy-asterisk-coturn"
ASTERISK_PROJECT="asterisk"
ASTERISK_CONTAINER=""
if [[ -f "$ASTERISK_DIR/docker-compose.yml" ]]; then
ASTERISK_CONTAINER="$(grep -m1 '^[[:space:]]*container_name:' "$ASTERISK_DIR/docker-compose.yml" | awk '{print $2}')"
fi
[[ -z "$ASTERISK_CONTAINER" ]] && ASTERISK_CONTAINER="asterisk"
ASTERISK_COTURN="${ASTERISK_CONTAINER}-coturn"
fi
}
@@ -1284,7 +1303,7 @@ _asterisk_ensure_live_voicemail_include() {
docker exec "$CONTAINER_NAME" asterisk -rx "dialplan reload" &>/dev/null || true
}
# ── pjsip.conf: [transport-tls] keep_alive_interval ─────────────────────────
# ── pjsip.conf: [global] keep_alive_interval ─────────────────────────────────
# Mitigation for WiFi/LAN SIP clients (e.g. Sipnetic on Android) dropping
# their TLS registration every few seconds on some hosts but not others —
# confirmed live on an IONOS VPS (never reproduced on a DigitalOcean droplet
@@ -1293,15 +1312,28 @@ _asterisk_ensure_live_voicemail_include() {
# live disconnect and CrowdSec/packet-loss both ruled out first. Leading
# theory: an idle-connection timeout somewhere in IONOS's own network
# virtualization layer, below anything client-side tools can see. PJSIP's
# `keep_alive_interval` sends a lightweight double-CRLF over the transport's
# TLS connection on a timer, which is the standard fix for exactly this
# `keep_alive_interval` sends a lightweight double-CRLF over connection-oriented
# transports (TCP/TLS) on a timer, which is the standard fix for exactly this
# class of "idle SIP/TLS connection gets silently dropped" symptom.
#
# This is a *transport* option, not an endpoint/AOR option — `qualify_frequency`
# (already set globally) is an endpoint-level OPTIONS ping that re-establishes
# a dropped connection, it doesn't stop the drop from happening in the first
# place. `rtp_keepalive` (mobile devices) is unrelated: RTP media keepalive
# during an active call, not SIP signaling connection keepalive while idle.
# **This is a `type=global` option, not a `type=transport` option**it does
# not exist on `[transport-tls]`/`[transport-tcp]` objects at all, on any
# Asterisk version. An earlier version of this patch inserted it into
# `[transport-tls]` (right after `protocol=tls`), which sorcery always
# rejects: "Could not find option suitable for category 'transport-tls'
# named 'keep_alive_interval'" — and rejecting the option means the whole
# `type=transport` object fails to be created, so `transport-tls` never
# binds at all. Confirmed live: this silently took down TLS SIP entirely on
# a box that had picked up the patch, reproducing the exact same "network
# error on all calls" symptom the rest of this file's health check exists to
# catch. The anchor below targets `type=global` inside `[global]` instead.
#
# This is a *transport-behavior* option, not an endpoint/AOR option —
# `qualify_frequency` (already set globally) is an endpoint-level OPTIONS
# ping that re-establishes a dropped connection, it doesn't stop the drop
# from happening in the first place. `rtp_keepalive` (mobile devices) is
# unrelated: RTP media keepalive during an active call, not SIP signaling
# connection keepalive while idle.
_asterisk_patch_keepalive_vendor_files() {
local EA_DIR="$1"
local ENTRYPOINT="$EA_DIR/docker/entrypoint.sh"
@@ -1313,15 +1345,20 @@ _asterisk_patch_keepalive_vendor_files() {
for f in "$ENTRYPOINT" "$EASY1" "$EASY2"; do
[[ -f "$f" ]] || continue
if ! grep -q '^protocol=tls$' "$f"; then
log_warning "$(basename "$f"): '[transport-tls]' anchor not found — vendor template changed upstream."
log_warning " Add 'keep_alive_interval=15' manually inside [transport-tls] in this file's pjsip.conf heredoc."
# Undo the old, incorrect [transport-tls] placement if an earlier
# run of this function already patched it there.
if grep -q '^protocol=tls$' "$f" && grep -A2 '^protocol=tls$' "$f" | grep -q '^keep_alive_interval='; then
sed -i '/^protocol=tls$/{n;/^keep_alive_interval=/d}' "$f"
fi
if ! grep -q '^type=global$' "$f"; then
log_warning "$(basename "$f"): '[global]' anchor not found — vendor template changed upstream."
log_warning " Add 'keep_alive_interval=15' manually inside [global] (not [transport-tls]) in this file's pjsip.conf heredoc."
continue
fi
grep -q '^keep_alive_interval=' "$f" || sed -i '/^protocol=tls$/a keep_alive_interval=15' "$f"
grep -q '^keep_alive_interval=' "$f" || sed -i '/^type=global$/a keep_alive_interval=15' "$f"
done
log_success "Vendor generator functions patched for TLS transport keepalive."
log_success "Vendor generator functions patched for SIP keepalive (pjsip.conf [global])."
}
# Live-file counterpart to the vendor-template patch above, same reasoning
@@ -1332,20 +1369,38 @@ _asterisk_patch_keepalive_vendor_files() {
# a transport object — PJSIP transports are bound at module load, not
# reloadable via sorcery like endpoints/AORs are — so this restarts the
# container rather than issuing a reload, same as _asterisk_ensure_live_dangerously.
#
# `keep_alive_interval` belongs in `[global]` (`type=global`), not
# `[transport-tls]` — see the comment on _asterisk_patch_keepalive_vendor_files
# for why the old placement made sorcery reject the transport object outright
# (killing TLS SIP entirely, not just the keepalive). This also self-heals a
# box that already has the bad `[transport-tls]` entry from before that fix.
_asterisk_ensure_live_keepalive() {
local EA_DIR="$1" CONTAINER_NAME="$2"
local CONF_LIVE="$EA_DIR/config/asterisk/pjsip.conf"
[[ -f "$CONF_LIVE" ]] || return 0
if ! grep -q '^\[transport-tls\]$' "$CONF_LIVE"; then
log_warning "Couldn't find '[transport-tls]' in the live pjsip.conf — add"
local CHANGED=false
if sed -n '/^\[transport-tls\]$/,/^\[/{/^keep_alive_interval=/p}' "$CONF_LIVE" | grep -q .; then
sed -i '/^\[transport-tls\]$/,/^\[/{/^keep_alive_interval=/d}' "$CONF_LIVE"
log_warning "Removed 'keep_alive_interval' from [transport-tls] — that option doesn't exist on a PJSIP"
log_warning "transport object and was making the whole TLS transport fail to bind. Moving it to [global]."
CHANGED=true
fi
if ! grep -q '^\[global\]$' "$CONF_LIVE"; then
log_warning "Couldn't find '[global]' in the live pjsip.conf — add"
log_warning "'keep_alive_interval=15' manually inside that section, then: docker restart ${CONTAINER_NAME}"
return 0
fi
grep -q '^keep_alive_interval=' "$CONF_LIVE" && return 0
sed -i '/^\[transport-tls\]$/,/^\[/{/^protocol=tls$/a keep_alive_interval=15
if ! grep -q '^keep_alive_interval=' "$CONF_LIVE"; then
sed -i '/^\[global\]$/,/^\[/{/^type=global$/a keep_alive_interval=15
}' "$CONF_LIVE"
log_success "Patched keep_alive_interval=15 into the live pjsip.conf's [transport-tls] transport."
log_success "Patched keep_alive_interval=15 into the live pjsip.conf's [global] section."
CHANGED=true
fi
[[ "$CHANGED" == true ]] || return 0
log_info "Restarting Asterisk to apply (transport options aren't picked up by a reload)..."
docker restart "$CONTAINER_NAME" &>/dev/null \
+21 -6
View File
@@ -1436,7 +1436,7 @@ _pstn_check_killswitch_clear() {
# _pstn_install_periodic_timer above) ───────────────────────────────────────
_pstn_write_usage_alert_script() {
local FILE="$1" EA_DIR="$2" ASTERISK_DIR="$3" RATE="$4" MONTH_THRESHOLD="$5" \
BURST_THRESHOLD="$6" MAX_MONTHLY_SPEND="$7" NTFY_URL="$8" CONTAINER_NAME="${9:-easy-asterisk}"
BURST_THRESHOLD="$6" MAX_MONTHLY_SPEND="$7" NTFY_URL="$8" CONTAINER_NAME="${9:-asterisk}"
cat > "$FILE" << 'EOF'
#!/bin/bash
# Auto-generated by services/pstn-trunk.sh — do not edit directly, re-run
@@ -1719,7 +1719,7 @@ _pstn_apply_settings() {
local EA_DIR="$1" ASTERISK_DIR="$2"
local SERVER="$3" SERVER_IPS="$4" DID="$5"
local RING_EXTS="$6" NTFY_URL="$7" RATE="$8" MONTH_THRESHOLD="$9" BURST_THRESHOLD="${10}"
local PROVIDER_NAME="${11}" MAX_MONTHLY_SPEND="${12:-0}" CONTAINER_NAME="${13:-easy-asterisk}"
local PROVIDER_NAME="${11}" MAX_MONTHLY_SPEND="${12:-0}" CONTAINER_NAME="${13:-asterisk}"
_pstn_patch_vendor_files "$EA_DIR" || return 1
@@ -1879,8 +1879,18 @@ install_pstn-trunk() {
local KILLSWITCH_FILE="$ASTERISK_DIR/pstn-trunk-killswitch.conf"
local PERSONAL_DIDS_FILE="$ASTERISK_DIR/pstn-personal-dids.conf"
local SETTINGS_FILE="$EA_DIR/.pstn-trunk.env"
local CONTAINER_NAME="easy-asterisk"
[[ "$ASTERISK_KIND" == "asterisk-digital-ocean" ]] && CONTAINER_NAME="easy-asterisk-do"
# Read the box's own container_name instead of assuming — new installs
# use plain "asterisk" now, but an existing "easy-asterisk" install
# (this repo's container name before that rename) keeps working
# unchanged until someone deliberately migrates it. See
# services/asterisk.sh's _asterisk_resolve_layout for the reasoning.
local CONTAINER_NAME="asterisk"
if [[ "$ASTERISK_KIND" == "asterisk-digital-ocean" ]]; then
CONTAINER_NAME="easy-asterisk-do"
elif [[ -f "$EA_DIR/docker-compose.yml" ]]; then
CONTAINER_NAME="$(grep -m1 '^[[:space:]]*container_name:' "$EA_DIR/docker-compose.yml" | awk '{print $2}')"
[[ -z "$CONTAINER_NAME" ]] && CONTAINER_NAME="asterisk"
fi
if [ "$DRY_RUN" = true ]; then
echo "[DRY-RUN] Would require an existing asterisk install (droplet or home/LAN)"
@@ -1988,8 +1998,13 @@ install_pstn-trunk() {
# never picking up dialplan changes at all. Re-assert the fresh
# detection here, discarding the sourced value, so it can't drift
# from reality and self-heals the persisted file too.
CONTAINER_NAME="easy-asterisk"
[[ "$ASTERISK_KIND" == "asterisk-digital-ocean" ]] && CONTAINER_NAME="easy-asterisk-do"
CONTAINER_NAME="asterisk"
if [[ "$ASTERISK_KIND" == "asterisk-digital-ocean" ]]; then
CONTAINER_NAME="easy-asterisk-do"
elif [[ -f "$EA_DIR/docker-compose.yml" ]]; then
CONTAINER_NAME="$(grep -m1 '^[[:space:]]*container_name:' "$EA_DIR/docker-compose.yml" | awk '{print $2}')"
[[ -z "$CONTAINER_NAME" ]] && CONTAINER_NAME="asterisk"
fi
_pstn_check_killswitch_clear "$ASTERISK_DIR"
_pstn_apply_settings "$EA_DIR" "$ASTERISK_DIR" \
"$TRUNK_SERVER" "${TRUNK_SERVER_IPS:-}" "$TRUNK_DID" \
+9 -1
View File
@@ -105,7 +105,15 @@ install_security-dashboard() {
if [[ "$ASTERISK_EA_DIR" == *asterisk-digital-ocean ]]; then
ASTERISK_EA_CONTAINER="easy-asterisk-do"
elif [ -n "$ASTERISK_EA_DIR" ]; then
ASTERISK_EA_CONTAINER="easy-asterisk"
# Read the box's own container_name instead of assuming — new
# installs use plain "asterisk" now, but an existing "easy-asterisk"
# install (this repo's container name before that rename) keeps
# working unchanged until someone deliberately migrates it. See
# services/asterisk.sh's _asterisk_resolve_layout for the reasoning.
if [[ -f "$ASTERISK_EA_DIR/docker-compose.yml" ]]; then
ASTERISK_EA_CONTAINER="$(grep -m1 '^[[:space:]]*container_name:' "$ASTERISK_EA_DIR/docker-compose.yml" | awk '{print $2}')"
fi
[[ -z "$ASTERISK_EA_CONTAINER" ]] && ASTERISK_EA_CONTAINER="asterisk"
fi
echo ""
+9 -1
View File
@@ -53,7 +53,15 @@ _sms_detect_container_name() {
if [[ "$_ea_dir" == *asterisk-digital-ocean ]]; then
echo "easy-asterisk-do"
else
echo "easy-asterisk"
# Read the box's own container_name instead of assuming — new
# installs use plain "asterisk" now, but an existing "easy-asterisk"
# install (this repo's container name before that rename) keeps
# working unchanged until someone deliberately migrates it. See
# services/asterisk.sh's _asterisk_resolve_layout for the reasoning.
local _name=""
[[ -f "$_ea_dir/docker-compose.yml" ]] && \
_name="$(grep -m1 '^[[:space:]]*container_name:' "$_ea_dir/docker-compose.yml" | awk '{print $2}')"
echo "${_name:-asterisk}"
fi
}
+7 -4
View File
@@ -56,9 +56,13 @@ fi
# ── Container + directory detection ─────────────────────────────────────────
section "Detecting install"
CONTAINER="$(docker ps --format '{{.Names}}' 2>/dev/null | grep -m1 -E '^easy-asterisk(-do)?$' || true)"
# "asterisk" is this repo's current container name; "easy-asterisk" is what
# an install kept from before that rename (never silently renamed under a
# running deployment); "easy-asterisk-do"/"asterisk-do" cover a DigitalOcean
# droplet install, old or new naming. Whichever is actually running wins.
CONTAINER="$(docker ps --format '{{.Names}}' 2>/dev/null | grep -m1 -E '^(easy-)?asterisk(-do)?$' || true)"
if [ -z "$CONTAINER" ]; then
fail "No running easy-asterisk / easy-asterisk-do container found — is asterisk installed and started?"
fail "No running asterisk / easy-asterisk / *-do container found — is asterisk installed and started?"
echo ""
echo " $PASS passed, $WARN warnings, $FAIL failed. Stopping — nothing else can be checked without a running container."
exit 1
@@ -196,8 +200,7 @@ if [ -z "$TURN_SERVER" ]; then
warn "Add it via: sudo ./setup.sh asterisk (update mode)"
else
if grep -q '^ coturn:' "$EA_DIR/docker-compose.yml" 2>/dev/null; then
COTURN_CONTAINER="easy-asterisk-coturn"
[[ "$CONTAINER" == *-do ]] && COTURN_CONTAINER="easy-asterisk-do-coturn"
COTURN_CONTAINER="${CONTAINER}-coturn"
ok "Using an embedded, per-Asterisk coturn ($COTURN_CONTAINER); tested separately below."
else
COTURN_CONTAINER="coturn"