Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing DDOS attack, for Django app with nginx reverse proxy + gunicorn

I am writing a Django app which uses an nginx reverse proxy + gunicorn as a webserver in production.

I want to include the capability to stop DDOS attacks from a certain IP (or pool of IPs). This as to be at the nginx level, rather than any deeper in the code. Do I need a web application firewall? If so, how do I integrate it.

My project's nginx file located at sites-available has:

server {
    listen 80;
    charset utf-8;
    underscores_in_headers on;
    location = /favicon.ico { access_log off; log_not_found off; }

    location /static/ {

        root /home/sarahm/djangoproject/djangoapp;
    }

    location /static/admin {

        root /home/sarahm/.virtualenvs/myenv/local/lib/python2.7/site-packages/django/contrib/admin/static/;
    }

    location / {
        proxy_pass_request_headers on;
        proxy_buffering on;
        proxy_buffers 8 24k;
        proxy_buffer_size 2k;
        include proxy_params;
        proxy_pass          http://unix:/home/sarahm/djangoproject/djangoapp/djangoapp.sock;
    }


    error_page 500 502 503 504 /500.html;
    location = /500.html {
        root /home/sarahm/djangoproject/djangoapp/templates/;
   }
}

Let me know if I should include more information, and what that information should be.

like image 695
Hassan Baig Avatar asked Feb 02 '16 12:02

Hassan Baig


1 Answers

If you want to prevent certain IPs or even subnets from accesing your app, add the following code to your server block:

#Specify adresses that are not allowed to access your server
    deny 192.168.1.1/24;
    deny 192.168.2.1/24;
    allow all;

Also if you're not useing REST, then you might want to limit possible HTTP verbs, by adding the following to your server block:

if ($request_method !~ ^(GET|HEAD|POST)$ ) {
    return 403;
}

To lessen the possibility of DoS attack, you might want to limit the number of possible requests from single host (see http://nginx.org/en/docs/stream/ngx_stream_limit_conn_module.html), by adding the following to NGINX nginx.conf:

limit_conn_zone $binary_remote_addr zone=limitzone:1M;

and the following to your server block:

limit_conn limitzone  20;

Some other useful setting for nginx.conf, that help mitigate DoS if set correctly:

server_tokens off;
autoindex off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
client_body_timeout 10;
client_header_timeout 10;
send_timeout 10;
keepalive_timeout  20 15;

open_file_cache max=5000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

Since it's too broad to explain these all here, suggest you to look in the docs http://nginx.org/en/docs/ for details. Though choosing correct values is achieved via trial and error on particular setup.

Django serves error pages itself as templates, so you should remove:

error_page 500 502 503 504 /500.html;
location = /500.html {
    root /home/sarahm/djangoproject/djangoapp/templates/;

Adding access_log off; log_not_found off; to static if you don't really care for logging is also an option:

location /static/ {
    access_log off;
    log_not_found off;
    root /home/sarahm/djangoproject/djangoapp;
}

this will lower the frequency of filesystem requests, therefore increasing performance.

NGINX is a great web server and setting it is a broad topic, so it's best to eaither read the docs (at least HOW-TO section) or find an article that describes the setup for a situation close to yours.

like image 55
Nikita Avatar answered Oct 24 '22 09:10

Nikita