Una sottorete privata nel tunnel e tutto il resto sul vostro percorso abituale è una richiesta piccola con moltissimi modi di sbagliarla. A decidere il risultato non è la casella chiamata split tunneling, ma dove viene applicata la decisione: la tabella di routing del client stesso, una rotta spinta dal server o una politica negoziata dai due estremi. Scegliete lo strato sbagliato e otterrete o un tunnel completo che non avete mai voluto, o una rotta verso un tunnel che l'altro lato rifiuta di accettare. Uso una prova a tre condizioni prima di aprire qualsiasi configurazione, poi scelgo uno dei meccanismi qui sotto.

Tre condizioni che fissano il progetto

Primo, vi servono il prefisso e la maschera esatti dal proprietario della rete. La rete 10.x non è un prefisso; 10.20.0.0/16 lo è. Verificate che non si sovrapponga alla vostra LAN domestica, a un bridge Docker o a un'altra VPN che gestite, perché una sovrapposizione rende la rotta ambigua e il kernel sceglie la voce che non intendevate.

Secondo, chi risponde al traffico di ritorno. Instradare un pacchetto nel tunnel lo porta solo al server VPN. Se la sottorete sta dietro un altro router che non ha una rotta di ritorno verso il vostro pool di client, il server deve mascherare il traffico, oppure quel router deve imparare il vostro pool. Nessuna rotta lato client sistema un percorso di ritorno mancante.

Terzo, il punto di applicazione. Alcuni client installano una rotta e il sistema operativo fa il resto. Altri negoziano una politica, e una politica che il gateway non accetta non produce alcun tunnel: i pacchetti vengono scartati senza un errore evidente. Stabilite quale dei due casi è il vostro prima di scrivere qualcosa.

WireGuard: AllowedIPs è la tabella di routing

Sul client, AllowedIPs elenca le destinazioni che possono entrare nel tunnel, e wg-quick trasforma ogni voce in una rotta ordinaria. Quindi la metà client di questo compito è una sola riga.

[Peer]
PublicKey = ...
Endpoint = vpn.example.net:51820
AllowedIPs = 10.20.0.0/16

Ora confrontate la voce del server per lo stesso client. Descrive ciò che il server invierà al client, cioè di norma l'indirizzo di tunnel del client, non la sottorete privata.

[Peer]
PublicKey = ...
AllowedIPs = 10.99.0.2/32

Scambiare queste due è l'errore che vedo più spesso. Mettere 10.20.0.0/16 sotto la sezione peer del server dichiara che l'intera sottorete sta dietro quel client, ed è una pretesa da sito a sito, non un permesso. I pacchetti che non corrispondono all'AllowedIPs di nessun peer vengono scartati in silenzio, quindi una voce sbagliata sembra esattamente un problema di firewall.

Se gestite le rotte voi stessi, impostate Table = off sotto [Interface] e aggiungete la rotta che volete. Allora non viene aggiunto nulla automaticamente, quindi la rotta appartiene a ciò che alza l'interfaccia.

OpenVPN: spingete la rotta, poi assicuratevi che arrivi

Su un server normale la modifica è una direttiva nella configurazione del server, accanto al pool di client.

push "route 10.20.0.0 255.255.0.0"

Il client la aggiunge quando si connette. La modalità di errore compare quando lo stesso profilo spinge anche redirect-gateway, o quando qualcuno ha già aggiunto route-nopull: il primo trasforma la sessione in un tunnel completo, il secondo scarta ogni rotta spinta, compresa la vostra.

Un client che ha bisogno di un comportamento stretto verso un server a tunnel completo dovrebbe ignorare solo le parti che non vuole. Su OpenVPN 2.4 e successivi, pull-filter esiste proprio per questo.

pull-filter ignore "redirect-gateway"
route 10.20.0.0 255.255.0.0

Tenete separate le famiglie di indirizzi: una rotta IPv4 spinta non fa nulla per un servizio interno che risolve in IPv6, e quel servizio fallisce sul tunnel mentre tutto il resto sembra a posto.

