{"id":2697,"date":"2025-12-17T09:01:21","date_gmt":"2025-12-17T08:01:21","guid":{"rendered":"http:\/\/clark.tipistrani.it\/?p=2697"},"modified":"2026-01-19T11:05:12","modified_gmt":"2026-01-19T10:05:12","slug":"check-connection-per-heartbeat-riveduto-e-corretto","status":"publish","type":"post","link":"http:\/\/clark.tipistrani.it\/?p=2697","title":{"rendered":"check connection per heartbeat riveduto e corretto"},"content":{"rendered":"<p>Di recente per motivi anche sciocchi se voglio essere sincero sino in fondo ho dovuto\/voluto rifare uno dei due firewall aziendali.<\/p>\n<p>I due firewall sono in HA per condividere l&#8217;IP virtualizzato 192.168.2.241 che \u00e8 il gateway aziendale, l&#8217;HA in formato Master\/slave \u00e8 fornito da heartbeat<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-2724\" src=\"http:\/\/clark.tipistrani.it\/wp-content\/uploads\/2026\/01\/heartbeat.drawio-300x197.png\" alt=\"\" width=\"1200\" height=\"787\" srcset=\"http:\/\/clark.tipistrani.it\/wp-content\/uploads\/2026\/01\/heartbeat.drawio-300x197.png 300w, http:\/\/clark.tipistrani.it\/wp-content\/uploads\/2026\/01\/heartbeat.drawio-1024x671.png 1024w, http:\/\/clark.tipistrani.it\/wp-content\/uploads\/2026\/01\/heartbeat.drawio-768x503.png 768w, http:\/\/clark.tipistrani.it\/wp-content\/uploads\/2026\/01\/heartbeat.drawio-1536x1007.png 1536w, http:\/\/clark.tipistrani.it\/wp-content\/uploads\/2026\/01\/heartbeat.drawio.png 1556w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/p>\n<p>La logica seguita \u00e8 la seguente su ambo i nodi:<\/p>\n<p>a) verifico che heartbeat sia attivo<\/p>\n<p>b) verifico che ci sia connessione ad internet<\/p>\n<p>se a=vero b=vero allora tutto a posto e si continua<\/p>\n<p>se a=a=vero b=falso heartbeat si ferma e l&#8217;IP\u00a0 passa sullo slave che viene eletto a Master quindi non si ha praticamente interruzione di connessione.<\/p>\n<p>a viene controllato con un pgrep b con un plugin di Nagios che si chiama\u00a0<span style=\"font-family: monospace;\">check_http.<\/span><\/p>\n<p>lo script che vene messo in cron ed eseguito ogni 2 minuti \u00e8 il seguente:<\/p>\n<p><span style=\"font-family: monospace;\">#!\/bin\/bash<br \/>\nset -euo pipefail<\/span><\/p>\n<p>PATH=\/usr\/local\/sbin:\/usr\/local\/bin:\/sbin:\/bin:\/usr\/sbin:\/usr\/bin<\/p>\n<p># === Configurazione ===<br \/>\nHOSTS=(&#8220;www.google.com&#8221; &#8220;www.amazon.com&#8221; &#8220;www.corriere.it&#8221;)<br \/>\nCHECK_CMD=&#8221;\/usr\/lib\/nagios\/plugins\/check_http -w 5 -c 10&#8243;<br \/>\nHEARTBEAT_PROC=&#8221;heartbeat&#8221;<br \/>\nHEARTBEAT_INIT=&#8221;\/etc\/init.d\/heartbeat&#8221;<br \/>\nLOGFILE=&#8221;\/var\/log\/connection_monitor.log&#8221;<br \/>\nMAX_LOG_SIZE=102400 \u00a0# 100 KB (rotazione semplice)<\/p>\n<p># === Funzioni ===<\/p>\n<p>log() {<br \/>\nlocal msg=&#8221;[$(date &#8216;+%Y-%m-%d %H:%M:%S&#8217;)] $*&#8221;<br \/>\necho &#8220;$msg&#8221; | tee -a &#8220;$LOGFILE&#8221; &gt; \/dev\/null<br \/>\n}<\/p>\n<p>rotate_log() {<br \/>\nif [ -f &#8220;$LOGFILE&#8221; ]; then<br \/>\nlocal size<br \/>\nsize=$(stat -c%s &#8220;$LOGFILE&#8221; 2&gt;\/dev\/null || echo 0)<br \/>\nif [ &#8220;$size&#8221; -ge &#8220;$MAX_LOG_SIZE&#8221; ]; then<br \/>\nmv &#8220;$LOGFILE&#8221; &#8220;${LOGFILE}.1&#8221;<br \/>\nlog &#8220;Log ruotato: ${LOGFILE}.1&#8221;<br \/>\nfi<br \/>\nfi<br \/>\n}<\/p>\n<p>check_heartbeat_alive() {<br \/>\nif pgrep -x &#8220;$HEARTBEAT_PROC&#8221; &gt; \/dev\/null 2&gt;&amp;1; then<br \/>\nlog &#8220;Heartbeat \u00e8 attivo&#8221;<br \/>\nreturn 0<br \/>\nelse<br \/>\nlog &#8220;Heartbeat non \u00e8 attivo&#8221;<br \/>\nreturn 1<br \/>\nfi<br \/>\n}<\/p>\n<p>check_network_alive () {<span style=\"color: #000000;\">\u00a0<\/span><br \/>\nfor host in &#8220;${HOSTS[@]}&#8221;; do<br \/>\nif $CHECK_CMD -H &#8220;$host&#8221; &gt; \/dev\/null 2&gt;&amp;1; then<br \/>\nlog &#8220;Rete OK ($host raggiungibile)&#8221;<br \/>\nreturn 0<br \/>\nfi<br \/>\ndone<br \/>\nlog &#8220;Rete NON raggiungibile&#8221;<br \/>\nreturn 1<br \/>\n}<\/p>\n<p>start_heartbeat() {<br \/>\nlog &#8220;Avvio heartbeat&#8230;&#8221;<br \/>\nif [ -x &#8220;$HEARTBEAT_INIT&#8221; ]; then<br \/>\n&#8220;$HEARTBEAT_INIT&#8221; start &amp;&amp; log &#8220;Heartbeat avviato&#8221; || log &#8220;Errore: impossibile avviare heartbeat&#8221;<br \/>\nelse<br \/>\nservice heartbeat start &amp;&amp; log &#8220;Heartbeat avviato (via service)&#8221; || log &#8220;Errore: comando service non disponibile&#8221;<br \/>\nfi<br \/>\n}<\/p>\n<p>stop_heartbeat() {<br \/>\nlog &#8220;Arresto heartbeat&#8230;&#8221;<br \/>\nif [ -x &#8220;$HEARTBEAT_INIT&#8221; ]; then<br \/>\n&#8220;$HEARTBEAT_INIT&#8221; stop &amp;&amp; log &#8220;Heartbeat fermato&#8221; || log &#8220;Errore: impossibile fermare heartbeat&#8221;<br \/>\nelse<br \/>\nservice heartbeat stop &amp;&amp; log &#8220;Heartbeat fermato (via service)&#8221; || log &#8220;Errore: comando service non disponibile&#8221;<br \/>\nfi<br \/>\n}<\/p>\n<p># === Esecuzione ===<span style=\"color: #000000;\">\u00a0<\/span><br \/>\nrotate_log<\/p>\n<p>hbalive=0<br \/>\nnetalive=0<\/p>\n<p>if check_heartbeat_alive; then hbalive=1; fi<br \/>\nif check_network_alive; then netalive=1; fi<\/p>\n<p>log &#8220;Stato corrente \u2192 Heartbeat: $hbalive | Rete: $netalive&#8221;<\/p>\n<p># === Logica decisionale ===<br \/>\nif [[ $hbalive -eq 1 &amp;&amp; $netalive -eq 0 ]]; then<br \/>\nlog &#8220;Condizione: Heartbeat attivo ma rete gi\u00f9 \u2192 fermo heartbeat&#8221;<br \/>\nstop_heartbeat<\/p>\n<p>elif [[ $hbalive -eq 0 &amp;&amp; $netalive -eq 1 ]]; then<br \/>\nlog &#8220;Condizione: Heartbeat fermo ma rete su \u2192 avvio heartbeat&#8221;<br \/>\nstart_heartbeat<\/p>\n<p>else<br \/>\nlog &#8220;Situazione coerente \u2192 nessuna azione necessaria&#8221;<br \/>\nfi<\/p>\n<p>exit 0<\/p>\n<p>Questa versione \u00e8 un test realizzato con AI, in altre parole ho preso lo script che avevo fatto (credo) 20 anni fa e l&#8217;ho dato in pasto a Grok dicendogli questo funziona bene, ottimizzalo.<\/p>\n<p>la versione da cui sono partito \u00e8 questa:<\/p>\n<p>#!\/bin\/bash -x<br \/>\nPATH=\/usr\/local\/sbin:\/usr\/local\/bin:\/sbin:\/bin:\/usr\/sbin:\/usr\/bin<br \/>\n### some variables<br \/>\nF_HOST=www.google.com<br \/>\nS_HOST=www.amazon.com<br \/>\nT_HOST=www.corriere.it<br \/>\nCHECK=&#8221;\/usr\/lib\/nagios\/plugins\/check_http -w 5 -c 10&#8243;<br \/>\n#HBPIDFILE=&#8221;\/var\/run\/heartbeat.pid&#8221;<br \/>\n#HBPIDFILE=`ps x | grep heartbeat | grep -v grep`<br \/>\n#HBPIDFILE=pgrep heartbeat<br \/>\nHBPIDFILE=`ps -C heartbeat -O pid=`<br \/>\nHEART=&#8217;heartbeat&#8217;<\/p>\n<p>hbalive=0<br \/>\nnetalive=0<\/p>\n<p>if [ -e $HBPIDFILE ]<br \/>\nthen<br \/>\nrunpid=`cat $HBPIDFILE`<br \/>\n# \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0runpid= pgrep heartbeat<br \/>\nfi<br \/>\nif ps ax | grep -v grep | grep $HEART &gt; \/dev\/null<\/p>\n<p>then<br \/>\necho &#8220;heartbeat gira&#8221;<\/p>\n<p>hbalive=1<br \/>\nfi<\/p>\n<p>$CHECK $F_HOST || $CHECK $S_HOST || $CHECK $T_HOST<br \/>\nif [ $? == 0 ]<br \/>\nthen<br \/>\nnetalive=1<br \/>\nfi<br \/>\necho $hbalive $netalive<\/p>\n<p>###se ( hbalive=1 \u00a0&amp;&amp; netalive=0) -&gt; heartbeat stop<br \/>\n###se ( hbalive=0 &amp;&amp; netalive=1) -&gt; heartbeat start<br \/>\n### se ambedue sono \u00a0a 0 (rete giu&#8217; heatbeat giu&#8217;) o a 1 (rete su heartbeat su) non bisogna fare nulla<br \/>\nif [ $hbalive -eq \u00a0$netalive ]<br \/>\nthen<br \/>\necho &#8220;tutto ok&#8221;<br \/>\nexit 0<br \/>\nfi<br \/>\n### se heartbeat e&#8217; giu a seguito di normale down di rete allora deve ripartire se la rete e&#8217; attiva<br \/>\nif [ $hbalive -lt \u00a0$netalive ]<br \/>\nthen<br \/>\n\/etc\/init.d\/heartbeat start<br \/>\nfi<br \/>\n### se heartbeat e&#8217; su e la rete e&#8217; giu deve fermarsi per fare partire lo slave<br \/>\nif [ $hbalive -gt \u00a0$netalive ]<br \/>\nthen<br \/>\n\/etc\/init.d\/heartbeat stop<br \/>\nexit 0<br \/>\nfi<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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&#8217;IP virtualizzato 192.168.2.241 che \u00e8 il gateway aziendale, l&#8217;HA in formato Master\/slave \u00e8 fornito da heartbeat La logica seguita \u00e8 la seguente su ambo i nodi: [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[109,8,14,7,6],"tags":[123,104,35,311,25],"class_list":["post-2697","post","type-post","status-publish","format-standard","hentry","category-firewall","category-linux","category-networking","category-sistemi-operativi","category-work","tag-bash","tag-bash-script","tag-heartbeat","tag-nagios","tag-script-2"],"_links":{"self":[{"href":"http:\/\/clark.tipistrani.it\/index.php?rest_route=\/wp\/v2\/posts\/2697","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/clark.tipistrani.it\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/clark.tipistrani.it\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/clark.tipistrani.it\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/clark.tipistrani.it\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2697"}],"version-history":[{"count":8,"href":"http:\/\/clark.tipistrani.it\/index.php?rest_route=\/wp\/v2\/posts\/2697\/revisions"}],"predecessor-version":[{"id":2726,"href":"http:\/\/clark.tipistrani.it\/index.php?rest_route=\/wp\/v2\/posts\/2697\/revisions\/2726"}],"wp:attachment":[{"href":"http:\/\/clark.tipistrani.it\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2697"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/clark.tipistrani.it\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2697"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/clark.tipistrani.it\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2697"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}