Why Your IPtables Anti-DDoS Rules Suck
To understand why your current iptables rules to prevent DDoS attacks suck, we first have to dig into how iptables works.
iptables is a command line tool used to set up and control the tables of IP packet filter rules. There are different tables for different purposes.
IPtables Tables
Filter: The filter table is the default and most commonly used table that rules go to if you don’t use the -t (–table) option.
NAT: This table is used for Network Address Translation (NAT). If a packet creates a new connection, the nat table gets checked for rules.
Mangle: The mangle table is used to modify or mark packets and their header information.
Raw: This table’s purpose is mainly to exclude certain packets from connection tracking using the NOTRACK target.
As you can see there are four different tables on an average Linux system that doesn’t have non-standard kernel modules loaded. Each of these tables supports a different set of iptables chains.
IPtables Chains
PREROUTING: raw, nat, mangle
Applies to packets that enter the network interface card (NIC)
INPUT: filter, mangle
Applies to packets destined to a local socket
FORWARD: filter, mangle
Applies to packets that are being routed through the server
OUTPUT: raw, filter, nat, mangle
Applies to packets that the server sends (locally generated)
POSTROUTING: nat, mangle
Applies to packets that leave the server
Depending on what kind of packets you want to block or modify, you select a certain iptables table and a chain that the selected table supports.
Of course, we’re still missing an explanation of iptables targets (ACCEPT, DROP, REJECT, etc.), but we’re assuming that if you’re reading this article, you already know how to deal with iptables.
We’re going to explain why your iptables rules suck to stop DDoS and not teach you how to use iptables. Let’s get back to that.
If you want to block a DDoS attack with iptables, performance of the iptables rules is extremely important. Most TCP-based DDoS attack types use a high packet rate, meaning the sheer number of packets per second is what causes the server to go down.
That’s why you want to make sure that you can process and block as many packets per second as possible.
You’ll find that most if not all guides on how to block DDoS attacks using iptables use the filter table and the INPUT chain for anti-DDoS rules.
The issue with this approach is that the INPUT chain is only processed after the PREROUTING and FORWARD chains and therefore only applies if the packet doesn’t match any of these two chains.
This causes a delay in the filtering of the packet which consumes resources. In conclusion, to make our rules as effective as possible, we need to move our anti-DDoS rules as far up the chains as possible.
The first chain that can apply to a packet is the PREROUTING chain, so ideally we’ll want to filter the bad packets in this chain already.
However, the filter table doesn’t support the PREROUTING chain. To get around this problem, we can simply use the mangle table instead of the filter table for our anti-DDoS iptables rules.
It supports most if not all rules that the filter table supports while also supporting all iptables chains.
So you want to know why your iptables DDoS protection rules suck? It’s because you use the filter table and the INPUT chain to block the bad packets!
The best solution to dramatically increase the performance of your iptables rules and therefore the amount of (TCP) DDoS attack traffic they can filter is to use the mangle table and the PREROUTING chain!
Файловый сервер
FTP-сервер Linux может понадобиться для обмена документами и загрузки файлов. Существует несколько версий таких ресурсов: vsFTPd, Samba, proFTPd.
Подробнее остановимся на vsFTPd. Его можно установить и запустить одной командой — «sudo apt-get install vsftpd». Дальнейшие настройки зависят от ваших предпочтений и от того, какой сервис вы хотите сделать. Для изменения параметров могут понадобиться права администратора.
Команда «sudo apt-get install vsftpd»
- Сразу после загрузки программы система создаёт нового пользователя и добавляет в домашнюю директорию папку, которая предназначена для работы с серверным хранилищем. Также в каталоге «etc» появляется файл «ftpusers». Туда можно добавлять пользователей, которым запрещён доступ к файлам.
- После установки лучше сменить директорию, в которой должны находиться файлы, в папку «var». Для этого от имени администратора напишите команду «usermod -d /var/ftp ftp && rmdir /home/ftp».
- Создайте новую группу пользователей. Например, «userftp». Напечатайте в консоли «addgroup userftp».
- Добавьте в неё новый аккаунт (для простоты назовём пользователя и группу одинаково). Используйте команду «useradd -a /var/ftp -g userftp userftp». Она заодно создаёт пользователя. Чтобы включить в группу уже существующий никнейм, вместо «useradd» напишите «usermod».
- Надо придумать пароль новому пользователю. Введите в терминале «passwd userftp».
- Напечатайте «chmod 555 /var/ftp && chown root:userftp /var/ftp», чтобы предоставить аккаунту доступ к корневой папке файлового сервера.
- Теперь создайте публичную директорию. Последовательно введите «mkdir /var/ftp/pub» и «chown userftp:userftp /var/ftp/pub».
Изначально FTP запускается в автономном режиме. У неё есть скрипт, который играет роль демона. При такой функциональности доступно несколько команд. Они вводятся после строки «sudo service vsftpd».
Команда «sudo service vsftpd»
- Stop и Start. Отключение и включение.
- Restart и Reload. Перезапуск. Нужен для применения новых настроек. Разница между командами в том, что во второй перезагрузка происходит без полного отключения.
- Status. Информация о состоянии.
Дальнейшая настройка сервера заключается в переписывании файла конфигурации, который находится в etc/vsftpd.conf. У него простая и понятная структура. Разобраться в нём достаточно просто. Хотя для этого нужны определённые знания. Перед изменением этого файла имеет смысл сделать его резервную копию. Чтобы в случае выявления ошибок можно было всё восстановить. Введите команду «cp /etc/vsftpd.conf /etc/vsftpd_old.conf» и информация будет сохранена.
После этого можно приступать к редактированию.
- В параметре «listen=» напишите «YES». Тогда сервер будет работать в независимом режиме.
- «Local_enable» разрешает вход локальным пользователям.
- «Write_enable» даёт им доступ в домашние каталоги.
- «Anonymous_enable». Можно ограничить права анонимных пользователей, если поставить «NO». Также есть опция «no_anon_password» — анонимные входят без пароля. Её тоже можно запретить.
Если вы хотите делать публичный сервер, то после строки «listen» надо добавить несколько дополнительных параметров.
- «Max_clients». Количество одновременных соединений.
- «Idle_session_timeout» и «data_connection_timeout». Таймауты сессии.
- «Ftpd_banner». Приветственное сообщение для посетителей. Можно написать, к примеру, «Hello!».
Анализ лог файла web сервера для защиты от ddos
Рассмотрим еще один простой, но все же более сложный тип ддос атаки, когда идут типовые запросы с разных IP. То есть простой ботнет, может быть даже собранный руками из нескольких дешевых vds серверов. Одновременных подключений будет не много, но если у вас тяжелый сайт и злоумышленник найдет его слабое место (например поиск), то этого может быть достаточно, чтобы положить сайт.
Банить будем тоже через iptables, а список адресов для бана будем извлекать из логов веб сервера. Для этого у вас должно быть включено логирование запросов к веб серверу. Например, в nginx за это отвечает такая настройка виртуального хоста:
access_log /web/sites/hl.zeroxzed.ru/log/access.log main;
Мы не будем каждый раз анализировать весь лог файл. Эта операция сама по себе будет сильно нагружать веб сервер. Возьмем последние 1000 строк из лог файла и посчитаем количество подключений с одного ip с типовым содержимым, например запрос главной страницы по протоколу http 1.0, «GET / HTTP/1.0». Если вы заметите другой постоянный признак ботнета, который вас атакует, используйте его. Это может быть один и тот же user agent или что-то еще. Допустим, если атакующий будет долбить в уязвимое место, то это будет адрес этой страницы.
# tail -1000 /web/sites/hl.zeroxzed.ru/log/ssl-access.log | egrep "GET / HTTP/1.0" | awk '{print $1}' | sort -n | uniq -c
Результатом этой команды будет примерно такой список.
В данном случае я использовал немного другое условие и просто вывел список всех тех, кто стучался на главную страницу. Но уже тут видно нарушителя, которого можно забанить.
#!/bin/sh tail -1000 /web/sites/hl.zeroxzed.ru/log/ssl-access.log | egrep "GET / HTTP/1.0" | awk '{print $1}' | sort -n | uniq -c | sort -n | tail -n100 | awk '{if ($1 > 50 ) print $2}' > /root/ddos/much_gets.txt sleep 3 list=$(cat /root/ddos/much_gets.txt) for ipnet in $list do ipset -A much_gets $ipnet done
Здесь делаем то же самое, что и раньше. Те, кто сделали более 50-ти одинаковых запросов по нашей маске на последние 1000 строк в лог файле, отправляются в бан.
Обращаю внимание на строку, по которой вы будете фильтровать запросы. В данном случае я показал только пример
Не надо брать и применять в том виде, как я показываю. Я демонстрирую технические возможности и подход. Настраивать и калибровать систему вам нужно у себя по месту
Важно это понимать и не применять решение бездумно. Будет только вред.
Не забудьте создать отдельный список в ipset и добавить отдельное правило в ipables. Можно использовать уже существующий список и добавленное правило из предыдущего примера, но я рекомендую все разделять. Так удобнее для последующего анализа.
Во время ddos атаки добавляете это правило в cron и выполняете каждую минуту. После завершения атаки скрипт можно отключить. В принципе, можно и на постоянку оставлять, но тут нужно хорошенько подумать и прикинуть, как оно должно выглядеть. Главный принцип — не навредить.
Технические подробности
Для работы защиты используется модуль ngx_http_limit_req_module, который позволяет ограничить скорость обработки запросов по заданному ключу или запросов, поступающих с одного IP-адреса.
Принципы работы модуля
Модуль для каждого домена с защитой создаёт зону разделяемой памяти (zone) и указывает максимальный размер всплеска запросов (burst). Если количество поступающих запросов превышает ограничение для зоны, то их обработка задерживается. Избыточные запросы задерживаются, пока их количество не превысит максимальный размер всплеска. При его превышении запрос завершается с ошибкой 503 (Service Temporarily Unavailable).
Настройки записываются в <путь к директории Nginx>/conf.d/isplimitreq.conf:
Конфигурационный файл nginx
limit_req_zone $binary_remote_addr zone=<имя WWW-домена>:<размер зоны> rate=<количество запросов в секунду>r/s
Пояснения
Размер зоны рассчитывается по формуле:
Формула для расчёта размера зоны
<количество запросов в секунду> * 64k
Например, если Количество запросов в секунду = 500, то размер зоны будет равен 500 * 64k, т.е. 32000k.
в <путь к директории Nginx>/vhosts-resources/<имя домена>:
Конфигурационный файл nginx
limit_req zone=<имя WWW-домена> burst=<максимальный размер всплеска>; error_page 503 =429 @blacklist;
Пояснения
@blacklist — секция location, в которую выполняется перенаправление при срабатывании ошибки 503, т.е. при превышении максимального количества запросов с IP-адреса.
Секция location @blacklist создаётся в <путь к директории Nginx>/vhosts-includes/blacklist-nginx.conf с содержимым вида:
Конфигурационный файл nginx
location @blacklist { proxy_redirect off ; proxy_pass https://<IP-адрес>:<порт>; rewrite (.*) /mancgi/ddos break; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X_ISP_FIREWALLSEC <ключ для ISPmanager>;
Пояснения
<IP-адрес> — адрес сервера с ISPmanager, который слушает ihttpd. Если ihttpd слушает любой корректный адрес сервера, то IP-адрес выбирается произвольно.
<порт> — порт, который слушает ihttpd.
Блокировка IP-адресов
При превышении максимального количества запросов:
- IP-адрес, с которого они поступают, передаётся в скрипт /mancgi/ddos. Скрипт вносит адрес в список заблокированных на 5 минут.
-
Блокировка выполняется с помощью iptables для IPv4, ip6tables для IPv6 и ipset.
В iptables создаётся правило:
iptables
DROP all -- anywhere anywhere match-set ispmgr_limit_req src
В ip6tables создаётся правило:
ip6tables
DROP all -- anywhere anywhere match-set ispmgr_limit_req6 src
В ipset создаются два набора (ispmgr_limit_req и ispmgr_limit_req6) с параметрами: hash:ip (IP-адрес) и timeout 300 (время блокировки в секундах).
-
При блокировке в журнал /usr/local/mgr5/var/ddos.log добавляется запись:
Журнал блокировок
WARNING Address (<IP-адрес>) is blacklisted
-
Чтобы проверить содержимое списка, выполните команду:
ipset -L ispmgr_limit_req
В выводе команды в поле «Members» указываются все адреса из списка блокировки и время до её окончания.
Изменение блокировки
Чтобы изменить период, на который блокируются IP-адреса:
-
Добавьте в manager (по умолчанию /usr/local/mgr5/etc/ispmgr.conf) параметр:
Конфигурационный файл ISPmanager
isp_limitreq_timeout <период блокировки в секундах>
-
Определите в iptables номер правила ispmgr_limit_req src:
iptables -L INPUT --line-number
-
Удалите это правило:
iptables -D INPUT <номер правила>
-
Определите в ip6tables номер правила ispmgr_limit_req6 src:
ip6tables -L INPUT --line-number
-
Удалите это правило:
ip6tables -D INPUT <номер правила>
-
Удалить правила из ipset:
ipset destroy ispmgr_limit_req ipset destroy ispmgr_limit_req6
-
Обновите правила брандмауэра ISPmanager:
/usr/local/mgr5/sbin/mgrctl -m ispmgr firewall
Debian: борьба с DDoS
По умолчанию ОС Debian и другие ОС не в состоянии поддерживать огромное количество соединений создаваемое ботнетом. Необходимо внести изменения в настройки ядра, чтобы укрепить стек TCP/IP. Пример такой конфигурации:
net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.eth0.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.core.rmem_max = 996777216 net.core.wmem_max = 996777216 net.ipv4.tcp_rmem = 4096 87380 4194304 net.ipv4.tcp_mem= 786432 1048576 996777216 net.ipv4.tcp_wmem = 4096 87380 4194304 net.ipv4.tcp_max_orphans = 2255360 net.core.netdev_max_backlog = 10000 net.ipv4.tcp_fin_timeout = 10 net.ipv4.tcp_keepalive_intvl = 15 net.ipv4.tcp_max_syn_backlog = 2048 net.ipv4.tcp_synack_retries = 1 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.shmmax = 494967295 kernel.shmall = 268435456 net.core.somaxconn= 16096
Аккуратно меняем конфигурацию ядра и перезагружаем сервер…
FreeBSD: борьба с DDoS
Уменьшаем время ожидания ответного пакета на запрос SYN-ACK (защита от SYN-флуда):
# sysctl net.inet.tcp.msl=7500
Превращаем сервер в черную дыру. Так ядро не будет слать ответные пакеты при попытке подключиться к незанятым портам (снижает нагрузку на машину во время DDoS’а на случайные порты):
# sysctl net.inet.tcp.blackhole=2 # sysctl net.inet.udp.blackhole=1
Ограничиваем число ответов на ICMP-сообщения 50-ю в секунду (защита от ICMP-флуда):
# sysctl net.inet.icmp.icmplim=50
Увеличиваем максимальное количество подключений к серверу (защита от всех видов DDoS):
# sysctl kern.ipc.somaxconn=32768
Включаем DEVICE_POLLING — самостоятельный опрос сетевого драйвера ядром на высоких нагрузках (существенно снижает нагрузку на систему во время DDoS’а):
Пересобираем ядро с опцией «options DEVICE_POLLING»;
Активируем механизм поллинга: «sysctl kern.polling.enable=1»;
Добавляем запись «kern.polling.enable=1» в /etc/sysctl.conf.
-
FreeBSD для обслуживания 100-200 тысяч соединений
- Методы защиты от DDoS нападений — попробовать скрипт написать по tcpdump
-
ANTI DDOS. ЗАЩИТА ОТ DDOS
Универсальные советы
Чтобы не попасть в безвыходное положение во время обрушения DDoS-шторма на системы, необходимо тщательным образом подготовить их к такой ситуации:
- Все сервера, имеющие прямой доступ во внешнюю сеть, должны быть подготовлены к простому и быстрому удаленному ребуту (sshd спасет отца русской демократии). Большим плюсом будет наличие второго, административного, сетевого интерфейса, через который можно получить доступ к серверу в случае забитости основного канала.
- ПО, используемое на сервере, всегда должно находиться в актуальном состоянии. Все дырки — пропатчены, обновления установлены (простой, как сапог, совет, которому многие не следуют). Это оградит тебя от DoS-атак, эксплуатирующих баги в сервисах.
- Все слушающие сетевые сервисы, предназначенные для административного использования, должны быть спрятаны брандмауэром ото всех, кто не должен иметь к ним доступ. Тогда атакующий не сможет использовать их для проведения DoS-атаки или брутфорса.
- На подходах к серверу (ближайшем маршрутизаторе) должна быть установлена система анализа трафика (NetFlow в помощь), которая позволит своевременно узнать о начинающейся атаке и вовремя принять меры по ее предотвращению.
Защита от основных видов DoS-атак
Чтобы защитится от HTTP-flood нужно прибавить одновременное количество максимальных подключений к БД сервера, нужно установить перед апачем еще и энжинкс для кэширования всех запросов. Данный конфиг приведу файликом, который можно глянуть:
nginx.conf
Защита от ICMP-flood
Расскажу сейчас как бороться от ICMP-flood, а всего то нужно отключить ответы на запросы ICMP ECHO:
# sysctl net.ipv4.icmp_echo_ignore_all=1
Так же это можно сделать с помощью брандмауэра:
# iptables -A INPUT -p icmp -j DROP --icmp-type 8
Защита от UDP-flood
Т.к UDP-пакеты посылаются на разные UDP-сервисы, то собственно достаточно вырубить их от мира и прописать собственно ограничение на количество соединений к DNS-серверу:
# iptables -I INPUT -p udp --dport 53 -j DROP -m iplimit --iplimit-above 1
Защита от SYN-flood
Эта данная защита заключается в выключении самой очереди «полуоткрытых» TCP-соединений:
# sysctl -w net.ipv4.tcp_max_syn_backlog=1024
Так же нужно включить сам механизм TCP syncookies, для этого следует выполнить:
# sysctl -w net.ipv4.tcp_syncookies=1
Следующим этапом мы ограничиваем максимального число «полуоткрытых» соединений с 1-го IP для нужного порта:
# iptables -I INPUT -p tcp --syn --dport 80 -m iplimit --iplimit-above 10 -j DROP
У вас должна быть настроена система, которая будет анализировать трафик и которая сможет своевременно узнать о ДДос-атаке, а так же по мере возможности, принимать меры по ее избежанию.
Защита от DDoS с iptables, готовый скрипт
Защита от спуфинга
Для этого нужно выполнить:
# net.ipv4.conf.default.rp_filter = 1
Проверяем TCP-соединение каждую минуту (если на др стороне — нормальный сервер, то сразу ответит. (Стандартное значение — 2ч):
# net.ipv4.tcp_keepalive_time = 60
Проверяем через 10 сек:
# net.ipv4.tcp_keepalive_intvl = 10
Устанавливаем количество проверок перед закрытием соединения:
# net.ipv4.tcp_keepalive_probes = 5
Я очень бегло рассказал и описал что и как, но постепенно ( со временем) я буду рассказывать и приводить примеры по борьбе с ДДосиками, так же я буду более глубоко уделять вниманию каждому из видов атак. Чтобы это я мог сделать, мне нужно время, время для того чтобы я смог найти нужный и полезный материал, а так же более подробно расписал, чтобы всем было понятно. Надеюсь я нормально пишу статьи, если есть замечания или может предложения, добавляйтесь в группы, можно и в друзья, а так же можете просто писать в комментах.
Собственно, я завершу наверное на этом «защита от ddos атак», надеюсь было полезно. Спасибо что посещаете мой сайт http://linux-notes.org
The Actual IPtables Anti-DDoS Rules
Considering you now know that you need to use the mangle table and the PREROUTING chain as well as optimized kernel settings to mitigate the effects of DDoS attacks, we’ll now move on to a couple of example rules to mitigate most TCP DDoS attacks.
DDoS attacks are complex.
There are many different types of DDoS and it’s close to impossible to maintain signature-based rules against all of them.
But luckily there is something called connection tracking (nf_conntrack kernel module), which can help us to mitigate almost any TCP-based DDoS attack that doesn’t use SYN packets that seem legitimate.
This includes all types of ACK and SYN-ACK DDoS attacks as well as DDoS attacks that use bogus TCP flags.
We’ll start with just five simple iptables rules that will already drop many TCP-based DDoS attacks.
Block Invalid Packets
iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP
This rule blocks all packets that are not a SYN packet and don’t belong to an established TCP connection.
Block New Packets That Are Not SYN
iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
This blocks all packets that are new (don’t belong to an established connection) and don’t use the SYN flag. This rule is similar to the “Block Invalid Packets” one, but we found that it catches some packets that the other one doesn’t.
Block Uncommon MSS Values
iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP
The above iptables rule blocks new packets (only SYN packets can be new packets as per the two previous rules) that use a TCP MSS value that is not common. This helps to block dumb SYN floods.
Block Packets With Bogus TCP Flags
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROPiptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROPiptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROPiptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROPiptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROPiptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROPiptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP
The above ruleset blocks packets that use bogus TCP flags, ie. TCP flags that legitimate packets wouldn’t use.
Block Packets From Private Subnets (Spoofing)
iptables -t mangle -A PREROUTING -s 224.0.0.0/3 -j DROP iptables -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP iptables -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP iptables -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP iptables -t mangle -A PREROUTING -s 192.168.0.0/16 -j DROP iptables -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP iptables -t mangle -A PREROUTING -s 0.0.0.0/8 -j DROP iptables -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP iptables -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j DROP
These rules block spoofed packets originating from private (local) subnets. On your public network interface you usually don’t want to receive packets from private source IPs.
These rules assume that your loopback interface uses the 127.0.0.0/8 IP space.
These five sets of rules alone already block many TCP-based DDoS attacks at very high packet rates.
With the kernel settings and rules mentioned above, you’ll be able to filter ACK and SYN-ACK attacks at line rate.
HTTP-флуд
Нужно подсчитать количество процессов Web — сервера (например Apache) и количество конектов на 80-ый порт. Значения, в несколько раз превышающие среднестатистические, дают основания задуматься.
-
Количество процессов
ps aux | grep apache | wc -l
-
Количество конектов на 80 порту
netstat -na | grep ":80\ " | wc -l
-
Просмотреть список IP- адресов, с которых идут запросы на подключение:
netstat -na | grep ":80\ " | sort | uniq -c | sort -nr
-
Примеры использования утилиты tshark: Tshark для мониторинга запросов http
- apachetop — отображает полученную от запущенной копии Apache информацию в режиме реального времени
Скрипт для разбора лог-файла Apache
Скрипт выводит топ-список ip адресов для конкретного домена, в запускаемый скрипт нужно передать параметр — имя домена, например
# .top_ips.sh YourDomen.ua
- top_ips.sh
-
#!/bin/bash # Скрипт выводит топ-список ip адресов для конкретного домена # в запускаемый скрипт нужно передать параметр - имя домена, например # ./top_ips.sh YourDomen.ua # Emails for notifications EMAILS=( "[email protected]" ) # Доменное имя DM=$1 #DM='YourDomen.ua' # Директория для отчетов RPDir='/var/log/apache2' # Файл журнала LOGFILE="/var/log/apache2/$DM.access.log" if ! -f "$RPDir/$DM.txt" then touch "$RPDir/$DM.txt" fi if -f $LOGFILE then echo "Start log $DM..." awk '{ print $1}' $LOGFILE | sort | uniq -c | sort -nr >> $RPDir$DM.txt| echo "End log $RPDir/$DM.txt" fi
-
Защита от спуфинга
net.ipv4.conf.default.rp_filter = 1
-
Проверять TCP-соединение каждую минуту. Если на другой стороне — легальная машина, она сразу ответит. Дефолтовое значение — 2 часа.
net.ipv4.tcp_keepalive_time = 60
-
Повторить пробу через десять секунд
net.ipv4.tcp_keepalive_intvl = 10
-
Количество проверок перед закрытием соединения
net.ipv4.tcp_keepalive_probes = 5
Баним ботов с неправильным referer
Есть категория простых ботов, которые подставляют в referrer либо мусор, либо кривые урлы без http или https в начале. Например вот такие:
194.67.215.242 - - [30/Nov/2017:20:48:08 +0300] "POST /index.php HTTP/1.1" 200 913 "g0dfw4p1.ru" "Mozilla/5.0 (Windows NT 6.0; rv:34.0) Gecko/20100101 Firefox/34.0" "-"
Корректное поле referer должно содержать либо http, либо https, либо быть пустым. Все, что иначе, можно смело блокировать или возвращать статус ошибки. Добавляем примерно такую конструкцию в конфигурацию виртуального хоста, в раздел server {}.
if ($http_referer !~* ^($|http://|https://) ) { return 403; }
После этого проверьте конфигурацию nginx и перечитайте ее.
# nginxt -t # nginx -s reload
Если вас достает какой-то бот с конкретным referer, можно забанить именно его. Для этого можно дополнить условие, или изменить. Например, вот так:
if ($http_referer = "https://bots.ru/dostanim_tebya.html") { return 403; }
В дополнение, можно всех этих ботов с помощью простого скрипта банить на iptables, как в примерах выше. К слову сказать, их можно банить сразу, разбирая http запросы еще до того, как они будут попадать к nginx, например, с помощью ngrep, но это более сложная задача. Не все это умеют делать, там есть нюансы, а с nginx знакомы все. Не составит большого труда реализовать данный метод.
Регулярное резервное копирование
Бэкап твой друг! Когда ничего не работает, резервная копия спасет вас.
Все может пойти не этим путем, но что если у вас нет необходимой резервной копии для восстановления? Большинство облачных или VPS-провайдеров предлагают резервное копирование за небольшую дополнительную плату, и об этом всегда следует помнить.
Узнайте у своего провайдера VPS, как включить службу резервного копирования. Если вы используете Google Compute Engine или AWS, запланируйте ежедневный снимок.
Резервное копирование позволит вам быстро восстановить всю виртуальную машину, и вы снова вернетесь в бизнес.
Защита от ддос с помощью модулей nginx — limit_conn и limit_req
Поделюсь еще одним простым способом снизить нагрузку на сервер и частично защититься от ддос с помощью модулей nginx — limit_conn и limit_req. Настроить их не сложно, частично результат работы первого модуля будет пересекаться с первыми двумя способами ddos защиты, описанными в начале. Он более простой для настройки, так что если не справились с теми способами, можно попробовать этот.
Смысл данных модулей в том, что один может ограничить одновременное количество разрешенных соединений с сайтом, а другой количество соединений в единицу времени.
Я ограничу в своем примере количество одновременных подключений к сайту с одного ip числом 50, а количество одновременных запросов к динамическому контенту не более 2-х в секунду. При этом будет разрешен всплеск (burst) запросов до 5-ти. Объясню, как понимать этот всплеск, так как сам не сразу понял, что конкретно он означает.
Если у нас идет превышение количества установленных запросов в секунду, то их выполнение задерживается, и они выстраиваются в очередь на исполнение с указанной скоростью. Размер этой очереди и равен значению всплеска. Все запросы, которым не хватит места в очереди, будут завершены с ошибкой. То есть, если запросов будет 4 в секунду, то 2 выполнятся сразу и еще 2 встанут в очередь. А если будет 10, то 2 выполнятся сразу, 5 встанут в очередь на выполнение по 2 штуки в секунду, а остальные будут завершены с ошибкой.
Исходя из этих условий, ограничение на подключения нужно установить в контексте server, а на доступ к динамическому контенту в соответствующем location. При этом описание зон, которые будут использовать директивы, нужно расположить в http.
Вот пример конфига nginx для реализации установленных ограничений с целью защиты от ддос атак.
http { ... limit_conn_zone $binary_remote_addr zone=perip:10m; limit_req_zone $binary_remote_addr zone=dynamic:10m rate=2r/s; ... server { ... limit_conn perip 50; ... location ~ \.php$ { ... limit_req zone=dynamic burst=5 nodelay; ... } } }
После этого перезапустите nginx и проверьте как работают лимиты. Ограничение на количество выполняемых динамических запросов можно увидеть, просто нажимая очень быстро F5 в браузере. Если будете достаточно ловки, то скоро увидите картинку
и запись в логе с ошибками:
2017/11/30 15:25:26 9773#9773: *51482 limiting requests, excess: 5.664 by zone "dynamic", client: 195.91.248.43, server: hl.zeroxzed.ru, request: "GET / HTTP/2.0", host: "hl.zeroxzed.ru", referrer: "https://hl.zeroxzed.ru/2013/03/15/featured-image-vertical/"
Лимит на количество подключений можете проверить той же утилитой ab, о которой я рассказал во введении.
017/11/30 15:38:56 9773#9773: *53938 limiting connections by zone "perip", client: 94.142.141.246, server: hl.zeroxzed.ru, request: "GET /wp-content/uploads/2013/03/the-dark-knight-rises.jpg HTTP/1.0", host: "hl.zeroxzed.ru"
Только не забывайте, что тест нужно запускать не на конкретную страницу, тогда вы попадете на ограничение выполнения динамического контента, а на что-то другое. Например, как в моем примере, на картинку.
При выставлении ограничений, не забудьте проконтролировать, не попадают ли в эти ограничения поисковые боты. По-умолчанию, они стараются не создавать повышенную нагрузку на сайт. При желании, роботу яндекса можно указать через robots.txt, с какой скоростью сканировать ваш сайт. А роботу гугла то же самое можно сделать через webmaster.
UDP-флуд
Метод захламления полосы пропускания. Основан на бесконечной посылке UDP-пакетов на порты различных UDP-сервисов. Легко устраняется за счет отрезания таких сервисов от внешнего мира и установки лимита на количество соединений в единицу времени.
#Ставим ограничение на 5 соединений на 80 порт. iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 5 -j REJECT # Разрешаем только одно одновременное соединение с одного айпи на smtp iptables -A FORWARD -p tcp --syn --dport smtp -m connlimit --connlimit-above 1 -j DROP #Ставим ограничение на 200 соединений на 1720 порт. iptables -A INPUT -p tcp --syn --dport 1720 -m connlimit --connlimit-above 200 -j REJECT
# udp 5060 $IPT -A INPUT -p udp --dport 5060 -m connlimit --connlimit-above 60 -j LOG --log-level info --log-prefix "REJECT 5060: " $IPT -A INPUT -p udp --dport 5060 -m connlimit --connlimit-above 60 -j REJECT # tcp 1720 $IPT -A INPUT -p tcp --syn --dport 1720 -m connlimit --connlimit-above 60 -j LOG --log-level info --log-prefix "REJECT 1720: " $IPT -A INPUT -p tcp --syn --dport 1720 -m connlimit --connlimit-above 60 -j REJECT