Consentire una connessione TLS passthrough nel contesto stream di NGINX
NGINX può rifiutare un relay TCP TLS senza terminare TLS. Metti la regola di ammissione in stream, non in una location HTTP, e controlla quale indirizzo peer arriva.
Inoltrare byte cifrati senza mai detenere il certificato è ciò che fa un relay TLS passthrough, e la soluzione è comoda e insieme un po’ confusa. Poiché nulla viene decifrato, non esiste nulla in forma HTTP su cui filtrare, quindi il solito blocco location e le sue regole di accesso qui non servono a nulla. La decisione a disposizione di NGINX riguarda la connessione stessa: quale peer di rete ha bussato e se quel peer vada inoltrato del tutto.
La decisione appartiene a stream, non a HTTP
Nel contesto stream NGINX lavora con sessioni TCP. Vede l’indirizzo peer della connessione e può applicarvi regole allow e deny ordinate prima che qualsiasi byte raggiunga il backend. È una decisione di ammissione completa e non richiede chiave privata, certificato né analisi HTTP.
| Mechanism | What it decides | Where it lives |
|---|---|---|
| stream allow/deny | Whether this TCP peer is relayed | stream server block |
| ssl_preread map | Which backend a named connection goes to | stream, with the preread module |
| HTTP location rule | Whether an HTTP request is served | http server block |
Quelle tre righe non si sostituiscono mai l’una con l’altra. Copiare una direttiva di accesso HTTP nel file che menziona la porta 443 non cambia nulla, perché il server stream non legge mai il contesto http.
Ammetti la connessione prima di inoltrarla
Supponi un’installazione esistente con i moduli stream e stream-access disponibili, client VPN che mantengono indirizzi di origine in 10.90.0.0/24, e un backend su 192.168.50.20:443 che già serve l’identità HTTPS prevista.
stream {
server {
listen 443;
allow 10.90.0.0/24;
deny all;
proxy_pass 192.168.50.20:443;
}
}
Leggilo come un frammento di un nuovo listener, non come una sostituzione diretta di una configurazione funzionante. Esamina prima i listener e gli include esistenti, perché un secondo listener su una porta già occupata fallisce al reload, non al momento della richiesta.
Nota ciò che manca: nessun listen ... ssl, nessuna direttiva di certificato. NGINX inoltra il flusso cifrato, e il backend termina TLS e presenta il certificato che il client convalida. Un client che non supera la allowlist riceve la sessione TCP rifiutata, non una pagina HTTP 403, e qualsiasi strumento che si aspetta un codice di stato riporterà qualcosa di inutile.
Cosa copre la allowlist e cosa no
Se il relay sceglie già i backend per nome del server, ssl_preread e una map possono continuare a fare quel lavoro, purché il modulo sia disponibile. Il nome è ancora fornito dal client, e nulla nel presentare un nome prova che il client sia entrato nella VPN.
La regola di esempio copre l’intero listener stream. Ciò la rende inadatta a un unico punto di ingresso che serve un misto di siti pubblici e siti solo VPN, dove servirebbe un’eccezione per nome; listener separati sono di solito più chiari di una politica dipendente dal nome che nessuno può leggere.
Vale la pena nominare altre due lacune. Una corrispondenza di prefisso non dice nulla su quale interfaccia sia arrivato il pacchetto, e una regola HTTP altrove non può vincolare questo listener. Entrambe sono ragioni per tenere la politica di ingresso a livello di host nel quadro invece di trattare una riga allow come l’intero confine. Scrivi il confine come due controlli che devono concordare, così che qualsiasi modifica a uno dei due venga riesaminata.
Quale indirizzo vede davvero NGINX?
Un bilanciatore di carico, un altro proxy o un source NAT possono mettere un intermediario davanti a NGINX, quindi il peer osservato non è l’indirizzo interno del client VPN. Ispeziona il percorso reale prima di scegliere un prefisso, perché una allowlist scritta per l’indirizzo sbagliato o ammette tutti dietro il traduttore o nessuno.
Il protocollo PROXY e la gestione dell’IP reale sono risposte legittime, e vanno configurate solo per mittenti compatibili ed esplicitamente fidati. Entrambi i meccanismi credono a ciò che dice il mittente, ed è proprio per questo che l’elenco dei mittenti deve essere corto. Fidarsi di un’intestazione di identità da qualsiasi client Internet non rende di nuovo affidabili le informazioni di origine; trasforma un rifiuto corretto in un’accettazione falsificata.
Verifica entrambi gli esiti prima del reload
Convalida la configurazione, esegui il reload, poi verifica due volte: una nuova sessione consentita che deve funzionare e una rifiutata che non deve. Mantieni la normale verifica del certificato del backend nel test consentito, perché un relay che si connette ma non riesce a convalidare il backend ha risolto un problema e ne ha creato un altro.
nginx -t
ss -tnp | grep ':443'
Controlla anche il percorso verso il backend e la risposta separatamente. Superare la allowlist prova solo che NGINX ha accettato la sessione; non può far rispondere un backend irraggiungibile, né riparare un percorso di ritorno che mancava prima che iniziassi.