Permitir unha conexión TLS passthrough no contexto stream de NGINX
NGINX pode rexeitar un relé TCP TLS sen terminar TLS. Pon a regra de admisión en stream, non nun location HTTP, e comproba que enderezo de par chega.
Reenviar bytes cifrados sen ter nunca o certificado é o que fai un relé TLS passthrough, e o arranxo é cómodo e algo confuso á vez. Como non se descifra nada, non existe nada con forma de HTTP sobre o que filtrar, así que o bloque location habitual e as súas regras de acceso non serven aquí. A decisión da que dispón NGINX refírese á propia conexión: que par da rede chamou e se ese par debe reenviarse.
A decisión vai en stream, non en HTTP
No contexto stream NGINX traballa con sesións TCP. Ve o enderezo do par da conexión e pode aplicarlle regras allow e deny ordenadas antes de que ningún byte chegue ao backend. É unha decisión de admisión completa e non require chave privada, nin certificado, nin análise 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 |
Esas tres filas nunca se substitúen entre si. Copiar unha directiva de acceso HTTP ao ficheiro que mencione o porto 443 non cambia nada, porque o servidor stream nunca le o contexto http.
Admite a conexión antes de reenviala
Supón unha instalación existente cos módulos stream e stream-access dispoñibles, clientes VPN que manteñen enderezos de orixe en 10.90.0.0/24, e un backend en 192.168.50.20:443 que xa serve a identidade HTTPS prevista.
stream {
server {
listen 443;
allow 10.90.0.0/24;
deny all;
proxy_pass 192.168.50.20:443;
}
}
Léo como un fragmento de novo listener, non como unha substitución directa dunha configuración en funcionamento. Revisa primeiro os listeners e includes existentes, porque un segundo listener nun porto xa ocupado falla ao recargar, non no momento da petición.
Fíxate no que falta: non hai listen ... ssl, non hai directiva de certificado. NGINX reenvía o fluxo cifrado, e o backend termina TLS e presenta o certificado que valida o cliente. Un cliente que non pasa a allowlist recibe a súa sesión TCP rexeitada, non unha páxina HTTP 403, e calquera ferramenta que espere un código de estado informará de algo inútil.
Que cobre a allowlist e que non
Se o relé xa escolle backends polo nome do servidor, ssl_preread e un map poden seguir facendo ese traballo, sempre que o módulo estea dispoñible. O nome séguoo achegando o cliente, e nada en presentar un nome demostra que o cliente se unise á VPN.
A regra do exemplo cobre todo o listener stream. Iso faina inadecuada para un único punto de entrada que serve unha mestura de sitios públicos e sitios só para VPN, onde faría falta unha excepción por nome; os listeners separados adoitan ser máis claros que unha política dependente do nome que ninguén pode ler.
Paga a pena nomear dous ocos máis. Unha coincidencia de prefixo non di nada sobre por que interface chegou o paquete, e unha regra HTTP noutro lugar non pode restrinxir este listener. Ambas son razóns para manter a política de entrada a nivel de host na imaxe en lugar de tratar unha liña allow como toda a fronteira. Escribe a fronteira como dous controis que deben coincidir, para que calquera cambio nun deles se revise.
Que enderezo ve realmente NGINX?
Un balanceador de carga, outro proxy ou un source NAT poden poñer un intermediario diante de NGINX, así que o par que observa non é o enderezo interno do cliente VPN. Inspecciona a ruta real antes de escoller un prefixo, porque unha allowlist escrita para o enderezo equivocado ou ben admite a todos os que están detrás do tradutor ou ben a ninguén.
O protocolo PROXY e o tratamento de IP real son respostas lexítimas, e só deben configurarse para remitentes compatibles e explicitamente de confianza. Ambos os mecanismos cren o que di o remitente, e precisamente por iso a lista de remitentes ten que ser curta. Confiar nunha cabeceira de identidade de calquera cliente de internet non volve facer fiable a información de orixe; converte un rexeitamento correcto nunha aceptación falsificada.
Proba ambos os resultados antes de recargar
Valida a configuración, recarga e logo proba dúas veces: unha sesión nova permitida que debe funcionar e unha rexeitada que non debe. Mantén a verificación normal do certificado do backend na proba permitida, porque un relé que conecta pero non pode validar o backend resolveu un problema e creou outro.
nginx -t
ss -tnp | grep ':443'
Comproba tamén a ruta ao backend e a resposta por separado. Pasar a allowlist só demostra que NGINX aceptou a sesión; non pode facer que un backend inalcanzable responda, nin pode reparar un camiño de volta que faltaba antes de que empezases.