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?

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.