SSL не работает при использовании PROXY-протокола между NGINX-loadbalancer и NGINX-reverse-ssl-terminating-proxy

SSL не работает при использовании PROXY-протокола между NGINX-loadbalancer и NGINX-reverse-ssl-terminating-proxy

У меня возникла проблема с нашим балансировщиком нагрузки NGINX (на основе потокового модуля) и использованием реальных удаленных IP-адресов наших конечных пользователей.

Ситуация

В нашей ситуации задействовано много серверов, но есть два важных сервера:

  • Сервер A -> Балансировщик нагрузки, работающий под управлением NGINX с модулем stream-module
  • Сервер B -> вышестоящий, на котором запущен обратный прокси-сервер NGINX для нашего соответствующего приложения, отвечающий за SSL-терминацию

Сервер A использует SNI для маршрутизации к различным восходящим потокам (используя ssl_preread on).

Я думаю, мы хотим добиться следующей ситуации:

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

Конфигурация

Для этой конкретной ситуации я добавил дополнительный блок сервера в наш поток с другим портом, чтобы иметь возможность протестировать это вместе с некоторыми другими проектами. Соответствующая часть конфигурации на сервере A:

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

Как можно заметить, порт 4431 перенаправляется на наш восходящий порт 4431, поэтому proxy_protocol onздесь следует использовать прокси-протокол.

На нашем сервере B (вышестоящий 172.16.25.4) у меня есть еще один экземпляр NGINX со следующей конфигурацией:

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
}

Вы видите еще один прослушиваемый порт 4431 с директивами sslи proxy_protocol. Насколько я понял, это означает, что прослушивающий сервер должен поддерживать сообщения PROXY-protocol-messages, поступающие от нашего балансировщика нагрузки.

Проблема с SSL-соединением

Однако я не могу установить SSL-соединение. Я понимаю, что это невозможно с сервера B (так как клиент не использует протокол PROXY), но я думаю, что это должно быть возможно с сервера A. Если я попытаюсь подключиться, то получу следующий ответ:

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

Я не понимаю, почему я не могу подключиться с помощью SSL из нашего балансировщика нагрузки, я полагаю (или, может быть, я надеюсь), что это что-то очень простое, что я упускаю. Есть ли у кого-нибудь идеи, что я делаю неправильно или что я упускаю?

Связанный контент