Clark's Home page

Tecnicismi vari di un Sysadmin Linux ma anche qualcosa della sua vita

check connection per heartbeat riveduto e corretto —

Di recente per motivi anche sciocchi se voglio essere sincero sino in fondo ho dovuto/voluto rifare uno dei due firewall aziendali.

I due firewall sono in HA per condividere l’IP virtualizzato 192.168.2.241 che è il gateway aziendale, l’HA in formato Master/slave è fornito da heartbeat

La logica seguita è la seguente su ambo i nodi:

a) verifico che heartbeat sia attivo

b) verifico che ci sia connessione ad internet

se a=vero b=vero allora tutto a posto e si continua

se a=a=vero b=falso heartbeat si ferma e l’IP  passa sullo slave che viene eletto a Master quindi non si ha praticamente interruzione di connessione.

a viene controllato con un pgrep b con un plugin di Nagios che si chiama check_http.

lo script che vene messo in cron ed eseguito ogni 2 minuti è il seguente:

#!/bin/bash
set -euo pipefail

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# === Configurazione ===
HOSTS=(“www.google.com” “www.amazon.com” “www.corriere.it”)
CHECK_CMD=”/usr/lib/nagios/plugins/check_http -w 5 -c 10″
HEARTBEAT_PROC=”heartbeat”
HEARTBEAT_INIT=”/etc/init.d/heartbeat”
LOGFILE=”/var/log/connection_monitor.log”
MAX_LOG_SIZE=102400  # 100 KB (rotazione semplice)

# === Funzioni ===

log() {
local msg=”[$(date ‘+%Y-%m-%d %H:%M:%S’)] $*”
echo “$msg” | tee -a “$LOGFILE” > /dev/null
}

rotate_log() {
if [ -f “$LOGFILE” ]; then
local size
size=$(stat -c%s “$LOGFILE” 2>/dev/null || echo 0)
if [ “$size” -ge “$MAX_LOG_SIZE” ]; then
mv “$LOGFILE” “${LOGFILE}.1”
log “Log ruotato: ${LOGFILE}.1”
fi
fi
}

check_heartbeat_alive() {
if pgrep -x “$HEARTBEAT_PROC” > /dev/null 2>&1; then
log “Heartbeat è attivo”
return 0
else
log “Heartbeat non è attivo”
return 1
fi
}

check_network_alive() {
for host in “${HOSTS[@]}”; do
if $CHECK_CMD -H “$host” > /dev/null 2>&1; then
log “Rete OK ($host raggiungibile)”
return 0
fi
done
log “Rete NON raggiungibile”
return 1
}

start_heartbeat() {
log “Avvio heartbeat…”
if [ -x “$HEARTBEAT_INIT” ]; then
“$HEARTBEAT_INIT” start && log “Heartbeat avviato” || log “Errore: impossibile avviare heartbeat”
else
service heartbeat start && log “Heartbeat avviato (via service)” || log “Errore: comando service non disponibile”
fi
}

stop_heartbeat() {
log “Arresto heartbeat…”
if [ -x “$HEARTBEAT_INIT” ]; then
“$HEARTBEAT_INIT” stop && log “Heartbeat fermato” || log “Errore: impossibile fermare heartbeat”
else
service heartbeat stop && log “Heartbeat fermato (via service)” || log “Errore: comando service non disponibile”
fi
}

# === Esecuzione ===
rotate_log

hbalive=0
netalive=0

if check_heartbeat_alive; then hbalive=1; fi
if check_network_alive; then netalive=1; fi

log “Stato corrente → Heartbeat: $hbalive | Rete: $netalive”

# === Logica decisionale ===
if [[ $hbalive -eq 1 && $netalive -eq 0 ]]; then
log “Condizione: Heartbeat attivo ma rete giù → fermo heartbeat”
stop_heartbeat

elif [[ $hbalive -eq 0 && $netalive -eq 1 ]]; then
log “Condizione: Heartbeat fermo ma rete su → avvio heartbeat”
start_heartbeat

else
log “Situazione coerente → nessuna azione necessaria”
fi

exit 0

Questa versione è un test realizzato con AI, in altre parole ho preso lo script che avevo fatto (credo) 20 anni fa e l’ho dato in pasto a Grok dicendogli questo funziona bene, ottimizzalo.

la versione da cui sono partito è questa:

#!/bin/bash -x
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
### some variables
F_HOST=www.google.com
S_HOST=www.amazon.com
T_HOST=www.corriere.it
CHECK=”/usr/lib/nagios/plugins/check_http -w 5 -c 10″
#HBPIDFILE=”/var/run/heartbeat.pid”
#HBPIDFILE=`ps x | grep heartbeat | grep -v grep`
#HBPIDFILE=pgrep heartbeat
HBPIDFILE=`ps -C heartbeat -O pid=`
HEART=’heartbeat’

hbalive=0
netalive=0

if [ -e $HBPIDFILE ]
then
runpid=`cat $HBPIDFILE`
#       runpid= pgrep heartbeat
fi
if ps ax | grep -v grep | grep $HEART > /dev/null

then
echo “heartbeat gira”

hbalive=1
fi

$CHECK $F_HOST || $CHECK $S_HOST || $CHECK $T_HOST
if [ $? == 0 ]
then
netalive=1
fi
echo $hbalive $netalive

###se ( hbalive=1  && netalive=0) -> heartbeat stop
###se ( hbalive=0 && netalive=1) -> heartbeat start
### se ambedue sono  a 0 (rete giu’ heatbeat giu’) o a 1 (rete su heartbeat su) non bisogna fare nulla
if [ $hbalive -eq  $netalive ]
then
echo “tutto ok”
exit 0
fi
### se heartbeat e’ giu a seguito di normale down di rete allora deve ripartire se la rete e’ attiva
if [ $hbalive -lt  $netalive ]
then
/etc/init.d/heartbeat start
fi
### se heartbeat e’ su e la rete e’ giu deve fermarsi per fare partire lo slave
if [ $hbalive -gt  $netalive ]
then
/etc/init.d/heartbeat stop
exit 0
fi


Categorised as: firewall | Linux | Networking | Sistemi operativi | Work

Comments are disabled on this post


Comments are closed.


Hide picture