Discourse socketed: Nginx davanti a Discourse: nessun indirizzo IP

Hello,

My problem is that ever since i placed an nginx webserver in front of the discourse container (following this guide), i don’t see the IP addresses of my visitors.

Before my nginx in front of discourse:

----------------------------------------------------------------------------------------------------
Top 30 IPs by Server Load

IP Address      Duration Reqs
----------      -------- ----
192.168.87.1      158.06  436 
66.249.93.40        1.56    1 
138.201.140.150     1.41    2 
95.213.130.90       0.92    1 
64.71.168.196       0.64    6 
66.249.93.36        0.04    1 
---------------------------------

After my nginx in front of discourse:

----------------------------------------------------------------------------------------------------
Top 30 IPs by Server Load

IP Address Duration Reqs
---------- -------- ----
unix:        184.38 4886 
----------------------------------------------------------------------------------------------------

I hope i followed the guide correctly, but in case not, here’s what i suppose are the relevant nginx configs:

  • the discourse server file
server {
    server_name chat.tbp.land;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    ssl_certificate         /etc/letsencrypt/live/tbp.land/fullchain.pem;
    ssl_certificate_key     /etc/letsencrypt/live/tbp.land/privkey.pem;

##################################################
    http2_idle_timeout 5m;          # up from 3m default

    # ssl_protocols TLSv1.1 TLSv1.2;        # this is already the default in nginx.conf
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA;
    ssl_prefer_server_ciphers on;
    ###### ssl_ecdh_curve secp384r1:prime256v1; # this throws some error

    ###### ssl_session_tickets off;      # this also gives me an SSL error
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_stapling on;
    ssl_stapling_verify on;

    gzip on;

    add_header Strict-Transport-Security 'max-age=31536000'; # remember the certificate for a year and automatically connect to HTTPS for this domain
##################################################

    # maximum file upload size (keep up to date when changing the corresponding site setting)
    client_max_body_size 10m;

    location / {
        proxy_pass http://unix:/var/discourse/shared/web/nginx.http.sock:;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;

        error_page 502 =200 /errorpages/discourse_offline.html;     # normally its "=502" but cloudflare free account intercepts 502.
        proxy_intercept_errors on;
    }

    location /errorpages/ {
        alias /var/www/errorpages/;
    }

}
  • and the default server file
# this default is used so that when someone uses an address like https://aaa.tbp.land
# and aaa subdomain is enabled in cloudflare (although it doesn't exist on any server),
# nothing is shown. (if default_server doesn't exist, then a random site is chosen as a response)
# see https://serverfault.com/questions/850119/how-to-get-nginx-to-return-404-unless-a-specific-domain-name-is-requested

server {
    server_name _;
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;

    ssl_certificate /etc/letsencrypt/live/tbp.land/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/tbp.land/privkey.pem;

    return 444;
}

server {
    server_name _;
    listen 80 default_server;
    listen [::]:80 default_server;

    return 301 https://$host$request_uri;
}

#=================================================
#               Rate limit EVERYTHING!!!!!!!

# rate limiting zones
limit_req_zone $binary_remote_addr zone=flood:10m rate=15r/s;
limit_req_status 429;

limit_conn_zone $binary_remote_addr zone=connperip:10m;
limit_conn_status 429;

# rate limiting zones are applied for all servers!
limit_conn connperip 20;
limit_req zone=flood burst=20 nodelay;

#=================================================

# see: https://meta.discourse.org/t/x/74060
proxy_buffer_size 8k;

Possibly offtopic:

in the guide above i i see 2 different headers, depending on http vs https:

  • http:
    proxy_set_header X-Forwarded-Proto $scheme;
  • https:
    proxy_set_header X-Forwarded-Proto https;

I am using the second version with https instead of $scheme.

Looks like that guide is missing configuration for set_real_ip_from. Plenty of discussion about how to set that up in other topics, though.

you mean adding the cloudflare template? (that doesn’t make sense for me as the IP is not cloudflare one – i think it’s the unix socket?)

From

i tried to add proxy_set_header X-Real-IP $remote_addr; to my config, (after proxy_set_header X-Forwarded-Proto https;) but that doesn’t help either.

About set_real_ip_from: i see that in the socketed template the unix template is already handled (https://meta.discourse.org/t/how-do-i-make-the-top-30-ips-report-work-with-socketed-container/33924/):

so that means that i am not passing the IPs correctly?

HA!
I stand corrected: proxy_set_header X-Real-IP $remote_addr; is correct!

My problem was that i only refreshed my discourse tab instead of closing and opening a new one, and the connection was somehow kept by outer nginx.

After restarting nginx service: systemctl restart nginx, i can see the correct ips being passed to discourse.

@mpalmer can you confirm that what i did is ok, and if it is should i edit the guide/wiki and add this new header?

Seems like i got @codinghorror’s blessing so i’ve edited the wiki.

Thanks for the help!