Skip to content

Instantly share code, notes, and snippets.

@ipmb
Last active July 21, 2024 05:37
Show Gist options
  • Save ipmb/472da2a9071dd87e24d3 to your computer and use it in GitHub Desktop.
Save ipmb/472da2a9071dd87e24d3 to your computer and use it in GitHub Desktop.
Nginx reverse proxy with rate limiting
upstream myapp {
server 127.0.0.1:8081;
}
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
server {
listen 443 ssl spdy;
server_name _;
ssl on;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/cert.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers AES256+EECDH:AES256+EDH;
ssl_session_cache builtin:1000 shared:SSL:5m;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://myapp;
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;
}
location /account/login/ {
# apply rate limiting
limit_req zone=login burst=5;
# boilerplate copied from location /
proxy_pass http://myapp;
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;
}
}
@bitcity
Copy link

bitcity commented Jul 29, 2015

Is is possible to move all proxy_set_header to server block to avoid copy-pasting ? Something like:

server {
    listen 443 ssl spdy;
    server_name _;

    ssl on;
    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/cert.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers AES256+EECDH:AES256+EDH;
    ssl_session_cache  builtin:1000  shared:SSL:5m;
    ssl_prefer_server_ciphers on;

    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;

    location / {
        proxy_pass http://myapp;
    }

    location /account/login/ {
        # apply rate limiting
        limit_req zone=login burst=5;

        # boilerplate copied from location /
        proxy_pass http://myapp;
    }
}

@ebsaral
Copy link

ebsaral commented Jun 29, 2016

In a website with high traffic, the configurations must be something like:

limit_req_zone $binary_remote_addr zone=myzone:10m rate=10r/s; or limit_req_zone $binary_remote_addr zone=myzone:50m rate=100r/s; as I understood.

@Laxman-SM
Copy link

@esaral, Correct 10000 TPS this need to be higher value. Also this depend on server configuration and core availability.

@VarunBatraIT
Copy link

limit_req_zone depends on remote ip? I am guessing if there is only one IP is involved then just 2r/s is fine.

@rajuginne
Copy link

yes, it helps to prevent DOS attack from single IP. No matter how much traffic is you are getting from different IPs /users.

@alexandervlpl
Copy link

All the proxy_set_* boilerplate can be moved to the server or even http blocks as @bitcity suggested:

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header

Syntax:         proxy_set_header field value;
Default:        proxy_set_header Host $proxy_host;
                proxy_set_header Connection close;
Context:        http, server, location

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment