Hoşgeldin Misafir

Nginx Ddos Engelleme Configuration

CyberHawk

CyberHawk

WebMaster
Adana
12 Ara 2018
16,070 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
before-limit.jpg


before-limit.jpg

Nginx Config:
Kod:
nano /etc/nginx/nginx.conf

Nginx Ddos Configuration:
Kod:
limit_req_zone $binary_remote_addr zone=limited:10m rate=5r/s;

İşlemimiz Bukadar Biraz Daha Gelişmiş Halini Alta Paylaşıyorum İncelemeniz İçin..
Kod:
# -----------------------------------------------------------------------------
# NGINX NOTLARI
# -----------------------------------------------------------------------------
Notların çoğu Debian Jessie ve nginx-extras paketi kullanıldığı düşünülerek
hazırlandı. Eski sürümlerde bazı özellikler mevcut değil.

# Kurulum
  apt-get install nginx-extras

# Config test
  /etc/init.d/nginx configtest


# -----------------------------------------------------------------------------
# NGINX + PHP
# -----------------------------------------------------------------------------

# Kurulum
  apt-get install php5-fpm

# /etc/php5/fpm/pool.d/www.conf
  pm.max_children = 50
  pm.start_servers = 20
  pm.min_spare_servers = 10
  pm.max_spare_servers = 30
  pm.max_requests = 500

# /etc/nginx/conf.d/custom.conf
  large_client_header_buffers 8 128k;
  proxy_hide_header X-Powered-By;
  server_tokens off;

# /etc/nginx/conf.d/cache.conf
  fastcgi_cache_path /var/cache/nginx_fastcgi levels=1:2 keys_zone=fcache:64m inactive=60m;
  fastcgi_temp_path /var/cache/nginx_fastcgi/tmp;
  fastcgi_cache_key "$host$request_uri";
  fastcgi_cache_lock on; 
  fastcgi_cache_use_stale error timeout invalid_header updating http_500 http_503

# /etc/nginx/sites-available/site.conf
  set $skip_cache 0;

  # Cachelenmeyecek bolumler.
  if ($request_uri ˜* "/(path1|path2)") {
      set $skip_cache 1; }

  # Fiziksel olarak var olan dosyalar static dosya olarak sunulacak.
  ******** / {
      try_files $uri $uri/ /index.php?$request_uri;

      add_header Pragma public;
      add_header Cache-Control "public, must-revalidate, proxy-revalidate";

      add_header X-Powered-By "www.emrah.com";
      add_header X-Host $host;
      add_header X-Node "default";
      expires max; }

  # PHP dosyalari ve framework pathleri bu bloktan sunulacak.
  ******** ˜ \.php {
      include snippets/fastcgi-php.conf;
      fastcgi_pass unix:/var/run/php5-fpm.sock;
      fastcgi_buffer_size 64k;
      fastcgi_buffers 8 64k;
      fastcgi_busy_buffers_size 64k;

      fastcgi_cache fcache;
      fastcgi_cache_bypass $skip_cache;
      fastcgi_no_cache $skip_cache;
      fastcgi_cache_valid 60s;
      fastcgi_cache_valid any 30s;
      fastcgi_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;
      expires 300;

      add_header X-Powered-By "www.emrah.com";
      add_header X-Cache $upstream_cache_status;
      add_header X-Status $upstream_status;
      add_header X-Time $upstream_response_time;
      add_header X-Upstream $hostname;
      add_header X-Backend $upstream_addr;
      add_header X-Node "php;
      add_header X-Worker $pid; }


# -----------------------------------------------------------------------------
# NGINX + UWSGI
# -----------------------------------------------------------------------------

# Kurulum
  apt-get install uwsgi uwsgi-plugin-python

# Basit bir Python Uygulaması
/home/kullanici/wsgi/myapp.py
  #!/usr/bin/python
  #-*- coding: utf-8 -*-

  from cgi import parse_qs

  def application(environ, start_response):
      args = parse_qs(env['wsgi.input'].read())
      status = '200 OK'
      output = 'Hello World'

      response_headers = [('Content-type', 'text/plain'),
                           ('Content-Length', str(len(output)))]
      start_response(status, response_headers)
      return [output]


# UWSGI ayarları
/etc/uwsgi/apps-available/myapp.ini
  [uwsgi]
  plugins = python
  uid = emrah
  gid = www-data
  socket = /var/run/uwsgi/app/myapp.socket
  wsgi-file = /home/kullanici/wsgi/myapp.py


cd /etc/uwsgi/apps-enabled
ln -s ../apps-available/myapp.ini .
/etc/init.d/uwsgi restart


# Nginx ayarları
/etc/nginx/sites-enabled/default
  ******** /myapp {
      include uwsgi_params;
      uwsgi_pass unix:/var/run/uwsgi/app/myapp.socket;
  }

