Rotte separate L2TP su Mac: perché un indirizzo host non funziona
setadditionalroutes vuole coppie rete e maschera, sostituisce l'intera lista e richiede il nome letterale del servizio. Controllate la tabella prima di incolpare il gateway.
La VPN si connette, la barra dei menu lo mostra, e un host interno va comunque in timeout. In questa situazione ci sono tre cause possibili, e quale si applichi dipende da come è stato configurato il tunnel. O il comando di rotta ha usato un indirizzo host dove serviva un indirizzo di rete, o il profilo stesso installa una rotta predefinita che ingoia la decisione, o il client è un tunnel PPP che ha bisogno di un hook invece di una chiave di profilo. Controllatele in quest'ordine, perché la prima è la più economica da escludere.
La destinazione è un indirizzo di rete, la maschera descrive il prefisso
networksetup -setadditionalroutes accetta terne di destinazione, maschera di sottorete e gateway. La chiamata che manda una sottorete interna attraverso il tunnel è questa:
sudo networksetup -setadditionalroutes "VPN (L2TP)" 192.168.1.0 255.255.255.0 10.2.0.0
Notate cos'è la destinazione: l'indirizzo di rete, non l'indirizzo del server che cercate di raggiungere. Nel caso che ha prodotto questo articolo, il comando identico con 192.168.1.20 in quella posizione non ha fatto nulla di utile, e sostituirlo con 192.168.1.0 ha funzionato subito. Stessa maschera, stesso gateway, un numero diverso. È tutto il guasto in miniatura.
La ragione è aritmetica, non politica. Un indirizzo host abbinato a una maschera /24 non descrive 192.168.1.0/24; descrive qualcosa che la tabella di routing non può tenere utilmente, quindi la voce viene rifiutata o ignorata e il tunnel finisce per trasportare meno del previsto.
Quando volete esattamente un host, usate l'indirizzo host con maschera 255.255.255.255. È nelle coppie miste che questo va storto, non nell'uso di un indirizzo host in sé. Una /32 costruita da un indirizzo è una rotta legittima; una /24 costruita da un indirizzo è un errore.
La chiamata sostituisce la lista, e il nome è letterale
Due comportamenti sorprendono al primo tentativo. Il comando imposta l'intera lista di rotte aggiuntive invece di aggiungere, quindi una chiamata che aggiunge un prefisso rimuove in silenzio le altre che c'erano prima. Costruite l'intero insieme in un'unica invocazione.
Anche il nome del servizio non è l'etichetta che avete inventato. Leggetelo dallo strumento e copiatelo esattamente, incluso il suffisso del tipo:
networksetup -listallnetworkservices
Un nome che differisce di un carattere non produce errori degni di lettura né alcuna rotta. Copiare e incollare è la tecnica giusta qui, non riscrivere a memoria.
Quando il profilo rivendica la rotta predefinita
Le rotte separate perdono contro una rotta predefinita per ogni destinazione che non coprono esplicitamente, e un profilo L2TP configurato per il tunnel completo installa esattamente questo. Se il profilo dice che tutto passa dal tunnel, la lista delle rotte aggiuntive cambia pochissimo. La vostra voce non è sbagliata; è semplicemente irrilevante per le destinazioni che non nomina mai. Il controllo di questo di solito sta nell'impostazione del profilo per l'invio di tutto il traffico, non in un comando di rotta.
Decidete quale modello volete davvero prima di modificare altre voci. Il tunnel completo con eccezioni è una configurazione diversa dal tunnel separato con prefissi specifici, e mescolare i due produce una tabella che nessuno può prevedere.
Se l'organizzazione richiede il tunnel completo, smettete di provare a separarlo localmente e portate la richiesta a chi possiede la politica. Una rotta aggiunta localmente che la contraddice sarà comunque rimossa dal prossimo aggiornamento del profilo.
I tunnel PPP hanno bisogno di un hook invece di una chiave
Per i tunnel basati su PPP, defaultroute è la chiave di profilo che crea una rotta predefinita; eliminate e il client smette di rivendicare ogni destinazione. Le rotte vengono poi aggiunte dopo la comparsa dell'interfaccia, di solito da /etc/ppp/ip-up:
#!/bin/sh
/sbin/route add -net 192.168.1.0 -interface ppp0
Tenete lo script di proprietà di root ed eseguibile, e aggiungete una protezione sul nome dell'interfaccia quando sulla macchina esiste più di un profilo di tunnel. Un hook che gira per ogni collegamento PPP e presume un solo nome di dispositivo è un piccolo bug dalla lunga vita.
Verificate la separazione con tre richieste
Catturate la tabella mentre siete connessi e annotate quale interfaccia serve il tunnel. Poi controllate la destinazione specifica invece di fidarvi dello stato di uscita del comando che l'ha creata. Un codice di uscita dice se lo strumento ha accettato gli argomenti, non se il traffico segue il percorso previsto.
Chiudete con tre richieste che provano la separazione: un host interno per indirizzo, un nome interno attraverso il resolver interno e un sito pubblico che dovrebbe ancora usare la connessione locale. Se il sito pubblico ora passa anch'esso dal tunnel, la separazione non è mai avvenuta, qualunque cosa sembri dire la lista delle rotte.
Riconnettetevi ancora una volta e ripetete la richiesta interna, perché le rotte aggiunte a mano possono sopravvivere all'interfaccia che le ha rese valide e trasformare silenziosamente il traffico in un buco nero dopo la caduta del tunnel.