Un utente remoto si connette all’hub, raggiunge il file server sulla LAN dell’hub e tutto sembra sano. Poi apre una condivisione su 10.20.0.50 nella sede centrale, che l’hub raggiunge tramite un tunnel separato tra sedi, e la connessione va in timeout. Entrambi i tunnel sono attivi ed entrambi i contatori salgono, quindi nessun tunnel è rotto. Attraversare l’hub sono tre decisioni di routing su tre dispositivi, e un tunnel trasporta solo i prefissi per cui è stato costruito. Questo è l’ordine che controllo, e il comando che mostra se ogni passo è vero.

Il transito richiede tre ricerche, non un solo tunnel

Ogni dispositivo fa la propria corrispondenza di prefisso più lungo e la dimentica. Il portatile deve inviare 10.20.0.50 nel tunnel invece che al proprio router locale. L’hub deve prendere un pacchetto arrivato sull’interfaccia di accesso remoto e consegnarlo all’interfaccia tra sedi. La sede centrale deve inviare una risposta per l’indirizzo dell’utente indietro attraverso il tunnel. Se una delle tre fallisce, il browser mostra la stessa cosa: silenzio.

Per questo testare ogni tunnel da solo dimostra così poco. Un ping all’indirizzo LAN dell’hub esercita la prima decisione, e un ping all’hub dalla sede centrale esercita la terza. Il pacchetto che fallisce ha il pool di utenti come origine e il secondo sito come destinazione, quindi annota prima quei prefissi. Qui il pool è 10.80.0.0/24, la LAN dell’hub è 10.10.0.0/24 e la sede centrale è 10.20.0.0/24.

Spingi il prefisso remoto verso il client remoto

Su un OpenVPN server di accesso remoto il client apprende le rotte al momento della connessione. Senza un push, un client con tunnel diviso invia 10.20.0.50 al proprio gateway e il pacchetto non entra mai nel tunnel.

push "route 10.20.0.0 255.255.255.0"

Una rotta spinta si applica quando il client si connette, quindi un utente che resta online non vede nulla finché non si riconnette. Verifica sul client: ip route get 10.20.0.50 su Linux, route print su Windows. L’output dovrebbe nominare l’interfaccia del tunnel.

Il push non aiuta l’hub. È un messaggio al client, non una rotta sul server e non un permesso di inoltro, quindi un hub con la riga push perfetta scarta comunque il flusso un hop dopo. È la ragione abituale per cui si conclude che il push è fallito.

Dai all’hub una vera rotta di uscita

L’hub ha bisogno del proprio next hop per il prefisso della sede centrale. Su un tunnel instradato è una rotta ordinaria attraverso l’interfaccia tra sedi, e un solo comando mostra sia la rotta scelta sia la sorgente scelta:

ip route get 10.20.0.50 from 10.80.0.25
sudo ip route add 10.20.0.0/24 via 172.30.0.2 dev s2s0

Quando il tratto tra sedi è esso stesso OpenVPN, la rotta può vivere in quella configurazione con l’indirizzo di tunnel del peer come gateway: route 10.20.0.0 255.255.255.0 172.30.0.2. Il gateway non è facoltativo. Se lo ometti, il next hop ricade su un valore predefinito dell’implementazione, che differisce tra un client con un solo peer e un hub con più peer.

L’IPsec basato su policy è diverso: il kernel dell’hub invia il pacchetto al suo gateway LAN normale e la policy lo intercetta in uscita, quindi una rotta di tunnel o non fa nulla o devia il traffico oltre la policy. Guarda la sorgente nel comando sopra, perché 10.10.0.1 al posto dell’indirizzo del pool significa che il kernel ha scelto un indirizzo che il lato remoto rifiuterà. iroute non è la risposta neppure lui; dice al server quale client possiede una sottorete dietro il proprio tunnel, non dove inviare il traffico per un terzo sito.

Estendi il lato remoto al pool di utenti