/etc/init.d/nginx restart


# -----------------------------------------------------------------------------
# NGINX + LUA
# -----------------------------------------------------------------------------
Lua ile örnek access control.

# /etc/nginx/default
  server {
      ...
      ...

      ******** /forbidden.html {
          expires -1;
      }

      ******** / {
          access_by_lua_file /path/to/file.lua;
          ...
          ...
      }
  }

# /path/to/file.lua
  headers = ngx.req.get_headers()
  if headers["Host"] == "localhost" then
      ngx.log(ngx.ERR, "localhost is forbidden")
      ngx.exec("/forbidden.html")
      -- ngx.exit(ngx.HTTP_FORBIDDEN)
  else
      return
  end

# test
  curl http://localhost/
  curl http://127.0.0.1/


# -----------------------------------------------------------------------------
# CACHE PURGE
# -----------------------------------------------------------------------------
Key olarak "$host/$1" kullanıldığı farzedildi.
Bu özellik sadece commercial sürümde olabilir.

# sites-available/site.conf
  ******** ˜ /purge/(.*) {
      fastcgi_cache_purge fcache "$host/$1"; }


# -----------------------------------------------------------------------------
# CACHE BYPASS
# -----------------------------------------------------------------------------
Cache bypass edilince içeriği güncellenir. Purge kullanılmaya gerek kalmıyor.

# Query string ile
proxy_cache_bypass $arg_nocache;

curl http://site.com/?nocache=1


# Header ile
proxy_cache_bypass $http_nocache;

curl http://site.com/ -H "nocache: true"



# -----------------------------------------------------------------------------
# CACHE MOBILE
# -----------------------------------------------------------------------------
http://detectmobilebrowsers.com/ sitesinde "nginx" bölümünde güncel kod yer
almakta.


# Desktop
set $mobile "D";

# Mobile
if ($http_user_agent ˜* "(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino") {
  set $mobile "M";
}

# Mobile
if ($http_user_agent ˜* "ˆ(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-)") {
  set $mobile "M";
}

******** ... {
  ...
  proxy_cache_key "$host$request_uri$mobile";
  ...
}



# -----------------------------------------------------------------------------
# REQUEST LIMIT
# -----------------------------------------------------------------------------
Belli bir IP adresinden birim zamanda gelen talep sayısı sınırlandırılabilir.

# /etc/nginx/conf.d/limit.conf
limit_req_zone $binary_remote_addr zone=limited:10m rate=1r/s;

Proxy arkasında ise key olarak $binary_remote_addr yerine $http_x_real_ip
değeri kullanılabilir. Duruma göre key olarak IP adresinden başka bir şey de
verilebilir.

Talep oranını belirtmek için r/s ve r/m seçenekleri var. Eğer 2 saniyede 1 adet
talep izni verilmek isteniyorsa 30 r/s değeri kullanılır.

# Limitlenecek server/******** için
limit_req zone=limited burst=5;

Talep oranı aşıldığında burst adedi kadar talep kuyrukta bekletilir ve talep
oranına uygun şekilde cevaplar gönderilir. Cevap bekleyen talep adedi, burst
değerini aşarsa bunlar için 503 döner.

# nodelay
limit_req zone=limited burst=5 nodelay;

503 (service temporary unavailable) cevapları bekletilmeden hemen gönderilmek
isteniyorsa nodelay parametresi kullanılır.



# -----------------------------------------------------------------------------
# TALEBİ BEKLETME
# -----------------------------------------------------------------------------
Talep edilen dosya henüz yoksa bir müddet bekleme yapıp dosyayı yeniden isteme.
Talep anında dinamik olarak oluşturulan dosyalar için kullanılabilir.

******** /temp/images {
  try_files $uri @delay;

  add_header Pragma public;
  add_header Cache-Control "public, must-revalidate, proxy-revalidate";

  add_header X-Powered-By "www.emrah.com";
  add_header X-Host $host;
  add_header X-Node "png";
  expires max; }

******** @delay {
  echo_sleep 5;
  echo_exec /delay$uri; }

******** /delay {
  alias /var/www;

  add_header Pragma public;
  add_header Cache-Control "public, must-revalidate, proxy-revalidate";

  add_header X-Powered-By "www.emrah.com";
  add_header X-Host $host;
  add_header X-Node "delay";
  expires max; }


# -----------------------------------------------------------------------------
# TALEBİ BEKLETME (LUA İLE)
# -----------------------------------------------------------------------------
Talep edilen dosya oluşana kadar redirect yapılıyor. Her redirect öncesi bir
müddet bekletiliyor. 10 kere istendikten sonra hala dosya oluşmamışsa 404
döndürülüyor.

