Come posso modificare la configurazione di Nginx direttamente all'interno di discourse/docker?

Vorrei modificare la configurazione di Nginx/Docker perché la mia installazione di Discourse è dietro HAProxy. Il problema che sto riscontrando è il seguente:
Tutti gli indirizzi IP che si connettono alla mia installazione di Discourse appaiono come l’indirizzo IP di HAProxy.
Devo aggiungere le seguenti righe al file di configurazione di Nginx:

set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

…in modo da trasmettere gli indirizzi IP pubblici che si connettono alla mia installazione di Discourse a Nginx.
Grazie per il vostro aiuto.

Probabilmente non vuoi usare solo:

set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;

Questo è corretto solo se entrambe le seguenti condizioni sono vere:

  1. HAProxy sta effettivamente inviando il protocollo PROXY al container Discourse.
  2. Nginx all’interno del container Discourse vede HAProxy come 127.0.0.1.

In molte configurazioni Docker HAProxy → Discourse, l’approccio più semplice e comune è utilizzare X-Forwarded-For, non il protocollo PROXY.

Per HAProxy, assicurati che invii l’intestazione IP inoltrata:

defaults
    mode http
    option httplog
    option forwardfor

o nel backend:

backend be_discourse
    option forwardfor
    server app 127.0.0.1:8080 check

Poi, nella configurazione del container Discourse, rendi persistenti le modifiche all’IP reale di Nginx tramite app.yml. Non modificare i file direttamente all’interno del container in esecuzione, perché andranno persi alla ricostruzione.

Aggiungi qualcosa di simile a /var/discourse/containers/app.yml sotto la sezione esistente run::

run:
  - replace:
      filename: /etc/nginx/conf.d/discourse.conf
      from: "types {"
      to: |
        set_real_ip_from 127.0.0.1;
        # adatta questo all'intervallo reale di rete/ponte Docker da cui HAProxy si connette
        set_real_ip_from 172.17.0.0/16;
        real_ip_header X-Forwarded-For;
        real_ip_recursive on;
        types {

Poi ricostruisci:

cd /var/discourse
./launcher rebuild app

Potrebbe essere necessario regolare set_real_ip_from per corrispondere all’IP/intervallo reale di origine che Nginx all’interno del container Discourse vede quando HAProxy si connette ad esso. Con Docker, questo spesso non è 127.0.0.1; potrebbe essere un indirizzo di ponte Docker come 172.17.0.1 o un intervallo di rete Docker definito dall’utente.

Se vuoi davvero usare il protocollo PROXY, HAProxy deve inviarlo esplicitamente:

backend be_discourse
    server app 127.0.0.1:8080 check send-proxy

e Nginx deve ascoltare con proxy_protocol, non solo leggere real_ip_header 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 {

La correzione importante è: real_ip_header proxy_protocol da solo è incompleto. Nginx ha anche bisogno di listen 80 proxy_protocol;, e HAProxy ha bisogno di send-proxy. Altrimenti, usa X-Forwarded-For, che è la configurazione standard di HAProxy in modalità HTTP. In HAProxy, option forwardfor è il modo standard per aggiungere l’intestazione IP del client X-Forwarded-For. Con il protocollo PROXY di Nginx, la direttiva listen deve includere proxy_protocol prima che real_ip_header proxy_protocol possa funzionare.

Quindi, in breve:

  • Usa X-Forwarded-For a meno che tu non abbia un motivo specifico per usare il protocollo PROXY.
  • Non mescolare i due modi.
  • Se HAProxy non usa send-proxy, allora real_ip_header proxy_protocol non funzionerà.
  • Se usi Discourse Docker, effettua la modifica in app.yml, non direttamente all’interno del container in esecuzione.