discourse/docker에서 Nginx 구성을 직접 수정하는 방법은 무엇인가요?

HAProxy 뒤에 Discourse 설치 환경이 있어 Nginx/Docker 설정을 수정하고 싶습니다. 현재 겪고 있는 문제는 다음과 같습니다.
Discourse 설치 환경에 연결되는 모든 IP가 HAProxy의 IP 주소로 표시됩니다.
Nginx 설정 파일에 다음 줄을 추가해야 합니다:

set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

…이를 통해 Discourse 설치 환경에 연결되는 공개 IP를 Nginx로 전달해야 합니다.
도와주셔서 감사합니다.

아마도 다음과 같이 설정만 하고 싶지는 않을 것입니다:

set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

이 설정은 다음 두 가지 조건이 모두 참일 때만 정확합니다:

  1. HAProxy가 실제로 Discourse 컨테이너에 PROXY 프로토콜을 전송하고 있는 경우.
  2. Discourse 컨테이너 내부의 Nginx가 HAProxy를 127.0.0.1로 인식하는 경우.

많은 HAProxy → Discourse Docker 환경에서는 PROXY 프로토콜 대신 X-Forwarded-For를 사용하는 것이 더 단순하고 일반적인 방법입니다.

HAProxy에서 전달된 IP 헤더가 전송되도록 확인하십시오:

defaults
    mode http
    option httplog
    option forwardfor

또는 백엔드 설정에서:

backend be_discourse
    option forwardfor
    server app 127.0.0.1:8080 check

그런 다음 Discourse 컨테이너 설정에서 app.yml을 통해 Nginx의 real-IP 변경 사항을 유지하도록 하십시오. 실행 중인 컨테이너 내부의 파일을 직접 편집하지 마십시오. 재빌드 시 변경 사항이 사라지기 때문입니다.

기존 run: 섹션 아래에 /var/discourse/containers/app.yml에 다음과 같은 내용을 추가하십시오:

run:
  - replace:
      filename: /etc/nginx/conf.d/discourse.conf
      from: "types {"
      to: |
        set_real_ip_from 127.0.0.1;
        # HAProxy가 연결하는 실제 Docker 브리지/네트워크 범위로 조정하십시오
        set_real_ip_from 172.17.0.0/16;
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;
        types {

그런 다음 재빌드하십시오:

cd /var/discourse
./launcher rebuild app

set_real_ip_from을 조정하여 HAProxy가 Discourse 컨테이너 내부의 Nginx에 연결할 때 Nginx가 인식하는 실제 소스 IP/범위와 일치하도록 해야 할 수 있습니다. Docker의 경우, 이는 127.0.0.1이 아닐 수 있으며 172.17.0.1과 같은 Docker 브리지 주소나 사용자 정의 Docker 네트워크 범위일 수 있습니다.

PROXY 프로토콜을 사용해야 하는 특별한 이유가 있다면, HAProxy가 이를 명시적으로 전송해야 합니다:

backend be_discourse
    server app 127.0.0.1:8080 check send-proxy

그리고 Nginx는 단순히 real_ip_header proxy_protocol을 읽는 것이 아니라 proxy_protocol로 리스닝해야 합니다:

run:
  - replace:
      filename: /etc/nginx/conf.d/discourse.conf
      from: "listen 80;"
      to: "listen 80 proxy_protocol;"

  - replace:
      filename: /etc/nginx/conf.d/discourse.conf
      from: "types {"
      to: |
        set_real_ip_from 127.0.0.1;
        set_real_ip_from 172.17.0.0/16;
        real_ip_header proxy_protocol;
        types {

중요한 수정 사항은 다음과 같습니다: real_ip_header proxy_protocol만으로는 불완전합니다. Nginx에는 listen 80 proxy_protocol;도 필요하고, HAProxy에는 send-proxy가 필요합니다. 그렇지 않다면, HAProxy HTTP 모드 설정에서 일반적으로 사용되는 X-Forwarded-For를 사용하십시오. HAProxy에서 option forwardforX-Forwarded-For 클라이언트 IP 헤더를 추가하는 표준 방법입니다. Nginx의 PROXY 프로토콜을 사용할 경우, real_ip_header proxy_protocol이 작동하려면 listen 지시문에 proxy_protocol이 포함되어야 합니다.

즉, 요약하면 다음과 같습니다:

  • PROXY 프로토콜을 사용해야 할 특별한 이유가 없는 한 X-Forwarded-For를 사용하십시오.
  • 두 모드를 혼합하지 마십시오.
  • HAProxy가 send-proxy를 사용하지 않는 경우, real_ip_header proxy_protocol은 작동하지 않습니다.
  • Discourse Docker를 사용하는 경우, 실행 중인 컨테이너 내부가 아닌 app.yml에서 변경 사항을 수행하십시오.

도와주셔서 감사합니다.

제가 해결한 방법은 다음과 같습니다:

  1. Let’s Encrypt와 HTTPS를 비활성화했습니다:
#- templates/web.ssl.template.yml

#- templates/web.letsencrypt.ssl.template.yml
  1. HAProxy가 Discourse의 SSL 인증서를 처리하도록 했습니다.
  2. /var/discourse/containers/app.yml 파일에 다음 구성을 사용했습니다.
run:
  - replace:
      filename: /etc/nginx/conf.d/discourse.conf
      from: "types {"
      to: |
        set_real_ip_from 192.168.1.8;   # HAProxy IP ADDRESS
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;
        types {

이제 Discourse 관리자 화면에서 공용 IP 주소를 확인할 수 있습니다:

@Ethsim2

다시 한번 도움 주셔서 감사합니다. :grin: