Perché nc -uz non può dimostrare che un server OpenVPN è pronto
Una sonda UDP con netcat segnala successo anche quando nulla è in ascolto, quindi non può dimostrare che un server OpenVPN è pronto. Controlla il processo, il log, il listener e un client reale.
Eseguire nc -uz contro un server OpenVPN non misura quasi nulla, e il manuale di OpenBSD lo dice nelle sue avvertenze: le scansioni UDP in quella modalità segnalano successo indipendentemente dal fatto che qualcosa sia in ascolto. Il codice di uscita riflette l’invio locale, non lo stato remoto, quindi un supervisore che si fida di esso mantiene un server morto contrassegnato come sano finché la tabella dei processi sembra plausibile. Sostituirlo inizia dal decidere a quale domanda debba rispondere il controllo, perché processo, listener, autenticazione e raggiungibilità dell’applicazione sono quattro osservazioni diverse. Una sonda che ne nomina una è utile; una sonda che le implica tutte e quattro è un peso.
Cosa può e cosa non può osservare una sonda UDP
nc -uz invia un datagramma ed esce, e lo stato che restituisce descrive l’invio locale. Una porta chiusa può rispondere con ICMP port unreachable, ma il comportamento documentato di questa modalità di scansione non lo trasforma in un errore, e una porta filtrata non produce alcuna risposta. Silenzio e successo significano quindi la stessa cosa per chi chiama.
Ciò rende la sonda un test dello stack locale, non del server. Non stabilisce che l’host sia raggiungibile, che la porta sia associata, che il processo OpenVPN sia in esecuzione o che un client potrebbe autenticarsi. Un test di connessione TCP è più forte perché la stretta di mano dà una risposta netta, ma solo quando la distribuzione ascolta davvero su TCP. Spostare la sonda su TCP sullo stesso numero verifica un listener che potrebbe non esistere, e contro un server solo UDP farà fallire un servizio sano.
Allineare la sonda al trasporto configurato viene prima di fidarsi di uno dei due risultati. Una distribuzione UDP ha bisogno di un segnale diverso, non di un protocollo diverso.
Tre chiamanti, tre domande diverse
La prontezza dipende da chi domanda. Un gestore di servizi che riavvia un processo bloccato deve sapere che l’istanza è partita e ha associato il suo listener. Un bilanciatore di carico deve sapere che un client che arriva ora verrebbe accettato. Un sistema di monitoraggio deve sapere che il percorso da una rete reale porta ancora una sessione verso una risorsa consentita.
Non sono lo stesso controllo, e una sola sonda non può coprire onestamente tutti e tre. Scegli prima chi chiama, poi la prova.
Costruisci la sonda dall’istanza corrente
OpenVPN scrive una riga di avvio quando un’istanza termina l’inizializzazione, e quella riga è una prova utile sull’avvio locale. Leggila dall’avvio corrente e non dalla coda di un file a cui si aggiunge, perché un successo della settimana scorsa si legge esattamente come un successo di un minuto fa. Un server può anche terminare l’inizializzazione prima che un client si sia mai connesso, quindi la riga non dice nulla sull’autenticazione.
Per un controllo di avvio, abbina lo stato del processo alla prova attuale del log e a un listener che corrisponda al trasporto configurato. Il controllo deve fallire quando il processo è in esecuzione ma non ha terminato l’inizializzazione, il che significa che la query del log deve essere limitata a questo avvio e a questa unità.
systemctl is-active openvpn@server
sudo journalctl -u openvpn@server -b --no-pager | grep "Initialization Sequence Completed"
ss -lunp | grep 1194
Tre output, tre affermazioni: l’unità è attiva, questo avvio ha prodotto la riga di inizializzazione e qualcosa occupa la porta UDP. Nessuna di esse dice che un client può connettersi. Tienile separate nella pagina di stato, così un incidente non collassa in un unico punto verde.
Rompila di proposito e osserva la sonda
Una sonda è affidabile solo dopo che l’hai vista fallire. Ferma il server, esegui la sonda e conferma il risultato atteso. Poi riavvialo e conferma che la sonda si riprende senza nessun’altra modifica.
sudo systemctl stop openvpn@server
nc -uz 203.0.113.10 1194; echo "exit=$?"
ss -lunp | grep 1194
sudo systemctl start openvpn@server
ss -lunp | grep 1194
Leggi il blocco riga per riga. Il comando netcat stampa exit=0 mentre nulla è associato, e questo è l’intero problema in una riga. Il primo ss non stampa nulla, il riavvio riesce, e il secondo ss mostra di nuovo il listener. Se la tua sonda passa contro il server fermo, sta misurando lo stack locale e nient’altro.
Anche il fallimento opposto conta. Una sonda che fallisce contro un server sano provoca riavvii che non erano mai necessari, e un ciclo di riavvii è di per sé un’interruzione. Prova entrambe le direzioni prima di collegare la sonda a qualcosa che possa agire su di essa.
Cosa dovrebbe dire la riga di stato
Annota quale confine copre ogni controllo: processo, listener, autenticazione o applicazione. Un controllo raramente ne copre più di uno, e una pagina di stato che li comprime in «up» nasconde la differenza che conta durante un incidente. Per il percorso di rete, usa un client reale con un’identità dedicata, lascia che completi la stretta di mano e un’operazione consentita innocua, poi disconnettilo. Questo esercita il canale di controllo, la politica di autenticazione e il listener in un solo passo.
Tieni quell’identità separata dagli utenti reali e dalle il minimo dei permessi che il controllo richiede. Una sonda di prontezza con accesso ampio è una nuova superficie d’attacco aggiunta per comodità. Ruota le sue credenziali come per qualsiasi altro account, perché una sonda che smette di autenticarsi sembra esattamente un server che ha smesso di accettare client.
Nomina il confine nel testo dell’avviso, così il primo soccorritore sa se guardare l’unità, il socket, il certificato o la rotta. Una sonda che non può dire cosa ha dimostrato verrà creduta per la ragione sbagliata, ed è così che il controllo con netcat è sopravvissuto fin dall’inizio.