SSL funktioniert nicht bei Verwendung des PROXY-Protokolls zwischen NGINX-Loadbalancer und NGINX-Reverse-SSL-Terminating-Proxy

SSL funktioniert nicht bei Verwendung des PROXY-Protokolls zwischen NGINX-Loadbalancer und NGINX-Reverse-SSL-Terminating-Proxy

Ich habe ein Problem mit unserem NGINX-Load Balancer (basierend auf dem Stream-Modul) und der Verwendung der echten Remote-IP unserer Endbenutzer.

Situation

Unsere Situation umfasst viele Server, aber es gibt zwei relevante Server:

  • Server A -> Load Balancer mit NGINX und dem Stream-Modul
  • Server B -> Upstream mit einem NGINX-Reverse-Proxy zu unserer entsprechenden Anwendung, verantwortlich für die SSL-Terminierung

Server A verwendet SNI zum Routing zu verschiedenen Upstreams (mithilfe von ssl_preread on).

Ich denke, wir wollen folgende Situation erreichen:

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

Aufbau

Für diesen speziellen Fall habe ich unserem Stream einen zusätzlichen Serverblock mit einem anderen Port hinzugefügt, um dies neben einigen anderen Projekten testen zu können. Der relevante Teil der Konfiguration auf Server A:

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

Wie man sehen kann, leitet Port 4431 an unseren Upstream auf Port 4431 weiter, daher proxy_protocol onsollte hier das Proxy-Protokoll verwendet werden.

Auf unserem Server B (Upstream 172.16.25.4) habe ich eine weitere NGINX-Instanz mit der folgenden Konfiguration:

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
}

Sie sehen einen weiteren Listener für Port 4431 mit den -Anweisungen sslund proxy_protocol. Soweit ich verstanden habe, bedeutet dies, dass der Listener-Server die PROXY-Protokoll-Nachrichten unterstützen soll, die von unserem Load Balancer kommen.

Problem mit der SSL-Verbindung

Ich kann jedoch keine SSL-Verbindung herstellen. Ich kann verstehen, dass dies von Server B aus nicht möglich ist (da der Client das PROXY-Protokoll nicht verwendet), aber ich denke, dass es von Server A aus möglich sein sollte. Wenn ich versuche, eine Verbindung herzustellen, erhalte ich die folgende Antwort:

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

Ich verstehe nicht, warum ich von unserem Load Balancer aus keine Verbindung per SSL herstellen kann. Ich vermute (oder hoffe es eher), dass ich etwas ganz Einfaches übersehe. Hat jemand eine Idee, was ich falsch mache oder was ich übersehe?

verwandte Informationen