Категорії
FreeBSD Security

Защита от небольшого DDoS’a

Что имеем: есть сервер (8Гб памяти, Intel(R) Xeon(R) CPU E31220 @ 3.10GHz) FreeBSD 8.4 Release amd64, сайт на php5.2, nginx+apache+mysql.

Перейти полностью на php-fpm не получилось, поэтому пришлось защищаться как есть. Это поможет отразить небольшую syn flood атаку.

Ниже будет приведены выполненные действия для отражения атак.

1) Тюнинг sysctl.

/boot/loader.conf:

kern.ipc.nmbclusters=65535
net.inet.tcp.syncache.hashsize=1024
net.inet.tcp.syncache.bucketlimit=100
net.inet.tcp.tcbhashsize=4096

/etc/sysctl.conf:

vfs.usermount=0
security.bsd.see_other_uids=0
security.bsd.see_other_gids=0
security.bsd.hardlink_check_uid=1
security.bsd.hardlink_check_gid=1
security.bsd.conservative_signals=1
security.bsd.unprivileged_proc_debug=0
security.bsd.unprivileged_read_msgbuf=0
security.bsd.unprivileged_get_quota=0
kern.ipc.somaxconn=32768
kern.ipc.maxsockets=204800
kern.ipc.maxsockbuf=2097152
kern.maxfiles=204800
kern.maxfilesperproc=200000
kern.random.sys.harvest.ethernet=0
kern.random.sys.harvest.interrupt=0
kern.random.sys.harvest.point_to_point=0
net.link.ether.inet.max_age=1200
net.link.ether.inet.log_arp_movements=0
net.local.stream.sendspace=65536
net.local.stream.recvspace=65536
net.inet6.ip6.redirect=0
net.inet.ip.portrange.first=1024
net.inet.ip.portrange.last=65535
net.inet.ip.fw.dyn_max=8192
net.inet.ip.redirect=0
net.inet.ip.sourceroute=0
net.inet.ip.accept_sourceroute=0
net.inet.ip.ttl=128
net.inet.ip.random_id=1
net.inet.ip.intr_queue_maxlen=4096
net.inet.icmp.drop_redirect=1
net.inet.icmp.bmcastecho=0
net.inet.icmp.maskrepl=0
net.inet.icmp.icmplim=50
net.inet.icmp.log_redirect=0
net.inet.udp.recvspace=65536
net.inet.udp.maxdgram=57344
net.inet.tcp.blackhole=2
net.inet.udp.blackhole=1
net.inet.tcp.log_in_vain=0
net.inet.udp.log_in_vain=0
net.inet.tcp.sendspace=64395
net.inet.tcp.recvspace=64395
net.inet.tcp.drop_synfin=1
net.inet.tcp.syncookies=1
net.inet.tcp.rfc1323=1
net.inet.tcp.msl=15000
net.inet.tcp.icmp_may_rst=0
net.inet.tcp.sack.enable=0
net.inet.tcp.finwait2_timeout=20000
net.inet.tcp.fast_finwait2_recycle=1
net.inet.tcp.sendbuf_max=16777216
net.inet.tcp.recvbuf_max=16777216
net.inet.tcp.maxtcptw=40960
net.inet.tcp.sack.enable=0
net.inet.tcp.delayed_ack=0
net.inet.tcp.nolocaltimewait=1

2) Файервол.

Пришлось ограничить количество соединений с одного IP до 20 шт.

ipfw add check-state
...
ipfw add allow tcp from any to me 80, 443 limit src-addr 20 via ${LanOut}
ipfw add allow tcp from 10.0.0.0/8 to me 80, 443 via ${LanIn} # для локальных юзеров
ipfw deny tcp from any to me dst-port 80,443
...

3) Nginx

– GeoIP

Поскольку сайт был украиноязычным, то решено было внедрить GeoIP (nginx пришлось пересобрать с поддержкой этого модуля) и ограничить для UA, RU, US (для гуглоботов и прочих ботов bingo, yahoo,…).

Скачиваем свежие базы GeoIP и распаковываем:

#mkdir /usr/local/etc/nginx/geoip && cd /usr/local/etc/nginx/geoip
#fetch http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz && gunzip GeoIP.dat.gz
#fetch http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz && gunzip GeoLiteCity.dat.gz

Далее в /usr/local/etc/nginx/nginx.conf добавляем такой код в раздел http:

map $geoip_country_code $good_country {
default no;
UA yes;
RU yes;
US yes;
}

– nginx map

Что бы разрешить доступ юзерам из локалки нужно создать map для нужных IP’ок. Для этого добавляем такой код в /usr/local/etc/nginx/nginx.conf в раздел http:

geo $net_geo {
default 0;
10.0.0.0/8 yes;
127.0.0.0/8 yes;
}

– применение для сайта

Что бы применить настройки GeoIP + map для нашего сайта, добавляем такой код в раздел server:


set $GOOD 0;
map $good_country:$net_geo $GOOD {
"yes":"yes" '1';
default '0';
}
if ($GOOD = 0) {
return 444;
}

Или устаревший вариант:

set $GOOD 0;
if ($good_country = yes) {
set $GOOD 1;
}
if ($net_geo = yes) {
set $GOOD 1;
}
if ($GOOD = 0) {
return 444;
}

– прочие настройки для nginx

В секции server добавляем

worker_rlimit_nofile  200000;
events {
worker_connections 10240;
use kqueue;
}

В секции http добавляем

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
reset_timedout_connection on;
client_body_timeout 10;
client_header_timeout 10;
send_timeout 10;

4) Прочие.

Можно написать скрипт, который будет парсить netstat на предмет syn соединений с window size 0 и банить IP.

Так же полезно отключить access-логи в apache/nginx, если они не используются для какой-то статистики. Дополнительно можно установить кешер (APC, eAccelerator, …) и смонтировать папку с кешем как tmpfs. Для mysql tmp-папку тоже смонтировать в tmpfs.

Нашёл недавно ПО ( http://synflood-defender.net/docs ) типа для защиты от атак, но не сильно верю, что оно поможет ))

Можно попробовать поставить Varnish для кеширования страниц, особенно, если боты запрашивают одну и ту же.

5) Дополнительная блокировка через файервол

pf:

### block probes that can possibly determine our operating system by disallowing
### certain combinations that are commonly used by nmap, queso and xprobe2, who
### are attempting to fingerprint the server.
### * F : FIN  - Finish; end of session
### * S : SYN  - Synchronize; indicates request to start session
### * R : RST  - Reset; drop a connection
### * P : PUSH - Push; packet is sent immediately
### * A : ACK  - Acknowledgement
### * U : URG  - Urgent
### * E : ECE  - Explicit Congestion Notification Echo
### * W : CWR  - Congestion Window Reduced
block drop in quick on $ext_if proto tcp flags FUP/WEUAPRSF
block drop in quick on $ext_if proto tcp flags WEUAPRSF/WEUAPRSF
block drop in quick on $ext_if proto tcp flags SRAFU/WEUAPRSF
block drop in quick on $ext_if proto tcp flags /WEUAPRSF
block drop in quick on $ext_if proto tcp flags SR/SR
block drop in quick on $ext_if proto tcp flags SF/SF

ipfw:

ipfw add deny tcp from any to any in via $ext_if tcpflags fin, syn, rst, psh, ack, urg
ipfw add deny tcp from any to any in via $ext_if tcpflags !fin, !syn, !rst, !psh, !ack, !urg
ipfw add deny tcp from any to any in via $ext_if not established tcpflags fin
ipfw add deny tcp from any to any not verrevpath in via $ext_if 

Дополнение: неплохой пример блокировки через файервол pf на основе country code https://it-notes.dragas.net/2024/06/16/freebsd-blocking-country-access/

2 коментарі “Защита от небольшого DDoS’a”

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *

Домашняя страничка Andy
Записки молодого админа
Самостоятельная подготовка к Cisco CCNA
Самостоятельная подготовка к Cisco CCNP
Powered by Muff