![NGINX-loadbalancer와 NGINX-reverse-ssl-terminating-proxy 간에 PROXY 프로토콜을 사용할 때 SSL이 작동하지 않습니다.](https://rvso.com/image/762114/NGINX-loadbalancer%EC%99%80%20NGINX-reverse-ssl-terminating-proxy%20%EA%B0%84%EC%97%90%20PROXY%20%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C%EC%9D%84%20%EC%82%AC%EC%9A%A9%ED%95%A0%20%EB%95%8C%20SSL%EC%9D%B4%20%EC%9E%91%EB%8F%99%ED%95%98%EC%A7%80%20%EC%95%8A%EC%8A%B5%EB%8B%88%EB%8B%A4..png)
NGINX 로드 밸런서(스트림 모듈 기반)와 최종 사용자의 실제 원격 IP를 사용하는 데 문제가 있습니다.
상황
우리 상황에는 많은 서버가 포함되어 있지만 관련 서버가 두 개 있습니다.
- 서버 A -> 스트림 모듈을 사용하여 NGINX를 실행하는 로드 밸런서
- 서버 B -> SSL 종료를 담당하는 관련 애플리케이션에 대해 NGINX 역방향 프록시를 실행하는 업스트림
서버 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
}
ssl
및 -지시문을 사용하여 포트 4431에 대한 또 다른 수신 대기를 볼 수 있습니다 proxy_protocol
. 내가 아는 한 이는 수신 서버가 로드 밸런서에서 오는 PROXY 프로토콜 메시지를 지원해야 함을 의미합니다.
SSL 연결 문제
그러나 SSL 연결을 설정할 수 없습니다. 클라이언트가 PROXY 프로토콜을 사용하지 않기 때문에 서버 B에서는 불가능하다는 것을 이해할 수 있지만 서버 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을 사용하여 연결할 수 없는 이유를 이해할 수 없습니다. 아마도 제가 놓치고 있는 아주 간단한 것임에 틀림없다고 생각합니다. 내가 뭘 잘못하고 있는지, 무엇을 놓치고 있는지 아는 사람이 있나요?