FreeBSD, network card: Intel fxp, port: 100Мбит, polling, http accept-filter.
in sysctl:
sysctl kern.maxfiles=90000 sysctl kern.maxfilesperproc=80000 sysctl net.inet.tcp.blackhole=2 sysctl net.inet.udp.blackhole=1 sysctl kern.polling.burst_max=1000 sysctl kern.polling.each_burst=50 sysctl kern.ipc.somaxconn=32768 sysctl net.inet.tcp.msl=3000 sysctl net.inet.tcp.maxtcptw=40960 sysctl net.inet.tcp.nolocaltimewait=1 sysctl net.inet.ip.portrange.first=1024 sysctl net.inet.ip.portrange.last=65535 sysctl net.inet.ip.portrange.randomized=0
in nginx configuration:
worker_processes 1; worker_rlimit_nofile 80000; events { worker_connections 50000; } server_tokens off; log_format IP `$remote_addr'; reset_timedout_connection on; listen xx.xx.xx.xx:80 default rcvbuf=8192 sndbuf=16384 backlog=32000 accept_filter=httpready;
In the following way it is possible to realize filtration of url, in example for POST
index.php?action=login which is with empty referral.
set $add 1; location /index.php { limit_except GET POST { deny all; } set $ban ""; if ($http_referer = "" ) {set $ban $ban$add;} if ($request_method = POST ) {set $ban $ban$add;} if ($query_string = "action=login" ){set $ban $ban$add;} if ($ban = 111 ) { access_log /var/log/[133]nginx/ban IP; return 404; } proxy_pass http://127.0.0.1:8000; #here is a patch }
Further we cut it at pf level – loaded into IP table, hosts from which came too many hits.
PF with tables works very quickly. Sources for parsing of logs (ddetect) you can find on http://www.comsys.com.ua/files
Then Cron used once in a minute, to add into ip tables new IPs from a log.
25 Mbyte DDoS, which cuts IPs, the rests fall on nginx which by it is criterion pass IPs and the rests passed on the apache – LA 0, site works.