# Bu ********'da HTML'den uretilen resimler yer alir. Ilk talep geldigi esnada
# resim dosyasi henuz hazirlanmamis olabilir. Bu nedenle resim dosyasi henuz
# yoksa talep, @delay bloguna gonderilip bir muddet bekletiliyor ve daha sonra
# resim tekrar web sunucudan isteniyor.
******** /temp/images {
      try_files $uri @delay;

      add_header Pragma public;
      add_header Cache-Control "public, must-revalidate, proxy-revalidate";

      add_header X-Powered-By "www.emrah.com";
      add_header X-Host $host;
      add_header X-Node "png";
      expires max; }

# Beklemeyi yaptiran blok. Bekleme sonunda resim, sunucudan tekrar isteniyor.
# Eger resim 10 kere istenmis olmasina ragmen hala olusmadiysa "404 NOT FOUND"
# donduruluyor.
******** @delay {
      set $step "$arg_step";

      rewrite_by_lua '
              local res = ngx.********.capture("/delay")
              local uri = "http://" .. ngx.var.host .. ngx.var.uri

              if ngx.var.step == "" then
                      ngx.var.step = 0
              else
                      ngx.var.step = tonumber(ngx.var.step) + 1
              end

              if tonumber(ngx.var.step) < 10 then
                      uri = uri .. "?step=" .. ngx.var.step
                      return ngx.redirect(uri, 302)
              else
                      return ngx.HTTP_NOT_FOUND
              end
      '; }

# Bu sanal ********, sadece @delay blogundan yapilan sunucu ici yonlendirmeler
# ile kullanilir. 302 redirectten once bir muddet bekleme yaptirmak icin
# kullaniliyor.
******** /delay {
      echo_sleep 0.8; }



# -----------------------------------------------------------------------------
# NGINX DEBUG
# -----------------------------------------------------------------------------

# Kurulum
Debug için derlenmiş paket kurulacak. Örneğin nginx-extras yerine
nginx-extras-dbg paketi...

apt-get install nginx-extras-dbg

# Debug ile ilgili ayarlar
/etc/nginx/nginx
  worker_rlimit_core  500M;
  working_directory /var/tmp/cores/;

  error_log /var/log/nginx/error.log debug;

mkdir /var/tmp/cores
chown www-data: /var/tmp/cores
systemctl restart nginx

# coredump inceleme
dmesg çıktısında Nginx tarafından oluşturulmuş segfault satırı varsa

gdb /usr/sbin/nginx /var/tmp/cores/core
  set logging on backtrace1.log
  backtrace full

# Debug logları
error.log dosyasından görülebilir.

# Kaynak
http://wiki.nginx.org/Debugging



# -----------------------------------------------------------------------------
# CONF.D/
# -----------------------------------------------------------------------------
# upstream.conf
upstream cache {
  server 10.10.10.1;
  server 10.10.10.2;
  keepalive 24;
}

upstream apache {
  server 127.0.0.1:8080;
  keepalive 24;
}


# limit.conf
limit_req_zone $binary_remote_addr zone=limited:10m rate=5r/s;


# custom.conf
server_tokens off;
autoindex off;
large_client_header_buffers 8 128k;


# proxy.conf
proxy_http_version 1.1;
proxy_connect_timeout 3;
proxy_read_timeout 30;

proxy_set_header Connection "";
proxy_set_header X-Real-IP  $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header X-Powered-By;


# proxy_cache.conf
proxy_cache_path /var/cache/nginx_proxy levels=1:2 keys_zone=pcache:64m inactive=60m;
proxy_temp_path /var/cache/nginx_proxy/tmp;
proxy_cache_lock on;
proxy_cache_bypass $http_nocache;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;


# proxy_buffer.conf
proxy_buffer_size 64k;
proxy_buffers 8 64k;
proxy_busy_buffers_size 64k;



# -----------------------------------------------------------------------------
# KAYNAKLAR
# -----------------------------------------------------------------------------
http://nginx.org/en/docs/

Örnek Nginx Config:
Kod:
user www-data www-data;
worker_processes 10;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
sendfile on;
#keepalive_timeout 0;
keepalive_timeout 5;
tcp_nodelay on;
gzip on;
limit_req_zone $binary_remote_addr zone=antiddosphp:10m rate=1r/s;
limit_req_zone $binary_remote_addr zone=antiddos:10m rate=10r/s;
include /etc/nginx/mustafat/*;
}
virtualhost.conf 
server {
root /home/www-data/gsxx.com;
listen 80;
server_name gsxx.com;
access_log off;
******** / {
index index.php index.html index.htm;
limit_req zone=antiddos burst=10;
}
******** ~ \.php$ {
fastcgi_pass unix:/tmp/php-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $********_root$fastcgi_script_name;
fastcgi_read_timeout 1800;
fastcgi_param SERVER_NAME $http_host;
fastcgi_ignore_client_abort on;
limit_req zone=antiddosphp burst=2;
}
}