Frequent nginx rate limiting with nginx also on the host

Continuing the discussion from Best free option to protect discourse from many requests:

Looks like these “too many request” errors are still coming thick and fast on my forum (and I don’t think I’m under DDOS attack):

I think the stock nginx config (the Discourse nginx instance) is overly conservative with its rate limits.

There are a lot of errors like the below in /var/discourse/shared/standalone/log/var-log/nginx/error.log on my host:

2019/04/24 13:08:55 [error] 66#66: *2237264 limiting requests, excess: 12.592 by zone "flood", client: 172.17.0.1, server: _, request: "GET /user-badges/Cheekybecki.json?_=1556111332933 HTTP/1.0", host: "se23.life", referrer: "https://se23.life/t/cleaner-recommendations/1147?page=2"

I note the client IP is reported as 172.17.0.1 - this is Docker’s host IP (not the real client IP). Could this be the problem?

1 Like

My “outer nginx instance” config on the host is as follows (I believe I’m forwarding real client IPs, but perhaps this isn’t working?):

upstream se23.life {
    ip_hash;
    server localhost:9092;
}

server {
    listen 212.110.179.83:80;
    server_name www.se23.life se23.life;
    access_log off;
    return 301 https://se23.life$request_uri;
}

server {
    listen 212.110.179.83:443 ssl;
    server_name www.se23.life;
    ssl_certificate [redacted];
    ssl_certificate_key [redacted];
    ssl_protocols TLSv1.2;
    ssl_ciphers '[redacted]';
    ssl_prefer_server_ciphers on;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    access_log off;
    return 301 https://se23.life$request_uri;
}

server {
    listen 212.110.179.83:443 ssl;
    server_name se23.life;
    ssl_certificate [redacted];
    ssl_certificate_key [redacted];
    ssl_protocols TLSv1.2;
    ssl_ciphers '[redacted]';
    ssl_prefer_server_ciphers on;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;

    rewrite ^/verify$ /groups/Verified_By_Members redirect;
    rewrite ^/t/se23-life-for-businesses/40 /advertise permanent;
    rewrite ^/t/about-the-commercial-category/40 /advertise permanent;
    rewrite ^/t/how-to-pay-for-promotional-topics-current-cost-12/525 /advertise permanent;
    location /.well-known {
        root   /var/www/se23.life/;
    }
    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_pass http://se23.life;
    }
    access_log off;
}

You need to tell nginx inside the container to trust 172.17.0.1 to set the Client IP headers by using the set_real_ip_from directive.

4 Likes

Have you checked your discourse install to see what IP it shows you as visiting from?

Thanks @supermathie.

Given that Docker is the standard deployment mechanism for Discourse, shouldn’t Discourse’s stock nginx config be set to include 172.17.0.1 as a set_real_ip_from directive out of the box?

No - the recommended configuration doesn’t use nginx on the host so it wouldn’t be necessary.

5 Likes

Ah I see, that makes sense, thanks

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.