SSL não funciona ao usar o protocolo PROXY entre NGINX-loadbalancer e NGINX-reverse-ssl-terminating-proxy

SSL não funciona ao usar o protocolo PROXY entre NGINX-loadbalancer e NGINX-reverse-ssl-terminating-proxy

Tenho um problema com nosso balanceador de carga NGINX (baseado no módulo de fluxo) e com o uso do IP remoto real de nossos usuários finais.

Situação

Nossa situação inclui muitos servidores, mas existem dois servidores relevantes:

  • Servidor A -> Balanceador de carga executando NGINX com o módulo de fluxo
  • Servidor B -> upstream executando um proxy reverso NGINX para nosso aplicativo relevante, responsável pela terminação SSL

O servidor A usa SNI para rotear para vários upstreams (usando ssl_preread on).

Acho que queremos alcançar a seguinte situação:

Client ---[HTTPS]---> NGINX LB ---[PROXY PROTOCOL]---> NGINX Reverse proxy incl. SSL-termination ---[HTTP]---> PHP-container

Configuração

Para esta situação específica, adicionei um bloco de servidor adicional ao nosso stream com uma porta diferente, para poder testar isso junto com alguns outros projetos. A parte relevante da configuração no Servidor A:

stream {
    server {
        listen 4431;
        listen [::]:4431;
        ssl_preread on;
        proxy_pass 172.16.25.4:4431;
        proxy_protocol on;
    }
}

Como pode ser visto, a porta 4431 encaminha para o nosso upstream na porta 4431, portanto proxy_protocol ondeve usar o protocolo proxy aqui.

Em nosso servidor B (upstream 172.16.25.4), tenho outra instância NGINX que possui a seguinte configuração:

server {
    server_name <REDACTED>;
    location / {
        proxy_pass http://127.0.0.1:8000/;
        proxy_buffering off;
        proxy_set_header Host $host;
        proxy_set_header x-forwarded-proto      https;
        proxy_set_header X-Forwarded-For $proxy_protocol_addr;
        proxy_set_header X-Real-IP $proxy_protocol_addr;
    }

    listen 4431 ssl proxy_protocol;
    ssl_certificate /etc/letsencrypt/live/<REDACTED>/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/<REDACTED>/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

Você vê outra escuta para a porta 4431, com as diretivas ssle proxy_protocol. Pelo que entendi, isso significa que o servidor de escuta deve suportar as mensagens do protocolo PROXY provenientes do nosso balanceador de carga.

Problema de conexão SSL

No entanto, não consigo estabelecer uma conexão SSL. Entendo que isso não seria possível no Servidor B (já que o cliente não usa o protocolo PROXY), mas acho que deveria ser possível no Servidor A. Se eu tentar me conectar, recebo a seguinte resposta:

user@ServerA $ openssl s_client -connect 127.0.0.1:4431 -servername <REDACTED>
CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 320 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---

Não entendo por que não conseguiria me conectar usando SSL do nosso balanceador de carga, acho (ou talvez seja mais do que espero) que deve ser algo muito simples que estou perdendo. Alguém tem uma idéia do que estou fazendo de errado ou do que estou perdendo?

informação relacionada