Il vostro client è impostato su UDP, il server Nginx ha un blocco location che punta alla porta della VPN e non arriva nulla. È prevedibile: un location HTTP non può trasportare un datagramma UDP, qualunque nome abbia il front end. Nginx richiede un listener stream per questo, e una volta spostata lì la configurazione, un secondo insieme di dettagli decide se una sessione sopravvive.

Il livello proxy viene prima dell'indirizzo

Il modulo stream di Nginx fa proxy di TCP e UDP senza analizzare HTTP. Il suo modulo HTTP si aspetta una riga di richiesta, intestazioni e una risposta, e niente di tutto ciò esiste in un datagramma OpenVPN nativo. Scegliere il livello è quindi la prima decisione, ed è indipendente dal fatto che il listener sia IPv4 o IPv6.

Una configurazione che sembra funzionare con OpenVPN su TCP non dice nulla sul caso UDP. Qui il trasporto fa parte del protocollo, non è un dettaglio del deployment.

Il listener e il backend

nginx -V 2>&1 | tr ' ' '\n' | grep stream

stream {
    server {
        listen [::]:1194 udp reuseport;
        proxy_pass [2001:db8::20]:1194;
    }
}

Verificate che la build includa il modulo stream prima di modificare qualsiasi cosa; un pacchetto di distribuzione può separarlo in un modulo a parte, e un modulo mancante produce un errore di configurazione anziché un tunnel. Mettete il blocco nel contesto principale di configurazione, non dentro http, e sostituite l'indirizzo di documentazione con il backend reale.

Sia le due rotte sia i due firewall devono consentire i datagrammi: il percorso verso il listener e il percorso dal proxy al backend. Un listener IPv6 non crea nemmeno un percorso IPv4, quindi se alcuni client usano ancora IPv4, quel listener è una voce separata con i suoi test. Controllate il firewall del backend dall'indirizzo del proxy, non dal vostro portatile.

I timeout di sessione non sono timeout di richiesta

Il proxy stream conserva lo stato per una sessione UDP e lo scarta secondo il suo timeout e le impostazioni di risposta. Un timeout breve copiato da un relay DNS si adatta male a una VPN che prevede di scambiare datagrammi per ore, e il guasto appare come una connessione che muore in silenzio anziché una che rifiuta di partire.

Leggete il proxy_timeout effettivo del deployment e qualsiasi impostazione di conteggio delle risposte, poi confrontateli con il comportamento keepalive che la VPN usa davvero. Due numeri scritti in file diversi da persone diverse sono lo stato normale di un sistema che funziona. Due numeri mai confrontati sono lo stato normale di un sistema intermittente. Scrivete entrambi nel registro del servizio perché il confronto avvenga una volta, alla luce del giorno.

Cosa cambia il relay e cosa no

Il proxy stream non termina il canale di controllo TLS di OpenVPN né lo converte in HTTPS. Il backend resta il servizio VPN, e il rapporto del certificato resta tra il client e quel servizio. Preservare l'identità di backend prevista resta compito del client e del server.

Il proxy ordinario cambia anche l'indirizzo sorgente che il backend vede. I log mostreranno il proxy, e qualsiasi regola di accesso basata su IP sul server VPN valuterà quell'indirizzo anziché quello del client. La conservazione trasparente della sorgente è un progetto separato di routing e privilegi, non qualcosa che deriva dall'aggiungere udp a un listener. Pianificatela prima che venga scritta una policy che dipende dall'indirizzo del client.

Verificate dal client, non dalla porta

Un controllo locale che la porta UDP sia aperta dimostra che il listener esiste. Non dimostra che un client possa autenticarsi attraverso di esso o continuare a scambiare traffico. Completate una connessione reale da un client approvato, poi confermate che la sessione resti attiva abbastanza a lungo da contare.

Quando qualcuno riferisce che Nginx non può fare UDP perché uno strumento di relay semplice ha funzionato al suo posto, i due fatti non sono collegati. Lo strumento ha dimostrato che il backend risponde; non ha detto nulla su ciò che il front end supporta. Entrambe possono essere vere, e solo una delle due è una configurazione per questo deployment.

Articoli correlati