Conta i processi OpenVPN prima di toccare un profilo. Un Pi che accetta utenti in roaming e compone anche un servizio upstream esegue due daemon, e ciascuno legge un file di configurazione scelto dal nome dell'istanza che hai digitato. I template del pacchetto assegnano poi a ogni daemon una propria directory di lavoro, un proprio file di stato di runtime e un proprio dispositivo di tunnel. Se sbagli questa separazione, passerai una serata a modificare un'impostazione corretta dentro un file che il processo in esecuzione non apre mai.

Ogni nome di istanza sceglie il proprio file

Nei file di unità forniti con OpenVPN 2.6, gli argomenti di avvio contengono un segnaposto di istanza che viene riempito con il testo dopo il segno @. Il template del server parte dalla directory di configurazione del server e risolve il proprio argomento su %i.conf che si trova lì, mentre il template del client fa lo stesso dalla directory del client. Quindi [email protected] legge admits.conf nella directory del server e [email protected] legge uplink.conf nella directory del client, e nessuno dei due nomi ha alcun significato nell'altra directory.

Verifica la corrispondenza sulla macchina invece di dare per scontato che il pacchetto abbia mantenuto i valori predefiniti upstream. Un drop-in della distribuzione può sostituire del tutto la directory di lavoro o l'argomento di configurazione.

systemctl cat [email protected]
systemctl cat [email protected]

Leggi la riga WorkingDirectory e l'argomento di configurazione in quell'output, perché l'unità abilitata è l'unica cosa che decide quale file viene caricato. Un drop-in che aggiunge --config a ExecStart vince sul template anche quando il percorso del template sembra giusto. Chiedi i percorsi dei frammenti e dei drop-in quando vuoi sapere se c'è un override locale. Se entrambi i ruoli finiscono su un solo file, hai un unico processo che cerca di essere server e client insieme, e l'opzione successiva in quel file vince in silenzio.

Trasporto locale e payload inoltrato incontrano hook diversi

La connessione cifrata del server verso ogni utente in roaming è generata sul Pi stesso, quindi le sue risposte esterne escono dall'hook di output locale. Anche la connessione del client verso il peer upstream è output generato localmente, anche se raggiunge una rete remota. Il payload inoltrato è la terza categoria, e il kernel lo abbina solo dopo aver già scelto un dispositivo di uscita per il pacchetto.

FlowHook that sees itWhat to inspect
Roaming user handshakes to the serverLocal input and local outputListener socket, bind address, rule admitting the UDP port
User payload leaving through the upstream tunnelForwardIPv4 forwarding switch, selected route, permission rule, any translation
Pi's own connection to the upstream peerLocal outputUnderlay route to the provider endpoint, not the tunnel route

Una regola che abbina un'interfaccia di uscita dentro una catena forward può consentire o scartare un pacchetto che il routing ha già assegnato a quell'interfaccia, ma non sceglie mai l'interfaccia. Quando un host termina un tunnel e ne origina un altro, la politica che manda il payload degli utenti nel tunnel upstream e la politica che protegge le risposte cifrate del Pi sono decisioni separate. Finiscono per caso sulla stessa NIC fisica, ed è per questo che vengono confuse.

Questa distinzione spiega un mezzo guasto comune. Gli utenti si connettono, l'handshake si completa e il loro traffico esce comunque dalla parte sbagliata, perché l'handshake era locale e il payload era forward e solo uno dei due è stato mai provato.

Una rotta importata può inghiottire le risposte ai tuoi utenti

L'impostazione di sicurezza del profilo client decide cosa l'upstream può spingere nella tabella di routing del Pi, e un redirect ampio è l'opzione che trasforma un host a doppio ruolo funzionante in uno rotto. Se la rotta spinta copre gli indirizzi pubblici degli utenti in roaming, le risposte che il server genera verso di loro possono seguire la nuova rotta dentro il tunnel upstream invece di uscire dall'underlay. Spesso si verifica che il tunnel verso il provider funzioni ancora e ci si ferma lì, perché quel traffico è il trasporto del tunnel stesso e continua a fluire mentre tutto il resto si comporta male.

Una politica basata sull'origine o sul mark è il modo per tenere separati i due flussi. L'opzione mark Linux di OpenVPN contrassegna i pacchetti cifrati del daemon con un mark del firewall, che una regola di routing può poi inviare a una tabella dedicata. Gli indirizzi di origine funzionano altrettanto bene quando le risposte esterne del server escono sempre da un solo indirizzo underlay. Entrambi gli approcci richiedono rotte valide nella tabella selezionata e un'eccezione per l'endpoint del provider, altrimenti il tunnel stesso non sale più.

Chiedi al kernel quale percorso seguirebbe davvero una risposta prima di scrivere qualsiasi regola. Gli indirizzi qui sotto sono segnaposto per un indirizzo underlay del Pi e per l'indirizzo pubblico di un utente in roaming.

ip rule show
ip route get 198.51.100.7 from 192.0.2.10

Verifica la separazione, poi ferma un ruolo alla volta

Prova tre flussi separatamente, perché un handshake che funziona non dimostra nulla sugli altri due. Accetta una nuova connessione in ingresso, manda un'applicazione consentita attraverso l'uscita upstream e conferma che entrambi i processi raggiungano ancora i propri peer.

Poi ferma il ruolo client e osserva cosa mantiene il ruolo server. È il modo più economico per trovare una regola di rotta o di mark pensata per un'istanza e applicata a entrambe.

systemctl stop [email protected]
systemctl status [email protected] --no-pager
ss -lunp | grep openvpn
journalctl -u [email protected] -n 20 --no-pager

Quello che vuoi vedere è il listener ancora in ascolto, il dispositivo di tunnel ancora presente e il log privo di nuovi errori mentre il ruolo client è fermo. Se fermare il client taglia anche le risposte del server agli utenti esistenti, i due ruoli condividono qualcosa che avrebbe dovuto essere limitato a uno solo di essi. Annota quale istanza, quale file di configurazione e quale proprietario del flusso ha toccato ogni modifica, perché la prossima persona che eseguirà il debug di questo host altrimenti ripeterà la stessa scoperta da zero.

Articoli correlati