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

1

7

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.

Forewent answered 2/2, 2016 at 12:2 Comment(0)
P
13

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.

Putput answered 2/2, 2016 at 12:37 Comment(8)
Thanks for getting me started Nikita. I'll read the docs like you advised, and check off the settings you've posted.Forewent
For completeness, do you also have anything to add to your answer vis-a-vis Naxsi (github.com/nbs-system/naxsi)? Or that's not relevant to a DDOS attack?Forewent
I'm sorry, I don't have any experience with Naxi to tell anything about it. In general, I would say, that you application, unless it's really special, won't interest "bad" people to make an attack, unless it gets famous or will affect other people buiseness (competition). Main reason for DDoS is to prevent site owner from doing buisiness, which is paid by unhonest competition, or to get site owner to pay ransom, because under DDoS attack the owner will loose money (i.e. ecommerce).Putput
If the site is growing big or is main buiseness asset, then it's worth to pay professionals to organize the defence, or at least use special services like cloudflare, etc. Untill then, you only need to make simple measures, some of which I suggested, to limit the effect of unintentional DoS effect, that might be cause by indexing or parsing of your site and etc. Because if someone will really want to DDoS it, they will succeed, unless you have an expensive server setup.Putput
Talking about general security... It's always important, because even if your site is not big and famous, while it probably won't attract professional "hackers" as not challenging enough, it might interest "script kiddies". But Django makes nice job with security. See Django docs: docs.djangoproject.com/en/1.9/#security *businessPutput
According to this: t37.net/… it seems sendfile isn't essential when using nginx as a reverse proxy (which is what I'm doing). Hence, in my case should I solely set tcp_nopush on; and tcp_nodelay on; and keep sendfile off?Forewent
Acording to your config, you serve static files with NGINX, which is the right thing to do. And sendfile on; will help to do it faster due to less lowlevel work performed.Putput
Btw, the article on the link you provided says: "sendfile is useless for UNIX sockets" which you use for proxying, because they don't support this function. But it doesn't hurt them as well, because it will be just ignore in this case. So using sendfile on; will benefit you anyway. If you're really concerned about it you might decide to tryto move this directive to static files location block.Putput

© 2022 - 2024 — McMap. All rights reserved.