Merge pull request #317 from outis1one/claude/ionos-script-integration-x32ofw
Claude/ionos script integration x32ofw
This commit is contained in:
@@ -143,7 +143,7 @@ account default in step 6 and skip even that:
|
||||
sudo ./setup.sh pstn-trunk
|
||||
```
|
||||
|
||||
- Existing install → choose **update** (`r`) if you're just changing the
|
||||
- Existing install → choose **update** (`u`) if you're just changing the
|
||||
DID/server, or the CLI will walk fresh prompts if none exists yet.
|
||||
- Provider quick-pick: **1) Anveo Direct** — pre-fills `sbc.anveo.com` and
|
||||
Anveo's 4 published signaling IPs (only one of which the hostname
|
||||
|
||||
+29
-4
@@ -718,12 +718,12 @@ prompt_reinstall_mode() {
|
||||
return
|
||||
fi
|
||||
echo " Existing install detected. Choose:"
|
||||
echo " r) Reinstall in place — refresh vendor files/config, keep existing settings"
|
||||
echo " f) Full install — re-run every prompt from scratch"
|
||||
echo " u) Update — refresh vendor files/config, keep existing settings"
|
||||
echo " f) Full reinstall — re-run every prompt from scratch"
|
||||
echo " c) Cancel — leave everything as-is [default]"
|
||||
read -p " Choice [r/f/c, Enter=cancel]: " response
|
||||
read -p " Choice [u/f/c, Enter=cancel]: " response
|
||||
case "${response,,}" in
|
||||
r) eval "$varname='update'" ;;
|
||||
u) eval "$varname='update'" ;;
|
||||
f) eval "$varname='fresh'" ;;
|
||||
*) eval "$varname='cancel'" ;;
|
||||
esac
|
||||
@@ -1076,6 +1076,31 @@ ensure_coturn_user() {
|
||||
_u="$(grep '^COTURN_USER=' "$_userfile" | cut -d= -f2-)"
|
||||
_p="$(grep '^COTURN_PASS=' "$_userfile" | cut -d= -f2-)"
|
||||
COTURN_USERNAME="$_u" COTURN_PASSWORD="$_p"
|
||||
|
||||
# The cache file surviving doesn't mean the username still exists in
|
||||
# coturn's own live database — confirmed live: a coturn
|
||||
# container/volume recreated without preserving ./db wipes the
|
||||
# database while this file (a separate directory) survives
|
||||
# untouched, silently orphaning every consumer's credentials until
|
||||
# something re-registers them. Without this check, re-running the
|
||||
# consumer's installer (fresh or update) never re-registers anything
|
||||
# since it only ever hits the else branch below on a MISSING cache
|
||||
# file — a stale-but-present one looked identical to a healthy one.
|
||||
# A real "user[realm]" line never contains a space; turnadmin -l's
|
||||
# own startup log lines do (confirmed live, at least one coturn
|
||||
# build writes them to stdout, not stderr), so filtering on that
|
||||
# keeps this robust across builds without needing to match a
|
||||
# specific log format.
|
||||
local _db_users
|
||||
_db_users="$(docker exec coturn turnadmin -l -b /var/lib/coturn/turndb 2>/dev/null | grep -v ' ' | sed -E 's/\[.*//' | awk 'NF')"
|
||||
if ! grep -qx "$_u" <<< "$_db_users"; then
|
||||
log_warning "coturn user '$_u' ($_consumer) has cached credentials but isn't in coturn's live database — re-registering with the same password."
|
||||
if docker exec coturn turnadmin -a -u "$_u" -p "$_p" -r "$_realm" -b /var/lib/coturn/turndb >/dev/null 2>&1; then
|
||||
log_success "Re-registered coturn user '$_u' for $_consumer"
|
||||
else
|
||||
log_warning "Could not re-register coturn user '$_u' for $_consumer — is the coturn container running?"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
COTURN_USERNAME="$_consumer"
|
||||
COTURN_PASSWORD="$(generate_password 24)"
|
||||
|
||||
+39
-5
@@ -82,12 +82,12 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
return
|
||||
fi
|
||||
echo " Existing install detected. Choose:"
|
||||
echo " r) Reinstall in place — refresh vendor files/config, keep existing settings"
|
||||
echo " f) Full install — re-run every prompt from scratch"
|
||||
echo " u) Update — refresh vendor files/config, keep existing settings"
|
||||
echo " f) Full reinstall — re-run every prompt from scratch"
|
||||
echo " c) Cancel — leave everything as-is [default]"
|
||||
read -r -p " Choice [r/f/c, Enter=cancel]: " _r
|
||||
read -r -p " Choice [u/f/c, Enter=cancel]: " _r
|
||||
case "${_r,,}" in
|
||||
r) eval "$_var='update'" ;;
|
||||
u) eval "$_var='update'" ;;
|
||||
f) eval "$_var='fresh'" ;;
|
||||
*) eval "$_var='cancel'" ;;
|
||||
esac
|
||||
@@ -1655,6 +1655,21 @@ install_asterisk() {
|
||||
log_warning "docker compose up failed — check: docker compose -f $EA_DIR/docker-compose.yml logs"
|
||||
fi
|
||||
|
||||
# Self-heal a stale/orphaned shared-coturn registration on
|
||||
# every update, not just a full reinstall — the check inside
|
||||
# ensure_coturn_user() is what actually re-registers a
|
||||
# missing user, this just needs to reach it. Gated on NOT
|
||||
# having an embedded coturn: an install with its own
|
||||
# dedicated coturn deliberately never touches the shared one
|
||||
# on update (see the warning above and CLAUDE.md's coturn
|
||||
# migration guidance) — calling this unconditionally would
|
||||
# silently chain-install services/coturn.sh for a box that
|
||||
# was never using it, the exact "don't migrate silently on
|
||||
# update" mistake that guidance warns against.
|
||||
if [[ "$_HAD_EMBEDDED_COTURN" != true ]]; then
|
||||
ensure_coturn_user "asterisk"
|
||||
fi
|
||||
|
||||
_asterisk_run_presence_step "$EA_DIR" "$CONTAINER"
|
||||
_asterisk_offer_dashboard_and_trunk "$EA_DIR"
|
||||
|
||||
@@ -1677,7 +1692,26 @@ install_asterisk() {
|
||||
return 0
|
||||
;;
|
||||
fresh)
|
||||
log_info "Proceeding with a full fresh reinstall — every prompt below runs from scratch."
|
||||
echo ""
|
||||
log_warning "Full reinstall stops the existing containers and re-runs every"
|
||||
log_warning "prompt below from scratch (domain, networking, firewall, Caddy/"
|
||||
log_warning "Authelia). The TURN credential registered with the shared coturn"
|
||||
log_warning "service is reused as-is — no need to touch coturn for this."
|
||||
local _WIPE_PBX_DATA=""
|
||||
prompt_yn " Also delete stored PBX data (extensions, voicemail, recordings, spool)? (y/n):" "n" _WIPE_PBX_DATA
|
||||
|
||||
log_info "Stopping the existing containers..."
|
||||
(cd "$EA_DIR" && docker compose down 2>/dev/null)
|
||||
|
||||
if [[ "$_WIPE_PBX_DATA" =~ ^[Yy]$ ]]; then
|
||||
rm -rf "$EA_DIR/config/asterisk" "$EA_DIR/spool" "$EA_DIR/logs" "$EA_DIR/lib"
|
||||
log_warning "Deleted config/asterisk, spool, logs, and lib — extensions,"
|
||||
log_warning "voicemail, and call recordings are gone."
|
||||
if declare -F install_pstn-trunk >/dev/null 2>&1 || [ -f "$EA_DIR/pstn-trunk-usage-alert.sh" ]; then
|
||||
log_warning "PSTN trunk patches config/asterisk's dialplan — re-run"
|
||||
log_warning "'sudo ./setup.sh pstn-trunk' afterward to restore it."
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
+25
-4
@@ -87,12 +87,12 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
local _var="$1" _r
|
||||
if [[ "${UNATTENDED:-false}" == "true" ]]; then eval "$_var='cancel'"; return; fi
|
||||
echo " Existing install detected. Choose:"
|
||||
echo " r) Reinstall in place — refresh vendor files, keep existing settings"
|
||||
echo " f) Full install — re-run every prompt from scratch"
|
||||
echo " u) Update — refresh vendor files, keep existing settings"
|
||||
echo " f) Full reinstall — re-run every prompt from scratch"
|
||||
echo " c) Cancel — leave everything as-is [default]"
|
||||
read -r -p " Choice [r/f/c, Enter=cancel]: " _r
|
||||
read -r -p " Choice [u/f/c, Enter=cancel]: " _r
|
||||
case "${_r,,}" in
|
||||
r) eval "$_var='update'" ;;
|
||||
u) eval "$_var='update'" ;;
|
||||
f) eval "$_var='fresh'" ;;
|
||||
*) eval "$_var='cancel'" ;;
|
||||
esac
|
||||
@@ -186,6 +186,27 @@ install_coturn() {
|
||||
log_warning "change the host/port/realm below, every already-registered consumer"
|
||||
log_warning "(Asterisk, Mattermost, ...) keeps pointing at the OLD values in its own"
|
||||
log_warning ".env until you re-run that service's installer too."
|
||||
|
||||
local _consumers=""
|
||||
[ -d "$DIR/users" ] && _consumers="$(find "$DIR/users" -maxdepth 1 -name '*.env' -printf '%f\n' 2>/dev/null | sed 's/\.env$//' | tr '\n' ' ')"
|
||||
if [ -n "$_consumers" ]; then
|
||||
echo ""
|
||||
log_info "Registered consumers: $_consumers"
|
||||
local _WIPE_USERS=""
|
||||
prompt_yn " Also delete all TURN user credentials and the user database (forces every consumer above to re-register)? (y/n):" "n" _WIPE_USERS
|
||||
if [[ "$_WIPE_USERS" =~ ^[Yy]$ ]]; then
|
||||
rm -rf "$DIR/users" "$DIR/db"
|
||||
mkdir -p "$DIR/db" "$DIR/users"
|
||||
# The running container (if any) still holds the old,
|
||||
# now-deleted turndb file open — new turnadmin writes
|
||||
# to the fresh file at that path go unseen until the
|
||||
# server process restarts and reopens it.
|
||||
docker restart coturn >/dev/null 2>&1
|
||||
log_warning "Deleted TURN credentials and the user database."
|
||||
log_warning "Re-run each consumer's installer in Update mode afterward —"
|
||||
log_warning "ensure_coturn_user() auto-recovers a fresh credential for it."
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -314,6 +314,20 @@ install_mattermost() {
|
||||
log_warning "the shared coturn service — the Calls plugin's TURN config in System"
|
||||
log_warning "Console will need updating to the new credentials afterward (see below)."
|
||||
fi
|
||||
echo ""
|
||||
log_warning "Full reinstall stops the existing containers and re-runs every prompt"
|
||||
log_warning "below from scratch. The TURN credential registered with the shared"
|
||||
log_warning "coturn service is reused as-is — no need to touch coturn for this."
|
||||
local _WIPE_MM_DATA=""
|
||||
prompt_yn " Also delete stored data (Postgres database, uploaded files, config, plugins)? (y/n):" "n" _WIPE_MM_DATA
|
||||
|
||||
log_info "Stopping the existing containers..."
|
||||
(cd "$DIR" && docker compose down 2>/dev/null)
|
||||
|
||||
if [[ "$_WIPE_MM_DATA" =~ ^[Yy]$ ]]; then
|
||||
rm -rf "$DIR/db" "$DIR/data" "$DIR/logs" "$DIR/config" "$DIR/plugins"
|
||||
log_warning "Deleted the Postgres database, uploaded files, config, and plugins."
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -184,7 +184,24 @@ install_security-dashboard() {
|
||||
log_info "Leaving the existing install as-is."
|
||||
return 0
|
||||
;;
|
||||
fresh) ;;
|
||||
fresh)
|
||||
echo ""
|
||||
log_warning "Full reinstall stops the dashboard and removes its systemd unit,"
|
||||
log_warning "sudoers grant, Caddy block, service user, and app files, then sets"
|
||||
log_warning "it up again from scratch — every prompt below runs as if this were"
|
||||
log_warning "a brand new install."
|
||||
local _WIPE_ADMINS=""
|
||||
prompt_yn " Also delete dashboard-admins.conf (per-admin Calls/Texts/Voicemail scoping)? (y/n):" "n" _WIPE_ADMINS
|
||||
|
||||
local _ADMINS_BACKUP=""
|
||||
if [[ ! "$_WIPE_ADMINS" =~ ^[Yy]$ ]] && [ -f "$APP_DIR/dashboard-admins.conf" ]; then
|
||||
_ADMINS_BACKUP="$(mktemp)"
|
||||
cp "$APP_DIR/dashboard-admins.conf" "$_ADMINS_BACKUP"
|
||||
log_info "Preserving dashboard-admins.conf across the reinstall."
|
||||
fi
|
||||
|
||||
_secdash_teardown "$APP_DIR" "$SVC_USER" "$DASHBOARD_PORT"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -197,6 +214,11 @@ install_security-dashboard() {
|
||||
_secdash_grant_asterisk_access "$SVC_USER" "$ASTERISK_LOG_DIR" "$ASTERISK_CONFIG_DIR" "$ASTERISK_EA_CONFIG_DIR" "$ASTERISK_SPOOL_DIR"
|
||||
|
||||
mkdir -p "$APP_DIR"
|
||||
if [ -n "${_ADMINS_BACKUP:-}" ]; then
|
||||
cp "$_ADMINS_BACKUP" "$APP_DIR/dashboard-admins.conf"
|
||||
rm -f "$_ADMINS_BACKUP"
|
||||
log_success "Restored dashboard-admins.conf"
|
||||
fi
|
||||
_secdash_write_app "$APP_DIR"
|
||||
chown -R "$SVC_USER:$SVC_USER" "$APP_DIR"
|
||||
_secdash_write_asn_helper "$APP_DIR"
|
||||
@@ -974,6 +996,35 @@ _secdash_remove_caddy_block() {
|
||||
log_info "Removed the existing dashboard Caddy block (regenerating it fresh)."
|
||||
}
|
||||
|
||||
# Full teardown for "Full reinstall" — stops the service and removes
|
||||
# everything a fresh install recreates: systemd unit, sudoers grant, Caddy
|
||||
# site block, the secdash system user, and the app directory. Non-Docker
|
||||
# service (systemd + /opt, not a container), so lib/common.sh's
|
||||
# remove_service() (Docker-only, $DOCKER_DIR/<name>) doesn't apply here —
|
||||
# this is the equivalent for this one service. Callers are responsible for
|
||||
# backing up/restoring anything under $_app_dir they want to survive (see
|
||||
# the dashboard-admins.conf handling around the "fresh" case in
|
||||
# install_security-dashboard() — this function does not know which files,
|
||||
# if any, the caller wants to keep).
|
||||
_secdash_teardown() {
|
||||
local _app_dir="$1" _svc_user="$2" _port="$3"
|
||||
|
||||
systemctl stop security-dashboard 2>/dev/null || true
|
||||
systemctl disable security-dashboard 2>/dev/null || true
|
||||
rm -f /etc/systemd/system/security-dashboard.service
|
||||
systemctl daemon-reload
|
||||
|
||||
rm -f /etc/sudoers.d/security-dashboard
|
||||
|
||||
_secdash_remove_caddy_block "$_port"
|
||||
|
||||
id "$_svc_user" &>/dev/null && userdel "$_svc_user" 2>/dev/null
|
||||
|
||||
rm -rf "$_app_dir"
|
||||
|
||||
log_success "Removed security-dashboard's systemd unit, sudoers grant, Caddy block, user, and app files."
|
||||
}
|
||||
|
||||
# Root-owned helper for editing CrowdSec's Asterisk-scenario YAMLs — the
|
||||
# secdash service user (--shell /usr/sbin/nologin, no special file grants)
|
||||
# cannot write /etc/crowdsec/scenarios/*.yaml directly (root:root, mode
|
||||
|
||||
@@ -95,12 +95,12 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
local _var="$1" _r
|
||||
if [[ "${UNATTENDED:-false}" == "true" ]]; then eval "$_var='cancel'"; return; fi
|
||||
echo " Existing install detected. Choose:"
|
||||
echo " r) Reinstall in place — refresh image/compose, keep database and settings"
|
||||
echo " f) Full install — re-run every prompt from scratch"
|
||||
echo " u) Update — refresh image/compose, keep database and settings"
|
||||
echo " f) Full reinstall — re-run every prompt from scratch"
|
||||
echo " c) Cancel — leave everything as-is [default]"
|
||||
read -r -p " Choice [r/f/c, Enter=cancel]: " _r
|
||||
read -r -p " Choice [u/f/c, Enter=cancel]: " _r
|
||||
case "${_r,,}" in
|
||||
r) eval "$_var='update'" ;;
|
||||
u) eval "$_var='update'" ;;
|
||||
f) eval "$_var='fresh'" ;;
|
||||
*) eval "$_var='cancel'" ;;
|
||||
esac
|
||||
|
||||
@@ -76,7 +76,14 @@ ok "Relay port range: ${COTURN_MIN_PORT}-${COTURN_MAX_PORT}"
|
||||
# ── Registered consumers ──────────────────────────────────────────────────────
|
||||
section "Registered consumers"
|
||||
|
||||
DB_USERS="$(docker exec coturn turnadmin -l -b /var/lib/coturn/turndb 2>/dev/null | sed -E 's/\[.*//' | awk 'NF' | sort -u)"
|
||||
# turnadmin -l writes its own startup log lines ("INFO SQLite connection
|
||||
# was closed.", "INFO log file opened: ...") to STDOUT on at least some
|
||||
# coturn builds, not stderr — confirmed live, `2>/dev/null` alone let them
|
||||
# through and got misparsed as usernames. A real "user[realm]" line never
|
||||
# contains a space; every log line here does, so filtering those out is a
|
||||
# safe, simple way to keep only genuine entries regardless of which coturn
|
||||
# build's log-noise happens to leak onto stdout.
|
||||
DB_USERS="$(docker exec coturn turnadmin -l -b /var/lib/coturn/turndb 2>/dev/null | grep -v ' ' | sed -E 's/\[.*//' | awk 'NF' | sort -u)"
|
||||
if [ -z "$DB_USERS" ]; then
|
||||
warn "No users found in coturn's own database — nothing has actually registered yet, or turnadmin -l's output format changed. Raw:"
|
||||
docker exec coturn turnadmin -l -b /var/lib/coturn/turndb 2>&1 | sed 's/^/ /'
|
||||
|
||||
Reference in New Issue
Block a user