Perché una risposta UDP di OpenVPN parte da un indirizzo sbagliato
Un server UDP con più indirizzi locali può rispondere a un client da un indirizzo diverso da quello contattato. multihome corregge l’origine sulle piattaforme supportate.
Un client OpenVPN compone un indirizzo, il server risponde da un altro e il tunnel non sale mai. Il registro del server mostra il pacchetto in arrivo e una cattura mostra una risposta in uscita, così la colpa viene attribuita al client. Su un host con più interfacce, o con più indirizzi su una sola interfaccia, le due parti semplicemente non concordano su quale indirizzo sia in uso. La risposta è valida a livello IP, eppure molti client scartano un datagramma la cui origine non è l’indirizzo che hanno contattato.
Cosa vede il client quando l’origine cambia
Un socket UDP non legato a un indirizzo locale preciso non ha un’origine fissa, quindi il kernel ne sceglie una al momento dell’invio. Questa scelta deriva da una ricerca di rotta verso l’indirizzo del client, e l’origine diventa l’indirizzo dell’interfaccia che la ricerca seleziona. Su una macchina con una sola interfaccia la scelta è invisibile; su un host con un indirizzo di gestione, un indirizzo pubblico e un indirizzo secondario sulla stessa scheda di rete, dipende dalle metriche e dalla politica di routing. Il routing basato su politiche rende la discrepanza più probabile anziché meno, perché una regola può selezionare un uplink che il client non ha mai raggiunto. Una rotta predefinita appresa da un fornitore più una regola di origine che punta a un altro bastano a produrla.
I client che filtrano le risposte, e il tracciamento delle connessioni che attende la quadrupla esatta e l’origine, scarteranno la risposta senza un messaggio utile. Allora il tunnel scade come se non fosse arrivato nulla, ed è per questo che la cosa viene scambiata per un problema di firewall lato client. Una cattura presa solo sul server conferma l’errore invece di spiegarlo, perché la risposta parte davvero. Confrontate l’origine della risposta con l’indirizzo composto dal client prima di cambiare qualsiasi altra cosa.
Cosa fa realmente l’opzione multihome
La direttiva si scrive multihome in un file di configurazione e --multihome sulla riga di comando, e fa sì che un server UDP risponda dall’indirizzo raggiunto dal pacchetto del client. Il kernel consegna l’indirizzo di destinazione originale come dati ausiliari alla ricezione, e OpenVPN usa quel valore come origine della risposta. Così un server in ascolto su un indirizzo jolly, local 0.0.0.0 per IPv4 o il suo equivalente IPv6, si comporta come se ogni client avesse raggiunto un ascoltatore dedicato. I client entrati dall’indirizzo pubblico ricevono risposte dall’indirizzo pubblico, e i client su un indirizzo interno le ricevono da quello. Nient’altro nel percorso del pacchetto si muove: la rotta, le regole del filtro e la configurazione del tunnel restano esattamente come erano.
È proprio quest’ultima proprietà a rendere l’opzione sicura da aggiungere a un server che per il resto funziona, ed è anche il motivo per cui non può riparare un filtro che consente un solo indirizzo. Il pacchetto deve comunque essere accettato sul percorso che segue, quindi la correzione dell’origine cambia la provenienza della risposta e nulla più. È anche solo per UDP: un ascoltatore TCP non ha questo problema nella stessa forma, perché la connessione è identificata dalla quadrupla e non dall’indirizzo di origine della risposta.
Quando un indirizzo locale fisso è l’impostazione predefinita sbagliata
Prima di ricorrere all’opzione, verificate se il server lega un indirizzo locale preciso, perché un ascoltatore legato risponde sempre da quell’indirizzo. È corretto per un’implementazione a una sola interfaccia e sbagliato non appena i client usano legittimamente più di un indirizzo. Se il legame era deliberato, decidete se il server debba accettare traffico su indirizzi aggiuntivi. Rimuovere il legame aumenta l’esposizione, quindi le interfacce e le reti di origine consentite devono essere imposte dal servizio e dal filtro, non solo dall’indirizzo di legame.
Il riferimento di OpenVPN limita l’opzione ai server UDP, segnala l’elaborazione aggiuntiva nel percorso del pacchetto e indica quali piattaforme la supportano. Verificatelo sulla versione installata prima di pianificare in base a essa. Dove non è supportata, l’alternativa è legare l’indirizzo specifico o correggere la rotta di ritorno, ed entrambe sono modifiche più ristrette di quanto sembri a prima vista. L’ascolto jolly ha conseguenze anche oltre le risposte: un server su tutti gli indirizzi è raggiungibile da ogni rete a cui l’host è collegato, e forse non è l’esposizione che qualcuno intendeva.
Dimostrate l’origine della risposta dall’esterno
Provate dall’esterno del server e annotate l’indirizzo e il trasporto esatti usati dal client prima di catturare qualsiasi cosa. Le tre prove qui sotto rispondono a tre domande diverse, e l’ordine conta.
tcpdump -ni any udp port 1194
ss -lunp 'sport = :1194'
ip route get 203.0.113.10 from 198.51.100.20
La cattura mostra l’indirizzo di origine nella risposta, ed è il fatto su cui ruota l’intero articolo. L’elenco dei socket mostra cosa ha legato davvero il server, perché un ascoltatore jolly e uno specifico sembrano identici in un file di configurazione e si comportano diversamente sulla rete. La ricerca di rotta mostra l’origine che il kernel sceglierebbe per quel flusso, e questo spiega la cattura prima che cambiate qualcosa. Ripetete tutte e tre per IPv4 e IPv6 separatamente, perché sono ascoltatori distinti e ricerche distinte, e una voce jolly per una famiglia non dice nulla dell’altra.
Routing, scoperta e filtraggio restano separati
Preservare l’origine della risposta non installa una rotta in uscita, non aggiorna il DNS dinamico e non fa accettare una famiglia di indirizzi all’altra. Su un server con più uplink il percorso di ritorno di ciascuna origine deve essere concordato deliberatamente, altrimenti le risposte escono da un’interfaccia che il filtro del client non ha mai consentito. Allo stesso modo, un nuovo indirizzo dopo un cambio di prefisso deve raggiungere i client tramite la scoperta e il flusso di riconnessione supportato, non tramite il vecchio record.
Lasciate i controlli di identità del server e la verifica dei certificati esattamente come sono, perché un indirizzo cambiato non giustifica accettare un pari non verificato. Se la risposta ora parte dall’origine prevista e il tunnel continua a fallire, considerate risolto il problema dell’origine e andate avanti. Il prossimo errore osservato appartiene al routing, al filtraggio o all’autenticazione, e cambiare di nuovo l’ascoltatore non lo raggiungerà. Scrivete l’origine della risposta nel ticket accanto all’indirizzo composto dal client, così che la persona successiva possa verificare lo stesso fatto con un solo comando.