La sede centrale copre già la LAN dell’hub, 10.10.0.0/24. Il pool di utenti è un secondo prefisso e deve stare anche nei selettori, altrimenti nessuna policy copre una risposta indirizzata a 10.80.0.25. Ogni peer nomina la stessa coppia di insiemi di prefissi dal proprio lato:

# strongSwan swanctl.conf, on the hub
local_ts  = 10.10.0.0/24, 10.80.0.0/24
remote_ts = 10.20.0.0/24
# on the headquarters peer
local_ts  = 10.20.0.0/24
remote_ts = 10.10.0.0/24, 10.80.0.0/24

Il local_ts di un dispositivo è il remote_ts dell’altro. Copia il blocco dell’hub nella sede centrale e la coppia è invertita, quindi la child SA non sale mai.

La sintassi più vecchia di ipsec.conf usa un leftsubnet separato da virgole. L’associazione di sicurezza in corso conserva i selettori negoziati, quindi ristabilisci il tunnel dopo la modifica. Un selettore cambiato alle 10:00 e testato contro una SA salita alle 09:40 fallisce ancora, mentre il file di configurazione sembra corretto per tutto il tempo.

Poi controlla l’ultimo hop. ip route get 10.80.0.25 sull’endpoint remoto dovrebbe puntare nel tunnel. Se il servizio usa un router LAN come gateway predefinito, anche quel router ha bisogno della rotta di ritorno, altrimenti la risposta muore lì. Eseguire tcpdump -ni eth1 host 10.80.0.25 su quel segmento mostra se la risposta ha lasciato l’endpoint.

Consenti il flusso sull’hub

L’inoltro deve essere abilitato e il percorso consentito. Circoscrivi le regole ai due prefissi invece di accettare tutto tra le interfacce.

sysctl -w net.ipv4.ip_forward=1
iptables -I FORWARD -i tun0 -o s2s0 -s 10.80.0.0/24 -d 10.20.0.0/24 -j ACCEPT
iptables -I FORWARD -i s2s0 -o tun0 -s 10.20.0.0/24 -d 10.80.0.0/24 -j ACCEPT

Il filtro reverse-path è il guasto silenzioso accanto: con le due gambe su interfacce diverse, rp_filter=1 può scartare la risposta mentre il contatore della regola di accettazione non si muove mai. Confronta iptables -vnL FORWARD prima e dopo un tentativo. Una regola che non incrementa mai non viene raggiunta, quindi guarda uno strato più in basso invece di riscriverla.

Se solo un gruppo ha bisogno del transito, metti la rotta in un file per client sotto client-config-dir invece di allargare il push globale. Il NAT di origine sull’hub elimina anche la necessità di una rotta di ritorno remota, ma nasconde l’indirizzo dell’utente, quindi i log del sito remoto e le regole basate sull’indirizzo smettono di distinguere gli utenti.

Verifica dal client, poi annulla in ordine inverso

Prova una porta TCP, non solo ICMP, perché un ping può passare mentre il servizio resta bloccato. nc -vz 10.20.0.50 445 e traceroute -n 10.20.0.50 dal client mostrano se il secondo hop è l’indirizzo di tunnel dell’hub. Sull’hub, tcpdump -ni tun0 host 10.20.0.50 e lo stesso filtro sull’interfaccia tra sedi: una richiesta su entrambe senza risposta su nessuna sposta il problema sul lato remoto.

Poi prova qualcosa che deve restare bloccato. Se risponde anche un host che il pool non dovrebbe mai raggiungere, hai aperto più del transito e dovresti stringere le regole. Un hub che inoltra tutto a ogni spoke passa il primo test e fallisce il secondo.

Tieni una lista di rollback, perché sono cambiati quattro oggetti e tre sono facili da dimenticare: la rotta spinta, la rotta dell’hub, i selettori e le regole del firewall. Annullali in ordine inverso, ristabilisci la SA e fai riconnettere un utente. Un rollback parziale lascia una rotta che punta a un tunnel che non corrisponde più, il che è più difficile da leggere del silenzio originale. Il manuale di OpenVPN 2.6 documenta push, route e iroute per la tua versione.

Articoli correlati