fix(cluster): strict SIP isolation on standby node and progressive BLF wake on master to eliminate stuck BLF lights

This commit is contained in:
sorcier committed 2026-11-06 09:54:39 +01:00
1 parent fd15f05b7a
commit e54de57105
4 files changed
+41 -7

No files matched your search

+12 -1
View File
@@ -29,5 +29,16 @@ if pidof asterisk >/dev/null 2>&1; then
/usr/sbin/asterisk -rx "dialplan reload" >> "$LOG_FILE" 2>&1 || true
fi
echo "[$TIMESTAMP] [CLUSTER] Mode Standby actif. En écoute des battements de cœur VRRP." >> "$LOG_FILE"
# 3. Isolation SIP stricte du nœud Standby / Backup via iptables (Architecture Télécom HA)
# Un nœud en veille ne doit JAMAIS répondre aux requêtes SIP des téléphones.
# Tout paquet SIP arrivant sur le Slave est immédiatement rejeté (ICMP port unreachable),
# ce qui force les téléphones (Yealink T46S, T54W, Fanvil, Snom...) à clore immédiatement
# leurs anciens dialogues orphelins et à réémettre leurs SUBSCRIBE BLF et REGISTER vers la VIP active.
iptables -C INPUT -i lo -j ACCEPT 2>/dev/null || iptables -I INPUT -i lo -j ACCEPT
iptables -C INPUT -p udp -m multiport --dports 5060,5061 -j REJECT --reject-with icmp-port-unreachable 2>/dev/null || \
iptables -A INPUT -p udp -m multiport --dports 5060,5061 -j REJECT --reject-with icmp-port-unreachable
iptables -C INPUT -p tcp -m multiport --dports 5060,5061 -j REJECT --reject-with tcp-reset 2>/dev/null || \
iptables -A INPUT -p tcp -m multiport --dports 5060,5061 -j REJECT --reject-with tcp-reset
echo "[$TIMESTAMP] [CLUSTER] Mode Standby actif (Ports SIP isolés). En écoute des battements de cœur VRRP." >> "$LOG_FILE"
exit 0
+7
View File
@@ -15,4 +15,11 @@ if [ -f "$DB_PATH" ]; then
sqlite3 "$DB_PATH" "UPDATE cluster_settings SET last_sync_status='fault', updated_at=CURRENT_TIMESTAMP WHERE id=1;" 2>/dev/null || true
fi
# Isolation des ports SIP en cas d'anomalie
iptables -C INPUT -i lo -j ACCEPT 2>/dev/null || iptables -I INPUT -i lo -j ACCEPT
iptables -C INPUT -p udp -m multiport --dports 5060,5061 -j REJECT --reject-with icmp-port-unreachable 2>/dev/null || \
iptables -A INPUT -p udp -m multiport --dports 5060,5061 -j REJECT --reject-with icmp-port-unreachable
iptables -C INPUT -p tcp -m multiport --dports 5060,5061 -j REJECT --reject-with tcp-reset 2>/dev/null || \
iptables -A INPUT -p tcp -m multiport --dports 5060,5061 -j REJECT --reject-with tcp-reset
exit 0
+20 -6
View File
@@ -10,6 +10,10 @@ TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$TIMESTAMP] [CLUSTER] >>> Transition vers l'état MASTER (VIP active) <<<" >> "$LOG_FILE"
# 0. Ouverture immédiate des ports SIP entrants sur le nouveau MASTER (levée d'isolation)
iptables -D INPUT -p udp -m multiport --dports 5060,5061 -j REJECT --reject-with icmp-port-unreachable 2>/dev/null || true
iptables -D INPUT -p tcp -m multiport --dports 5060,5061 -j REJECT --reject-with tcp-reset 2>/dev/null || true
# 1. Mise à jour de l'état en base de données locale si SQLite disponible
DB_PATH="/var/www/nexus-pbx/storage/database.sqlite"
ASTDB_PATH="/var/lib/asterisk/astdb.sqlite3"
@@ -55,13 +59,23 @@ if [ -n "$VIP_CLEAN" ] && command -v arping >/dev/null 2>&1; then
arping -c 5 -U -I "$IFACE" "$VIP_CLEAN" >> "$LOG_FILE" 2>&1 || true
fi
# 5. Envoi automatique du signal check-sync silencieux aux téléphones enregistrés
# Force Yealink, Fanvil, Snom à réémettre instantanément tous leurs SUBSCRIBE BLF sur ce serveur actif
# 5. Réveil progressif et réabonnement BLF des postes téléphoniques
# Dès que les postes se réenregistrent sur ce Master (via la VIP), un signal silencieux check-sync
# leur est transmis pour forcer la synchronisation immédiate de l'ensemble des touches BLF.
if pidof asterisk >/dev/null 2>&1; then
echo "[$TIMESTAMP] [CLUSTER] Envoi check-sync de réveil aux postes pour réabonnement immédiat des BLF..." >> "$LOG_FILE"
for ep in $(/usr/sbin/asterisk -rx "pjsip show endpoints" 2>/dev/null | grep -o 'Endpoint: [0-9]*' | awk '{print $2}'); do
/usr/sbin/asterisk -rx "pjsip send notify check-sync endpoint $ep" >> "$LOG_FILE" 2>&1 || true
done
echo "[$TIMESTAMP] [CLUSTER] Lancement du réveil BLF progressif en arrière-plan..." >> "$LOG_FILE"
(
for delay in 2 5 12 25; do
sleep "$delay"
if ! pidof asterisk >/dev/null 2>&1; then break; fi
# Cibler uniquement les postes actuellement joignables (Avail)
for ep in $(/usr/sbin/asterisk -rx "pjsip show contacts" 2>/dev/null | grep -E 'Contact:.*Avail' | awk '{print $2}' | cut -d'/' -f1 | sort -u); do
if [ -n "$ep" ]; then
/usr/sbin/asterisk -rx "pjsip send notify check-sync endpoint $ep" >> "$LOG_FILE" 2>&1 || true
fi
done
done
) >/dev/null 2>&1 &
fi
echo "[$TIMESTAMP] [CLUSTER] Prise de relais MASTER terminée avec succès." >> "$LOG_FILE"