Encaminhar bytes cifrados sem nunca deter o certificado é o que um relay TLS passthrough faz, e o arranjo é prático e um pouco confuso ao mesmo tempo. Como nada é decifrado, não existe nada em forma de HTTP para filtrar, então o bloco location habitual e as suas regras de acesso não servem aqui. A decisão de que o NGINX dispõe diz respeito à própria conexão: qual par da rede bateu e se esse par deve ser encaminhado.

A decisão pertence ao stream, não ao HTTP

No contexto stream o NGINX trabalha com sessões TCP. Vê o endereço de par da conexão e pode aplicar-lhe regras allow e deny ordenadas antes de qualquer byte chegar ao backend. É uma decisão de admissão completa e não exige chave privada, certificado nem análise HTTP.

MechanismWhat it decidesWhere it lives
stream allow/denyWhether this TCP peer is relayedstream server block
ssl_preread mapWhich backend a named connection goes tostream, with the preread module
HTTP location ruleWhether an HTTP request is servedhttp server block

Essas três linhas nunca se substituem. Copiar uma diretiva de acesso HTTP para o ficheiro que menciona a porta 443 não muda nada, porque o servidor stream nunca lê o contexto http.

Admite a conexão antes de a encaminhar

Suponha uma instalação existente com os módulos stream e stream-access disponíveis, clientes VPN que mantêm endereços de origem em 10.90.0.0/24, e um backend em 192.168.50.20:443 que já serve a identidade HTTPS pretendida.

stream {
    server {
        listen 443;

        allow 10.90.0.0/24;
        deny all;

        proxy_pass 192.168.50.20:443;
    }
}

Leia isto como um fragmento de um novo listener, não como uma substituição direta de uma configuração em funcionamento. Reveja primeiro os listeners e includes existentes, porque um segundo listener numa porta já ocupada falha no reload, não no momento do pedido.

Repare no que falta: não há listen ... ssl, não há diretiva de certificado. O NGINX encaminha o fluxo cifrado, e o backend termina o TLS e apresenta o certificado que o cliente valida. Um cliente que falhe a allowlist recebe a sessão TCP rejeitada, não uma página HTTP 403, e qualquer ferramenta que espere um código de estado reportará algo inútil.

O que a allowlist cobre e o que não cobre

Se o relay já escolhe backends pelo nome do servidor, ssl_preread e um map podem continuar a fazer esse trabalho, desde que o módulo esteja disponível. O nome continua a ser fornecido pelo cliente, e nada em apresentar um nome prova que o cliente aderiu à VPN.

A regra de exemplo cobre todo o listener stream. Isso torna-a inadequada para um único ponto de entrada que serve uma mistura de sítios públicos e sítios apenas para VPN, onde seria necessária uma exceção por nome; listeners separados são geralmente mais claros do que uma política dependente do nome que ninguém consegue ler.

Vale a pena nomear mais duas lacunas. Uma correspondência de prefixo não diz nada sobre por que interface o pacote chegou, e uma regra HTTP noutro lugar não pode restringir este listener. Ambas são razões para manter a política de entrada ao nível do host no quadro em vez de tratar uma linha allow como toda a fronteira. Escreva a fronteira como dois controlos que têm de concordar, para que qualquer alteração num deles seja revista.

Que endereço o NGINX vê realmente?

Um balanceador de carga, outro proxy ou um source NAT podem colocar um intermediário à frente do NGINX, pelo que o par observado não é o endereço interno do cliente VPN. Inspecione o caminho real antes de escolher um prefixo, porque uma allowlist escrita para o endereço errado ou admite todos os que estão atrás do tradutor ou ninguém.

O protocolo PROXY e o tratamento de IP real são respostas legítimas, e só devem ser configuradas para remetentes compatíveis e explicitamente fidedignos. Ambos os mecanismos acreditam no que o remetente diz, e é precisamente por isso que a lista de remetentes tem de ser curta. Confiar num cabeçalho de identidade de qualquer cliente de internet não torna a informação de origem fiável outra vez; converte uma recusa correta numa aceitação falsificada.

Teste os dois resultados antes do reload

Valide a configuração, faça reload e depois teste duas vezes: uma nova sessão permitida que tem de funcionar e uma recusada que não deve. Mantenha a verificação normal do certificado do backend no teste permitido, porque um relay que liga mas não consegue validar o backend resolveu um problema e criou outro.

nginx -t
ss -tnp | grep ':443'

Verifique também a rota até ao backend e a resposta em separado. Passar a allowlist prova apenas que o NGINX aceitou a sessão; não consegue fazer um backend inalcançável responder, nem reparar um caminho de retorno que faltava antes de começar.

Artigos relacionados