SSL no funciona cuando se utiliza el protocolo PROXY entre NGINX-loadbalancer y NGINX-reverse-ssl-terminating-proxy

SSL no funciona cuando se utiliza el protocolo PROXY entre NGINX-loadbalancer y NGINX-reverse-ssl-terminating-proxy

Tengo un problema con nuestro balanceador de carga NGINX (basado en el módulo de transmisión) y con el uso de la IP remota real de nuestros usuarios finales.

Situación

Nuestra situación incluye muchos servidores, pero hay dos servidores relevantes:

  • Servidor A -> Equilibrador de carga que ejecuta NGINX con el módulo de transmisión
  • Servidor B -> en sentido ascendente ejecutando un proxy inverso NGINX para nuestra aplicación relevante, responsable de la terminación SSL

El servidor A usa SNI para enrutar a varios canales ascendentes (usando ssl_preread on).

Creo que queremos lograr la siguiente situación:

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

Configuración

Para esta situación específica, agregué un bloque de servidor adicional a nuestra transmisión con un puerto diferente, para poder probar esto junto con otros proyectos. La parte relevante de la configuración en el Servidor A:

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

Como se puede ver, el puerto 4431 reenvía a nuestro puerto ascendente en el puerto 4431, por proxy_protocol onlo que debería usar el protocolo proxy aquí.

En nuestro servidor B (ascendente 172.16.25.4) tengo otra instancia NGINX que tiene la siguiente configuración:

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
}

Verá otra escucha del puerto 4431, con las directivas ssly proxy_protocol. Hasta donde tengo entendido, esto significa que el servidor de escucha debe admitir los mensajes de protocolo PROXY provenientes de nuestro balanceador de carga.

Problema de conexión SSL

Sin embargo, no puedo establecer una conexión SSL. Puedo entender que eso no sería posible desde el Servidor B (ya que el cliente no usa el protocolo PROXY), pero creo que debería ser posible desde el Servidor A. Si intento conectarme obtengo la siguiente respuesta:

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)
---

No entiendo por qué no puedo conectarme usando SSL desde nuestro balanceador de carga, creo (o tal vez es más de lo que espero) que debe ser algo bastante simple que me falta. ¿Alguien tiene una idea de lo que estoy haciendo mal o de lo que me falta?

información relacionada