Quando la sottorete privata non è sul server VPN ma dietro un altro client, bisogna avvisare il server. Aggiungete un file per client tramite client-config-dir che contenga iroute 10.20.0.0 255.255.0.0, più la route corrispondente perché gli altri client imparino il percorso. Senza iroute il server non ha motivo di inviare quel prefisso proprio attraverso quel tunnel.

IPsec: i selettori di traffico devono accordarsi

Con IPsec non c'è nessuna rotta da spingere. I due estremi negoziano quali indirizzi vivono dentro il tunnel, e il traffico fuori dai selettori concordati non viene né cifrato né inviato attraverso di esso. Su un client strongSwan i selettori sono espliciti.

leftsubnet=192.168.1.0/24
rightsubnet=10.20.0.0/16

Se il gateway è configurato con 0.0.0.0/0 su entrambi i lati, il restringimento IKEv2 di solito riduce la SA figlia all'intersezione delle due proposte, che è il risultato voluto. Alcuni gateway invece rifiutano una proposta che non corrisponde ai loro selettori configurati, e il registro mostra allora una SA figlia fallita invece di una lamentela di routing. Quando accade, la modifica spetta al gateway, perché una rotta sul client non può creare un tunnel per un selettore che l'altro lato non accetterà.

Su Windows il client integrato nasconde la stessa decisione dietro due impostazioni. La divisione del tunnel deve essere attiva, e il prefisso deve essere registrato sul profilo.

Set-VpnConnection -Name Office -SplitTunneling $true
Add-VpnConnectionRoute -ConnectionName Office -DestinationPrefix 10.20.0.0/16

È la registrazione del prefisso che lo fa sopravvivere a una riconnessione, cosa che una rotta aggiunta a mano non fa.

Tenete l'endpoint e il DNS fuori dalla decisione

L'endpoint della VPN deve restare raggiungibile senza il tunnel, altrimenti il tunnel crolla su sé stesso. Quando si instrada solo 10.20.0.0/16 è automatico, dato che l'endpoint è un indirizzo pubblico. Su un profilo a tunnel completo non lo è, e il client ha bisogno di una rotta host esplicita verso l'endpoint prima che il tunnel salga.

Il DNS è una seconda decisione che un push di rotta non prende per voi. I nomi interni di solito si risolvono tramite un resolver raggiungibile solo dalla rete privata. Se il server spinge un server DNS, ogni nome passa da lì; se non lo fa, i nomi interni o falliscono o si risolvono pubblicamente in qualcosa che non intendevate. Il DNS diviso tiene un dominio di ricerca sul resolver interno, ma dipende dal supporto del client, quindi trattatelo come un compito a sé e non come un effetto collaterale del routing.

Verificate, riavviate e verificate di nuovo

Tre sonde coprono la questione del routing. Chiedete al kernel dove andrebbe un indirizzo remoto, scaricate qualcosa dall'interno della sottorete, poi confermate che una richiesta pubblica ordinaria esca ancora dalla vostra connessione normale.

ip route get 10.20.5.7
curl -sS http://10.20.5.7/health
curl -sS https://ifconfig.me

La prima riga nomina un'interfaccia. Se nomina la vostra interfaccia fisica, la rotta non è mai arrivata. Su Windows, Find-NetRoute -RemoteIPAddress 10.20.5.7 risponde alla stessa domanda, e l'ultima sonda dovrebbe mostrare ancora il vostro indirizzo abituale e non quello del server VPN.

Poi riavviate. Le rotte aggiunte a mano spariscono, mentre le rotte del profilo, di una configurazione spinta o di AllowedIPs tornano. Se l'accesso stretto funziona prima del riavvio e fallisce dopo, il difetto sta in come parte il tunnel, non nella rotta stessa.

Prima di dichiararlo finito, confermate quattro cose: il prefisso è arrivato dal proprietario della rete e non si sovrappone a nulla di locale, il percorso di ritorno esiste o una regola di mascheramento lo sostituisce, il meccanismo che avete configurato è quello che applica il routing sulla vostra piattaforma, e le stesse sonde passano dopo un riavvio pulito. Le note di inoltro di strongSwan meritano una lettura se il percorso di ritorno è la parte che continua a fallire.

Articoli correlati