Contenitori Windows e VPN: perché la rete locale si rompe
Un contenitore Windows usa la tabella di routing dell'host, quindi una VPN che blocca la subnet locale si porta dietro il prefisso del contenitore. La modalità Linux prende un'altra strada.
Su un solo portatile, con un solo client VPN connesso, i contenitori Linux continuano a parlarsi e i contenitori Windows si fermano. La variabile non è l'immagine, ma il percorso che i pacchetti seguono verso l'host. I contenitori Windows sulla rete predefinita prendono in prestito la tabella di routing e la traduzione dell'host, quindi una politica che cambia il routing dell'host cambia anche loro. Confermatelo con una ricerca di route prima di reinstallare qualsiasi cosa.
Dove i pacchetti di un contenitore Windows entrano nell'host
Un contenitore sulla rete predefinita nat riceve un indirizzo da un prefisso del servizio Host Networking Service, di solito da qualche parte dentro 172.16.0.0/12, e raggiunge l'host tramite un adattatore virtuale. L'host possiede la route di quel prefisso e traduce il traffico verso l'adattatore attivo. Non c'è nessuna macchina virtuale separata in mezzo a quel percorso.
È questo progetto che rende meccanico il guasto. Quando il contenitore invia un pacchetto, l'host esegue una ricerca di route per il prefisso del contenitore. La route che vince è dove va il pacchetto, e il contenitore non ha opinioni in merito.
Cosa cambia il client VPN su quel percorso
Un client aziendale installa spesso un ampio insieme di route e un filtro che nega l'accesso alla subnet locale mentre il tunnel è attivo. L'intento è difensivo: una rete locale compromessa non deve raggiungere una macchina protetta. L'effetto collaterale è che la route dell'host verso il prefisso del contenitore non è più la rete NAT locale.
Invece la ricerca corrisponde al tunnel e il pacchetto viene consegnato al gateway, che non ha mai sentito parlare di quell'indirizzo del contenitore. Il ping fallisce, l'applicazione va in timeout e il contenitore sembra rotto mentre l'icona della VPN brilla. Guardate la tabella dell'host mentre siete connessi e la route concorrente è visibile.
| Container mode | Outbound path | Typical result behind the VPN |
|---|---|---|
| Windows, default nat | Host routes and translates container traffic | Container prefix follows the tunnel and fails |
| Windows, transparent | Container sits on the physical link | Depends on the local subnet being allowed |
| Linux engine on Docker Desktop | VM egress proxied by a host process | Often keeps working |
Perché i contenitori Linux si comportano diversamente
Il motore Linux esegue i contenitori dentro una macchina virtuale leggera, e le connessioni in uscita da quella macchina vengono aperte da un proxy lato host per conto del contenitore. È l'host che avvia il socket, quindi la regola della VPN sul prefisso del contenitore non si applica allo stesso modo, e il carico di lavoro continua a raggiungere la rete.
Questa differenza spiega anche perché le ricette Linux non si trasferiscono. A un contenitore Linux che ha bisogno del proprio tunnel viene assegnato un dispositivo TUN più la capacità NET_ADMIN. I contenitori Windows non espongono alcuna interfaccia come dispositivo, quindi quello schema non ha equivalenti su quel lato.
Dimostrate la route, poi scegliete un progetto
Raccogliete le prove dall'host, non dal contenitore, perché è l'host che esegue la ricerca:
docker network inspect nat --format "{{range .IPAM.Config}}{{.Subnet}}{{end}}"
route print -4
Get-NetRoute -AddressFamily IPv4 | Where-Object DestinationPrefix -like "172.16.*"
Eseguite l'output delle route una volta prima che la VPN si connetta e una volta dopo. Se nel secondo output il prefisso del contenitore punta all'adattatore del tunnel, la diagnosi è completa e riavviare i contenitori non aiuterà.
La prima opzione è una decisione di politica: chiedete al proprietario della rete se l'accesso alla LAN locale può essere consentito per questo dispositivo. Diversi client aziendali lo espongono come impostazione, ma indebolisce un confine deliberato. Chiedetelo come eccezione documentata con un proprietario e una data di revisione. Un interruttore per dispositivo che nessuno torna a rivedere è il modo in cui una politica difensiva sparisce in silenzio.
Dove la politica deve restare, spostate il carico di lavoro invece di combattere la route. Una rete trasparente con subnet e gateway espliciti mette i contenitori sul collegamento locale, un carico di lavoro Linux gira dietro il proxy della macchina virtuale, e una macchina virtuale separata con il proprio client conserva la propria politica. Sceglietene una deliberatamente e provatela dall'interno del contenitore, perché è lì che nasce la richiesta dell'utente.