Laboratorio VPN con VirtualBox: VM gateway o rete solo host
Scegliete tra una VM gateway instradata e un segmento solo host per un laboratorio VPN con VirtualBox, poi fate fallire chiuso l'ospite quando il tunnel cade.
Dovete decidere quanta macchineria merita il vostro laboratorio VPN. Una VM gateway instradata tra due segmenti VirtualBox riproduce la traduzione degli indirizzi, il percorso di ritorno e la posizione del firewall dietro cui siede un client reale. Un solo segmento solo host vi dà una porta controllata e nient'altro. La versione con gateway costa tre ospiti e una tabella di routing che mantenete; la versione solo host costa un ospite e una politica. Tre domande le separano, e la terza decide se il vostro test può passare del tutto.
Rispondete a tre domande prima di clonare qualsiasi cosa
Iniziate da ciò che il server VPN deve osservare. Se il server deve vedere un indirizzo sorgente che non è quello dell'ospite di test, qualcosa deve tradurre tra i due, e quel qualcosa deve essere un router che controllate. La rete solo host dà all'host un adattatore sul segmento dell'ospite, non un traduttore. Quando l'ospite deve poi raggiungere qualcosa all'esterno, collegate un adattatore NAT, e il motore NAT di VirtualBox stesso riscrive la sorgente senza chiedervi nulla.
Poi chiedete se l'ospite può raggiungere qualcosa se non attraverso il tunnel. Quella risposta sceglie interno o solo host, ed è la domanda che la maggior parte delle descrizioni di laboratorio salta. Infine chiedete cosa deve succedere quando il tunnel cade, perché questo decide la politica e non la topologia, e un laboratorio che dimostra solo il percorso felice non ha quasi provato nulla.
| What the test requires | Routed gateway VM | Host-only guest |
|---|---|---|
| Server sees a translated source address | Yes, from your own MASQUERADE rule | No, VirtualBox NAT does it instead |
| The guest has exactly one egress | Yes, while the second adapter faces the tunnel | Only until a NAT adapter is attached |
| Policy is testable during a tunnel failure | Rules live in one place | Rules live on each guest |
Collegate i tre ruoli con reti interne
Usate tre ospiti e due segmenti con nome, con il gateway come l'unica macchina che ha un adattatore su entrambi:
VBoxManage modifyvm lab-client --nic1 intnet --intnet1 WAN
VBoxManage modifyvm lab-server --nic1 intnet --intnet1 LAN
VBoxManage modifyvm lab-gw --nic1 intnet --intnet1 WAN --nic2 intnet --intnet2 LAN
Non c'è un passo di creazione separato per una rete interna. La stringa in --intnet1 è il segmento: due macchine lo condividono solo se il nome coincide esattamente, e nulla sull'host vi è collegato. Quest'ultima proprietà è il motivo per cui il laboratorio si ripete in modo pulito, poiché le rotte dell'host, il suo client VPN e il suo firewall non possono raggiungere gli ospiti per caso. Un segmento interno non ha nemmeno un server DHCP a meno che non ne aggiungiate uno, quindi gli indirizzi statici sono la via più breve.
Date al client solo il suo indirizzo WAN, con un gateway predefinito che punta all'indirizzo WAN del gateway. Il server riceve un indirizzo LAN e usa l'indirizzo LAN del gateway come gateway predefinito. Un ospite che tiene due indirizzi su un segmento, o ha una rotta smarrita verso l'altro segmento, ha un percorso attorno al router, e i test qui sotto vi mentiranno.
Tengo un file di testo accanto ai nomi delle VM con i quattro indirizzi e i due nomi dei segmenti, e lo incollo in ogni shell. Settimane dopo, quando un cambio di profilo rompe qualcosa, quel file è la differenza tra il debug del profilo e il debug della mia stessa memoria.
Scegliete interno o solo host per il segmento che non deve perdere
La modalità solo host crea un adattatore virtuale sull'host stesso, di solito vboxnet0, e dà all'host un indirizzo sul segmento dell'ospite. È comodo per l'amministrazione e fatale per un test di isolamento, perché l'host ora può raggiungere l'ospite direttamente e ogni servizio lato host diventa un percorso possibile. La modalità interna non ha alcun adattatore host. Le due modalità si confondono facilmente nel pannello delle impostazioni di rete, quindi verificate la differenza documentata invece dell'etichetta (vedete la pagina dettagli di rete di VirtualBox).
Per un ospite che deve usare il tunnel, l'interno è il valore predefinito più sicuro, con il gateway come unica uscita. Se mantenete solo host, trattate l'adattatore host come un percorso di gestione e ditelo a voce alta: l'host può raggiungere l'ospite, e l'ospite non deve poter usare l'host come uscita.
VBoxManage modifyvm lab-client --nic1 hostonly --hostonlyadapter1 vboxnet0
L'isolamento che potete dimostrare è l'isolamento che avete configurato. Un ospite con un adattatore interno, una rotta predefinita sul gateway e nessun adattatore NAT non ha alcun percorso che aggiri il gateway. Un ospite con un adattatore solo host e un adattatore NAT ha due percorsi, e solo uno è quello che volevate provare.
Instradate e traducete sul gateway, poi fatelo fallire chiuso
VirtualBox non inoltra tra segmenti; lo fa l'ospite. Con la VM del server VPN dietro il gateway, abilitate l'inoltro e traducete il traffico del client mentre esce verso il server:
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
Con quella regola il server vede l'indirizzo LAN del gateway invece di quello del client, ed è così che un client reale dietro un NAT di operatore appare a un head-end. Salvate il valore sysctl in /etc/sysctl.d/ e la regola nel servizio firewall usato dalla distribuzione, altrimenti un riavvio riporta silenziosamente il laboratorio a uno stato instradato ma non tradotto.
L'inoltro non è autorizzazione. Sotto la politica FORWARD predefinita di ACCEPT, un ospite la cui rotta predefinita punta al gateway esce dall'interfaccia scelta dalla tabella di routing, con o senza tunnel. Se il gateway ha anche un adattatore NAT per installare pacchetti, quell'adattatore è un'uscita non cifrata funzionante nel momento in cui il tunnel cade, e il vostro test solo VPN non è mai stato un test solo VPN.
Quando il server è remoto ed è il gateway stesso a terminare il tunnel, la stessa decisione punta all'interfaccia del tunnel, non alla NIC che raggiunge internet:
iptables -P FORWARD DROP
iptables -A FORWARD -i eth0 -o tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Tenete il trasporto esterno proprio del tunnel e una rotta di gestione fuori banda separati dal traffico inoltrato. Se l'unico modo per riparare il gateway è attraverso il tunnel che state debuggando, il laboratorio diventa un esercizio di blocco. Una console seriale, un adattatore di gestione solo host o un'istantanea di uno stato buono noto costano meno del recupero manuale di un router rotto.
Verificate il percorso dall'ospite, non dall'host
Lavorate verso l'esterno. Confermate che il client raggiunge l'indirizzo WAN del gateway, poi il server attraverso il gateway, poi che una connessione alla porta VPN esce e ritorna. Una cattura su entrambe le interfacce del gateway mostra se la risposta arriva e viene scartata sul percorso di ritorno, cosa che una cattura solo sul client non può distinguere:
tcpdump -ni eth0 udp port 1194
tcpdump -ni tun0 udp port 1194
Poi dimostrate l'uscita. Chiedete dall'ospite a un servizio di riflessione degli indirizzi quale sorgente vede e confrontatela con l'indirizzo di uscita del gateway; se la risposta coincide con l'indirizzo dell'host, esiste un percorso attorno al tunnel. Verificate quale resolver usa realmente l'ospite, e verificate IPv6 separatamente, perché un segmento in cui IPv6 è attivo mentre il tunnel porta solo IPv4 perde per progetto e non per caso.
Infine, rompetelo di proposito. Fermate il tunnel, o bloccate la sua porta esterna, e aprite una nuova connessione dall'ospite. Deve fallire, e il motivo deve essere uno che potete nominare: nessuna rotta, una regola di rifiuto o un resolver morto. Riavviate il tunnel e confermate che l'ospite si riprende senza ricostruire la rete. Se una VPN mesh come Hamachi o ZeroTier condivide il laboratorio, ricordate che un adattatore in bridge segue il nome dell'adattatore, non la mesh, quindi il bridge va reindirizzato dopo che il client installa il proprio adattatore virtuale.
VBoxManage list bridgedifs
VBoxManage modifyvm lab-client --bridgeadapter1 <mesh-adapter-name>
Condividere il tunnel di un ospite con l'host rispecchia il problema. Puntare la rotta predefinita dell'host all'ospite funziona, e anche un proxy dentro l'ospite; il NAT attraverso l'host non porta il tunnel dell'ospite per il traffico che l'host ha originato. Salvate i nomi dei segmenti e le regole del firewall in un unico posto, fate un'istantanea dello stato che funziona e annotate l'indirizzo sorgente che il server ha osservato. Il prossimo cambio di profilo costa allora un'esecuzione di script invece di un laboratorio ricostruito.