I ping all'indirizzo del tunnel del server riescono, la tabella di routing del client sembra corretta, e la LAN dietro quel client resta irraggiungibile. La tabella di routing del client sembra corretta, il server ha una rotta verso il tunnel, e i pacchetti svaniscono comunque. È il sintomo classico di un tunnel layer-3 che non sa che uno dei suoi client è anche un gateway.

Un'interfaccia tun non ha next hop per client. Il kernel vede una sola interfaccia con molti peer, quindi la decisione su quale client debba ricevere un pacchetto per una LAN remota deve essere presa dentro il processo OpenVPN. Quella decisione si configura con iroute, e senza di essa il pacchetto non ha dove andare.

Il server instrada per client, non per interfaccia

Quando il server deve inviare un pacchetto all'indirizzo del tunnel di un client, la risposta è inequivocabile: l'indirizzo appartiene alla sessione di quel client. Quando la destinazione è un'intera sottorete dietro quel client, l'indirizzo non appartiene a nessuno che il server conosca, e la rotta del kernel verso il tunnel dice solo "da questa interfaccia", senza dire quale peer.

OpenVPN risolve questo con una tabella di routing interna che associa un prefisso di destinazione a un client specifico. Quella tabella è costruita dalle voci iroute, per questo una rotta normale sull'host del server non basta. La rotta del kernel porta il pacchetto all'interfaccia del tunnel; la mappatura interna decide quale sessione lo riceve. È anche per questo che la riparazione non compare mai nell'output delle rotte del kernel.

Se la mappatura manca, il pacchetto arriva al server, corrisponde alla rotta del tunnel e viene scartato perché nessun client rivendica la destinazione. Nulla registra un errore pulito, per questo il guasto sembra un buco nero silenzioso invece di un loop di routing.

Scrivere la voce iroute che nomina il client

iroute vive in un file di configurazione specifico del client, non nella configurazione principale del server. Puntate il server a una directory con l'opzione client-config-dir, poi create un file il cui nome è il nome comune del certificato del client e inserite il prefisso.

Per una filiale la cui LAN è 10.20.0.0/24 e il cui nome comune del certificato è branch-router, il file in quel percorso contiene una riga come iroute 10.20.0.0 255.255.255.0. La configurazione principale necessita solo dell'opzione della directory; il prefisso vive con il client.

Il nome comune è la parte fragile. Un certificato emesso con un altro subject, o un deployment che autentica gli utenti per nome utente mentre il file è nominato dal certificato, produce un file che non viene mai letto. Verificate il nome che il server riporta realmente per la sessione, e considerate l'opzione che fa fallire un client non corrispondente invece di collegarlo silenziosamente senza le sue rotte. Rinominare il file per farlo corrispondere al certificato è una correzione di cinque minuti che evita una serata molto lunga.

Un client può possedere più prefissi. Aggiungete una riga iroute per rete e tenete l'elenco accanto al resto delle impostazioni di quel client perché la mappatura resti verificabile.

Costruire il percorso di ritorno in entrambe le direzioni

Portare i pacchetti alla LAN remota è metà del lavoro. Il client deve anche inviare il traffico di quella LAN nel tunnel, cosa che di solito si fa spingendo una rotta al client: una riga come push "route 10.8.0.0 255.255.255.0" dice a ogni client come raggiungere la rete lato server. Per la filiale, la rotta equivalente punta al tunnel per tutto ciò che deve raggiungere lato server.

La direzione di ritorno ha bisogno di un proprietario sul lato remoto. Su quel lato, qualcuno deve conoscere la via del ritorno: una rotta statica sul router della LAN che punta il pool VPN al server, o la traduzione degli indirizzi sul server prima che il traffico entri nella LAN. La rotta statica mantiene gli indirizzi originali visibili nei log e nelle regole di accesso ma richiede la collaborazione del proprietario della LAN; la traduzione è autosufficiente ma nasconde chi si è realmente connesso.

L'inoltro deve essere abilitato sull'host del server. Senza di esso il kernel accetta il pacchetto dal tunnel e rifiuta di passarlo all'interfaccia LAN, cosa che dal punto di vista del client sembra identica a una iroute mancante.

Verificare la raggiungibilità con le sonde giuste

Testate a strati invece di fare ping all'estremità remota e tirare a indovinare. Dal server, verificate che la mappatura interna del prefisso esista e che la rotta del kernel punti al tunnel. Dal client, confermate che la rotta spinta sia installata e che il suo percorso predefinito per l'indirizzo LAN sia il tunnel.

Poi osservate i pacchetti. Una cattura sull'interfaccia del tunnel mostra se il server sta trasmettendo verso il client, e una cattura sull'interfaccia LAN mostra se sta inoltrando. Se la prima mostra pacchetti e la seconda nulla, il problema è l'inoltro o un filtro; se nessuna mostra nulla, la ricerca è fallita prima.

Due server uniti da un tunnel ripetono la stessa regola su entrambi i lati: ognuno ha bisogno di una iroute per il pool dell'altro, e ognuno ha bisogno della rotta e dell'inoltro che rendono il percorso simmetrico. Routing e policy sono questioni separate qui. Il routing decide dove un pacchetto può andare, mentre una regola FORWARD decide se può, quindi un client con due righe iroute raggiunge entrambi i prefissi a meno che un filtro dica il contrario.

Articoli correlati