VirtualBox NAT o bridge: dove finisce la VPN della VM
NAT nasconde un ospite dietro l'host, quindi un tunnel sull'host lo copre. Il bridge dà all'ospite un indirizzo proprio, quindi il tunnel deve vivere dentro la VM.
Due domande diverse arrivano insieme ogni volta che una macchina virtuale esegue un client VPN, e hanno risposte diverse. La prima è se un tunnel dentro l'ospite protegge l'host, la seconda è se un tunnel sull'host copre l'ospite. La modalità dell'adattatore decide entrambe, più del software VPN stesso. Un adattatore NAT rende l'host l'estremità visibile, mentre un adattatore bridge mette l'ospite sulla rete con il proprio indirizzo.
Chi termina davvero la sessione cifrata
Una sessione cifrata appartiene alla macchina che la termina, e questa è l'ospite quando il client gira dentro la VM. Solo il traffico che entra nell'adattatore virtuale dell'ospite attraversa quel tunnel, e l'hypervisor non instrada mai un'altra macchina attraverso l'ospite di sua iniziativa. Per questo l'ospite può mantenere un tunnel funzionante mentre l'host naviga in chiaro. Il contrario non è simmetrico, e questa asimmetria è la parte che quasi tutte le guide sbagliano.
Quale indirizzo vede la rete esterna è la domanda a cui risponde la modalità dell'adattatore. Una volta chiarito questo, la copertura smette di essere una questione di politica e diventa meccanica. Tutto quanto segue deriva da questi due fatti.
NAT riscrive l'ospite finché non sembra l'host
Con NAT, l'hypervisor riscrive ogni pacchetto dell'ospite verso l'indirizzo dell'host prima che raggiunga il primo commutatore. Quel traffico viene poi consegnato allo stack di rete dell'host, dove segue la sua tabella di routing, compresa una rotta predefinita posseduta da un tunnel sull'host. Un ospite NAT è quindi coperto da un tunnel sull'host senza alcuna configurazione, che è l'opposto di ciò che suggerisce il caso da ospite a host.
# on the host: adapter mode and NAT DNS behaviour
VBoxManage showvminfo "lab-vm" | grep -i -E "nic|nat"
VBoxManage modifyvm "lab-vm" --natdnshostresolver1 on
Un ospite che esegue il proprio client termina quel tunnel dentro l'ospite, e il traffico cifrato esce poi attraverso la stessa riscrittura, così le applicazioni dell'host mantengono il proprio percorso e il proprio indirizzo di uscita. VirtualBox possiede anche la risoluzione dei nomi in questa modalità e inoltra le query dell'ospite attraverso il proprio motore tranne se --natdnshostresolver1 è abilitato. Abilitarlo consegna le ricerche dell'ospite al resolver dell'host, il che corregge la risoluzione quando la visione dell'host è giusta e ugualmente consegna un resolver che può esistere solo dentro un tunnel. La VM deve essere spenta prima di cambiare l'impostazione, e l'impostazione appartiene all'adattatore e non al software dell'ospite.
Il bridge dà all'ospite il proprio lease e la propria esposizione
Il bridge passa i frame dell'ospite al segmento fisico, quindi DHCP gli assegna un lease e la rete lo tratta come un host separato. Ogni ospite in bridge può tenere un tunnel indipendente con la propria rotta predefinita, e la tabella dell'host non cambia mai. Il prezzo è l'esposizione: l'ospite risponde ai broadcast, compare nelle tabelle dei vicini e finisce sotto la sicurezza delle porte dello switch e l'isolamento dei client wireless. Nemmeno un tunnel sull'host copre questa disposizione, perché i frame dell'ospite non passano mai dallo stack dell'host.
Questa differenza rispetto al caso NAT va detta chiaramente invece di lasciarla come implicazione. Un ospite in bridge ha bisogno del proprio client e delle proprie credenziali ogni volta che il suo traffico deve usare un tunnel. Dove l'ospite deve restare invisibile alla rete locale, NAT o una rete solo interna con routing controllato è il progetto migliore.
Perché l'ospite non può essere il gateway dell'host
Prestare il tunnel di un ospite all'host non ha alcun interruttore supportato in nessuno dei due grandi hypervisor. L'host non ha rotte verso il tunnel dell'ospite né regole di traduzione che puntino lì, quindi il traffico dell'ospite e quello dell'host restano flussi separati con proprietari separati. Questa direzione fallisce indipendentemente dalla modalità dell'adattatore.
I sostituti praticabili sono gli inoltri e i proxy. Un inoltro locale SSH permette all'host di collegarsi al proprio loopback mentre l'ospite porta il flusso nel tunnel, il che copre i servizi TCP senza installare un secondo client. Far usare al traffico IP dell'host il tunnel dell'ospite invece richiede un router dentro l'ospite più una rotta esplicita sull'host e una traduzione sull'host. È un piccolo progetto di rete e non una casella da spuntare, e richiede un piano per il percorso di ritorno. Quando l'ospite esiste solo per eseguire il client, metti il client sull'host ed elimina il salto in più.
ssh -N -f -L 8080:internal-host.example:80 user@lab-vm
Resolver e rotte non attraversano il confine
Il DNS segue l'adattatore che ha ricevuto l'opzione, quindi un ospite non eredita il resolver del tunnel dell'host e un host non conosce mai il server spinto all'ospite. I valori dhcp-option DNS spinti valgono per l'interfaccia che li ha accettati, ed è per questo che un ospite in bridge senza client non può risolvere nomi interni. Un ospite NAT usa di norma la gestione DNS dell'hypervisor, e la differenza si vede in un comando per ambiente.
# on the host
VBoxManage showvminfo "lab-vm" | grep -i -E "nic|nat"
# inside a Linux guest
ip -4 route
resolvectl status
# inside a Windows guest
Get-DnsClientServerAddress
Leggi il resolver e la rotta dentro l'ospite prima di supporre che uno dei due segua l'host. Aggiungi il resolver del tunnel all'adattatore proprio dell'ospite quando i nomi interni vanno risolti lì, poi verifica con un nome che esiste solo dietro il tunnel. Annota la modalità dell'adattatore, il proprietario del tunnel e la fonte del resolver per ogni VM, perché questi tre fatti rispondono a quasi ogni domanda successiva. Gli altri hypervisor rinominano le modalità e lasciano intatto il principio.