Отбиваем небольшой http flood

Материал из poiuty wiki
Перейти к: навигация, поиск

Будем использовать iptables, geoip, nginx и fail2ban.

apt-get install fail2ban xtables-addons-common libtext-csv-xs-perl libxml-csv-perl libtext-csv-perl unzip geoip-bin

В случае с debian > 8 => apt-get автоматически установим модуль iptables geoip.
В случае с debian 7 => нужно дополнительно выполнить:

module-assistant auto-install xtables-addons-source

Если вы используете debian 7 + ядро из backports, то собирать нужно самому (из исходников).
На данный момент актуальная версия xtables-addons-2.10 (внимание для ядер < 3.7, нужно использовать xtables-addons-1.47.1)

cd /usr/src/ 
wget http://downloads.sourceforge.net/project/xtables-addons/Xtables-addons/xtables-addons-2.10.tar.xz
tar -xf xtables-addons-2.10.tar.xz
cd ./xtables-addons-2.10
./configure
make
make install
depmod -a
modprobe xt_geoip

Попробуем заблокировать Китай, и получим ошибку.

# iptables -I INPUT ! -i lo -m geoip --src-cc CN -j DROP
Could not open /usr/share/xt_geoip/LE/CN.iv4: No such file or directory
iptables v1.4.21: Could not read geoip database

Теперь нам нужно получить geoip database.

cd /usr/src/xtables-addons-2.10/geoip
mkdir /usr/share/xt_geoip
./xt_geoip_dl
./xt_geoip_build -D /usr/share/xt_geoip *.csv

Снова пробуем заблокировать Китай.

# iptables -I INPUT ! -i lo -m geoip --src-cc CN -j DROP
# iptables -L -v -n
Chain INPUT (policy ACCEPT 22161 packets, 5339K bytes)
 pkts bytes target     prot opt in     out     source               destination         
   14  2147 DROP       all  --  !lo    *       0.0.0.0/0            0.0.0.0/0            -m geoip --source-country CN 

Посмотрим, откуда идет http flood => China, United States, Venezuela и т.д.

# for ip in `cat /var/log/nginx/access.log | awk '{print $1}'`; do geoiplookup $ip; done | sort | uniq -c | sort -rn > /root/ips.logБ
    973 GeoIP Country Edition: CN, China
    490 GeoIP Country Edition: RU, Russian Federation
    356 GeoIP Country Edition: US, United States
    346 GeoIP Country Edition: IP Address not found
    250 GeoIP Country Edition: VE, Venezuela
    245 GeoIP Country Edition: BR, Brazil
    171 GeoIP Country Edition: ID, Indonesia
    124 GeoIP Country Edition: UA, Ukraine
     84 GeoIP Country Edition: TH, Thailand
     73 GeoIP Country Edition: IR, Iran, Islamic Republic of
     59 GeoIP Country Edition: KR, Korea, Republic of
     58 GeoIP Country Edition: IN, India
     55 GeoIP Country Edition: RO, Romania
     53 GeoIP Country Edition: JP, Japan
     51 GeoIP Country Edition: GB, United Kingdom
     49 GeoIP Country Edition: CO, Colombia
     48 GeoIP Country Edition: TW, Taiwan
     48 GeoIP Country Edition: AR, Argentina
     43 GeoIP Country Edition: BD, Bangladesh
     42 GeoIP Country Edition: HK, Hong Kong
     36 GeoIP Country Edition: MX, Mexico
     34 GeoIP Country Edition: CH, Switzerland
     31 GeoIP Country Edition: IT, Italy
     30 GeoIP Country Edition: CZ, Czech Republic
     29 GeoIP Country Edition: TR, Turkey
     29 GeoIP Country Edition: PL, Poland
     25 GeoIP Country Edition: CA, Canada
     24 GeoIP Country Edition: ZA, South Africa
     22 GeoIP Country Edition: SE, Sweden
     22 GeoIP Country Edition: PK, Pakistan
     21 GeoIP Country Edition: VN, Vietnam

Сайт рас читан на русскоязычную аудиторию => сделаем белый список (коды стран смотрите тут)

iptables -I INPUT ! -i lo -p tcp --dport 80 -m geoip ! --src-cc RU,BY,UA,KZ,UZ,LT,LV,KG,GE,AM,TJ,DE -j DROP

Дополнительно посмотрим какие запросы приходили от ботов.

161.68.250.69 - - [06/Feb/2016:16:58:43 -0500] "POST /forums/index.php HTTP/1.0" 200 35122 "-" "Mozilla/4.0 (compatible; Synapse)"
23.244.43.146 - - [06/Feb/2016:16:58:43 -0500] "POST /forums/index.php HTTP/1.0" 503 206 "-" "Mozilla/4.0 (compatible; Synapse)"
82.209.248.78 - - [06/Feb/2016:16:58:57 -0500] "GET /forums/index.php HTTP/1.1" 502 166 "-" "Mozilla/4.0 (compatible; Synapse)"
217.25.209.34 - - [06/Feb/2016:16:58:58 -0500] "GET /forums/index.php HTTP/1.0" 502 166 "-" "Mozilla/4.0 (compatible; Synapse)"

Synapse заблокируем их на iptables.

iptables -A INPUT -p tcp --dport 80 -m string --string 'Synapse' --algo bm -j DROP

Добавляем правила iptables в автозагрузку => редактируем /etc/rc.local до exit 0

modprobe xt_geoip
iptables -A INPUT ! -i lo -p tcp --dport 80 -m geoip ! --src-cc RU,BY,UA,KZ,UZ,LT,LV,KG,GE,AM,TJ,DE -j DROP
iptables -A INPUT -p tcp --dport 80 -m string --string 'Synapse' --algo bm -j DROP

exit 0

Дополнительно отфильтруем на fail2ban. Создаем /etc/fail2ban/filter.d/nginx-post-flood.conf

[Definition]
failregex = ^<HOST> .* "POST
ignoreregex =

Создаем /etc/fail2ban/filter.d/nginx-conn-limit.conf

# Fail2Ban configuration file
#
# supports: http_limit_zone module
 
[Definition]
 
failregex = limiting connections by zone.*client: <HOST>
 
# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex =

Редактируем /etc/fail2ban/jail.conf

[nginx-conn-limit]

enabled = true
filter = nginx-conn-limit
action = iptables-multiport[name=nginxConnLimit, port="http,https", protocol=tcp]
logpath = /var/log/nginx/error.log
findtime = 300
bantime = 14400
maxretry = 100

[nginx-post-flood]

enabled = true
filter = nginx-post-flood
action = iptables-multiport[name=nginxPOST, port="http,https", protocol=tcp]
logpath = /var/log/nginx/access.log
findtime = 300
bantime = 14400
maxretry = 100

Чтобы правила fail2ban были *ниже* наших => редактируем /etc/fail2ban/action.d/iptables-multiport.conf

actionstart = iptables -N fail2ban-<name>
              iptables -A fail2ban-<name> -j RETURN
              iptables -A <chain> -p <protocol> -m multiport --dports <port> -j fail2ban-<name>

Редактируем конфиг nginx => /etc/nginx/nginx.conf

http{
...
limit_conn_zone   $binary_remote_addr  zone=addr:10m;
...
server{
limit_conn addr 5;
...

Перезагружаем nginx, fail2ban

/etc/init.d/nginx restart
/etc/init.d/fail2ban restart