Un profilo vpnc si riconnette in modo pulito dopo un roaming; tre di loro finiscono per rompersi a turno socket, rotte e stato del resolver. Lo script di riconnessione fornito è scritto per un solo tunnel, quindi riavvia ogni profilo ogni volta che uno qualsiasi è giù. Sistemarlo richiede tre cose: porte locali separate, una sonda che verifichi un servizio reale per profilo e una catena ordinata che non esegua mai due connessioni insieme.

Assegna a ogni profilo la sua porta locale

Un profilo vpnc lasciato sulla porta locale predefinita compete con il profilo già in esecuzione. La seconda connessione fallisce mentre la prima tiene la porta, e la riga di log sembra un problema di gateway più che un conflitto locale. Metti invece una riga per ogni file di profilo:

Local Port 0

Lo zero lascia che il kernel scelga una porta effimera, così due profili possono essere stabiliti insieme. Nomina ogni file secondo il gateway e il gruppo che serve, mantienilo leggibile solo da root e connettiti sempre con il profilo corrispondente invece che con un default condiviso. Un file predefinito condiviso è il modo in cui uno script riconnette il tunnel sbagliato dopo che qualcuno ha rinominato un profilo.

I file di profilo contengono credenziali, quindi i permessi fanno parte della progettazione e non della pulizia. Un file leggibile da tutti sotto /etc/vpnc consegna il segreto del gruppo a ogni utente locale. Mantieni il modo a 0600 con root come proprietario e lascia che gli script leggano il file come root invece di copiare segreti negli argomenti. È anche per questo che uno script di sonda non dovrebbe mai riversare il contenuto del file in un log.

Sonda un servizio per profilo, non l’indirizzo del tunnel

Una richiesta echo all’indirizzo del tunnel stesso dimostra soprattutto che l’interfaccia esiste. Non dice nulla sulla capacità dell’host dietro di essa di raggiungere ancora l’applicazione che giustifica il tunnel. L’interfaccia può essere attiva mentre la rotta oltre di essa è già sparita.

Sonda un servizio per profilo con un breve timeout TCP e riconnetti solo il profilo la cui sonda è fallita. Due secondi separano un percorso morto da uno lento, e una sonda TCP non dipende dal fatto che ICMP sia consentito da qualche parte lungo il percorso. Cambia solo il bersaglio e il nome della configurazione tra i profili:

#!/bin/bash
set -eu
if ! nc -z -w 2 10.63.7.20 8443; then
  /usr/sbin/vpnc-connect ops.conf
fi

Salva tutto questo come /usr/local/bin/ensure-vpn-ops.sh, rendilo eseguibile e ripetilo per ogni profilo cambiando solo il bersaglio della sonda e il nome della configurazione. Una sonda che risponde a una domanda di protocollo sopravvive ai gateway che scartano l’echo ma continuano a inoltrare i servizi che interessano agli utenti.

Concatena le sonde in modo che non competano mai

Lo script di riconnessione fornito può chiamare le tue sonde in sequenza, e la sequenza è tutto il punto. Due chiamate a vpnc-connect eseguite insieme riscrivono la tabella di routing in un ordine che nessuno controlla, ed è così che un profilo sano perde la sua rotta.

Mantieni le chiamate in primo piano, aggiungi una breve pausa di assestamento per l’interfaccia sottostante e pianifica la catena dalla tabella cron di root, dato che solo root può riscrivere le rotte del tunnel:

#!/bin/bash
sleep 20
/usr/local/bin/ensure-vpn-ops.sh
/usr/local/bin/ensure-vpn-lab.sh

Mantieni l’ordine identico tra lo script di avvio e la voce cron, dato che una catena che all’avvio gira in un ordine diverso è di fatto un altro programma. Quando un profilo dipende dalle rotte di un altro, metti la dipendenza per prima e lascia che la sonda successiva fallisca senza danni mentre il tunnel precedente sta ancora salendo.

Osserva il log, poi rompine uno di proposito

Registra una riga per esecuzione con il profilo, il bersaglio della sonda, il risultato e l’azione intrapresa. Senza di ciò, un tunnel che oscilla ogni minuto sembra esattamente uno che non è mai caduto, e un bug della sonda è indistinguibile da un’interruzione del gateway. Il log dimostra anche che la catena ha toccato solo il profilo che è fallito. Scrivilo dove sopravvive a un riavvio, altrimenti le prove se ne vanno con il processo.

Poi rompi deliberatamente un tunnel e osserva cosa succede. Ferma un singolo profilo e conferma quali processi e rotte sono ancora presenti:

pgrep -a vpnc
ip -4 route show | grep -E '10[.]63|10[.]90'
tail -n 5 /var/log/ensure-vpn.log

Solo il profilo fermato dovrebbe essere riconnesso, e le altre sessioni dovrebbero conservare sia i processi sia le rotte. Se due profili si riavviano, la tua catena sta girando in parallelo da qualche parte che non ti aspettavi.

Cosa non deve fare il watchdog

Un watchdog che riavvia tutto ogni volta che qualcosa fallisce sembra sano durante i test e provoca un’interruzione in una finestra di manutenzione. Riavvia per profilo, mai globalmente.

Preferisci un client mantenuto quando il gateway ne offre uno per lo stesso protocollo, e non codificare mai una password nello script né passarla su una riga di comando, perché il file di profilo custodisce già il segreto. Se un’attività deve girare come utente normale una volta che il tunnel è attivo, riduci i privilegi dall’interno dello script invece di far girare l’intera catena con quell’account. Infine, rileggi le rotte dopo una riconnessione, perché un profilo può tornare con un indirizzo assegnato diverso e lasciare una rotta obsoleta che nessuna sonda rivolta all’indirizzo del tunnel noterà mai.

Articoli correlati