После прошлой истории с ddos захотелось проработать какое-то готовое универсальное решение, чтобы можно было его быстро применить, а не придумывать разные способы. В комментариях люди писали, что надо было установить fail2ban, какой-нибудь WAF или что-то в этом роде. Это всё слабо поможет, если идёт большая нагрузка. Fail2ban сразу мимо, забываем про него. А WAF или какой-то фильтрующий сервер надо настраивать заранее, а не когда у вас единственную машину ддосят.
Я взял наиболее простой и быстрый с точки зрения производительности вариант: ipset + iptables. Если ваш канал и сервер в целом вывозят нагрузку и вас не блокирует провайдер, указанная связка будет наиболее лёгкой и эффективной с точки зрения потребления ресурсов.
Сначала хотел что-то простое набросать, но потом всё расширял и расширял возможности. В итоге родился довольно большой bash скрипт с некоторыми проверками и логированием. Рассказываю, что он делает:
1️⃣ Проверяет установку ipset, создаёт списки.
2️⃣ Проверяет установку rsyslog, чтобы логировать заблокированные подключения. Это нужно на момент отладки и в обычное время, когда нет ддоса. Если начали ддосить, логирование надо отключить.
3️⃣ Создаёт конфигурацию rsyslog для хранения логов в отдельных файлах. Настраивает ротацию через logrotate.
4️⃣ Дальше идут переменные, касающиеся правил iptables: имя и ip адрес WAN интерфейса, белый список IP, с которых разрешено всё, разрешённые TCP и UDP порты, на которые мы принимаем соединения. Всё остальное блокируем.
5️⃣ Дальше идут наборы правил:
- очистка всех правил
- запрет всего, что не разрешено явно
- разрешаем установленные соединения
- разрешаем localhost и icmp
- разрешаем исходящие соединения сервера
- разрешаем все соединения от белого списка
- блокируем неопознанные и нулевые пакеты
- блокируем новые соединения без статуса NEW
- блокируем списки ipset, которые формируются ниже
- добавляем в список тех, кто открывает более 10-ти соединений с сервером в течении секунды, логируем таких товарищей
- разрешаем доступ к открытым портам, в данном примере это порты 80, 443 TCP и 443 UDP
- тех, кто обращается к другим портам, добавляем в список ipset
- сохраняю все правила в файл
Сразу скажу, что я не занимался плотной отладкой этого набора правил в реальной ситуации. Набросал правила на основе своего опыта и протестировал в ручном режиме. Под реальной нагрузкой и спамом запросов не проверял.
Для проверки работы надо установить на сервере iptables, ipset, rsyslog:
Скопировать и заполнить переменные в bash скрипте. Особое внимание уделить переменным WAN, WAN_IP, WLIST, WPORT_TCP, WPORT_UDP. На основе них будут сформированы правила iptables. Отдельного правила для SSH я не делал. Подразумевается, что подключаться куда-либо кроме открытых 80 и 443 портов можно только из списка WLIST. Туда можно добавлять IP адреса или подсети через запятую.
После выполнения скрипта, смотрим правила iptables:
Проверял работу так. Установил веб сервер. Попробовал с другой машины подключиться к серверу через telnet на любой отличный от HTTP порт:
Получил бан с занесением в список BANPORT. Смотреть этот список так:
Далее установил ab и попробовал спам запросов в 50 потоков к веб серверу:
Получил бан с занесением в список BANDDOS. Оба бана были отражены в лог файлах
⚡️На работающем сервере запускать такие скрипты не рекомендую, особенно если нет доступа к консоли. Сначала проверьте и отладьте на тестовой виртуалке. Убедитесь, что не отрубаете себе доступ. В целом, тут небольшой и относительно простой набор правил.
⇨ Забрать скрипт iptables.sh
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#iptables #ipset #ddos
Я взял наиболее простой и быстрый с точки зрения производительности вариант: ipset + iptables. Если ваш канал и сервер в целом вывозят нагрузку и вас не блокирует провайдер, указанная связка будет наиболее лёгкой и эффективной с точки зрения потребления ресурсов.
Сначала хотел что-то простое набросать, но потом всё расширял и расширял возможности. В итоге родился довольно большой bash скрипт с некоторыми проверками и логированием. Рассказываю, что он делает:
- очистка всех правил
- запрет всего, что не разрешено явно
- разрешаем установленные соединения
- разрешаем localhost и icmp
- разрешаем исходящие соединения сервера
- разрешаем все соединения от белого списка
- блокируем неопознанные и нулевые пакеты
- блокируем новые соединения без статуса NEW
- блокируем списки ipset, которые формируются ниже
- добавляем в список тех, кто открывает более 10-ти соединений с сервером в течении секунды, логируем таких товарищей
- разрешаем доступ к открытым портам, в данном примере это порты 80, 443 TCP и 443 UDP
- тех, кто обращается к другим портам, добавляем в список ipset
- сохраняю все правила в файл
Сразу скажу, что я не занимался плотной отладкой этого набора правил в реальной ситуации. Набросал правила на основе своего опыта и протестировал в ручном режиме. Под реальной нагрузкой и спамом запросов не проверял.
Для проверки работы надо установить на сервере iptables, ipset, rsyslog:
# apt install iptables ipset rsyslogСкопировать и заполнить переменные в bash скрипте. Особое внимание уделить переменным WAN, WAN_IP, WLIST, WPORT_TCP, WPORT_UDP. На основе них будут сформированы правила iptables. Отдельного правила для SSH я не делал. Подразумевается, что подключаться куда-либо кроме открытых 80 и 443 портов можно только из списка WLIST. Туда можно добавлять IP адреса или подсети через запятую.
После выполнения скрипта, смотрим правила iptables:
# iptables -L -v -nПроверял работу так. Установил веб сервер. Попробовал с другой машины подключиться к серверу через telnet на любой отличный от HTTP порт:
# telnet 85.143.173.182 23Получил бан с занесением в список BANPORT. Смотреть этот список так:
# ipset -L BANPORTДалее установил ab и попробовал спам запросов в 50 потоков к веб серверу:
# ab -c 50 -n 30000 "http://85.143.173.182/"Получил бан с занесением в список BANDDOS. Оба бана были отражены в лог файлах
ipset_portscan.log и ipset_ddos.log. При этом если ничего из описанного выше не делать, а просто ходить на веб сайт, доступ открыт, всё работает нормально.⚡️На работающем сервере запускать такие скрипты не рекомендую, особенно если нет доступа к консоли. Сначала проверьте и отладьте на тестовой виртуалке. Убедитесь, что не отрубаете себе доступ. В целом, тут небольшой и относительно простой набор правил.
⇨ Забрать скрипт iptables.sh
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#iptables #ipset #ddos
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍185👎2
Сейчас борьба с DDOS - в основном удел специализированных сервисов, у которых есть свои каналы и пулы IP адресов. Без этого эффективной защиты не построить. Если у вас не подключена специализированная защита, то вас просто отключит провайдер в случае серьёзной атаки.
Но далеко не всегда атаки реально серьёзные, с которыми невозможно справиться самостоятельно. С подобной ситуацией столкнулся в очередной раз. И вроде как успешно справился. Расскажу обо всём по порядку.
У меня есть в управлении веб сервер с очень старым проектом. Он уже не приносит прибыль, но бросить его жалко. У него очень много страниц в индексе, люди всё ещё заходят. Покупать для него защиту смысла не имеет.
В какой-то момент на сервер полился спам запросов на форумный поиск. Не сказать, что очень много, но сервер загрузили полностью. Отклик по 10-15 секунд, часто 500-е ошибки. Все запросы с разных IP, почти не повторялись. Трафик лился примерно 10-20 мегабит, небольшой, но и виртуалка под сервер не очень мощная, ей этой нагрузки хватало, тем более в поиск.
Я зашёл на сервер и бегло посмотрел, что там за IP адреса. Они были из экзотических стран, типа Сейшелы, Маврикий, Малайзия и т.д. Проект под аудиторию из РФ, решил временно ограничить страны, откуда идёт спам. Можно было бы разрешить только РФ и страны СНГ, а остальное запретить, но эти списки ненадёжны. А тем более сейчас, когда куча людей сидит по ВПН. Сразу скажу, что в любом случае это решение временное, на время атаки. Позже я такие ограничения убираю.
Есть сервис со списками IP адресов по странам. Я обычно его использую, так как списки легко забрать через wget. На сервере стоит iptables и ipset для больших списков адресов. Набросал простенький скрипт для загрузки IP стран и добавления их в iptables:
Скрипт рабочий, я его сходу написал и использовал. Ничего не отлаживал, проверок не делал, не оптимизировал. Любой ИИ вам всё это сделает, если нужно будет. У меня такой задачи не стояло.
Это помогло. Спам запросов прекратился. Через несколько дней возобновился. Список IP адресов очень разнообразный - США, Европа. Блокировать по странам не стал. Посмотрел внимательно на запросы. У них почему-то у всех был одинаковый user agent с фразой:
Решил банить IP по этому признаку. Сначала прошёл по всему логу и собрал всех с этим юзер агентом, кто сделал более одного запроса:
А потом загнал их в список ipset скриптом:
И забанил:
Это частично помогло, но, постоянно лезли новые IP. Собрал ещё один скрипт, который берёт последние 3000 строк лога и банит всех с указанным user agent. Перед запуском создал список и правило для него:
Скрипт:
Поставил его в cron на запуск раз в минуту. Примерно через час все адреса оказались в бане и нагрузка упала.
Не знаю, что это было, кто и зачем ддосил этот веб сервер. Ботнет был сильно разнесён географически, но почему-то с одинаковым user agent. Какая-то бессмыслица, но ситуация реальная. Написал заметку по горячим следам.
#iptables #ipset #ddos
Но далеко не всегда атаки реально серьёзные, с которыми невозможно справиться самостоятельно. С подобной ситуацией столкнулся в очередной раз. И вроде как успешно справился. Расскажу обо всём по порядку.
У меня есть в управлении веб сервер с очень старым проектом. Он уже не приносит прибыль, но бросить его жалко. У него очень много страниц в индексе, люди всё ещё заходят. Покупать для него защиту смысла не имеет.
В какой-то момент на сервер полился спам запросов на форумный поиск. Не сказать, что очень много, но сервер загрузили полностью. Отклик по 10-15 секунд, часто 500-е ошибки. Все запросы с разных IP, почти не повторялись. Трафик лился примерно 10-20 мегабит, небольшой, но и виртуалка под сервер не очень мощная, ей этой нагрузки хватало, тем более в поиск.
Я зашёл на сервер и бегло посмотрел, что там за IP адреса. Они были из экзотических стран, типа Сейшелы, Маврикий, Малайзия и т.д. Проект под аудиторию из РФ, решил временно ограничить страны, откуда идёт спам. Можно было бы разрешить только РФ и страны СНГ, а остальное запретить, но эти списки ненадёжны. А тем более сейчас, когда куча людей сидит по ВПН. Сразу скажу, что в любом случае это решение временное, на время атаки. Позже я такие ограничения убираю.
Есть сервис со списками IP адресов по странам. Я обычно его использую, так как списки легко забрать через wget. На сервере стоит iptables и ipset для больших списков адресов. Набросал простенький скрипт для загрузки IP стран и добавления их в iptables:
#!/bin/bash
country=mu
ipset -N ${country}_ip nethash
wget -O tmplist https://www.ipdeny.com/ipblocks/data/countries/${country}.zone
list=$(cat tmplist)
for ipnet in $list
do
ipset -A ${country}_ip $ipnet
done
iptables -I INPUT 1 -m set --match-set ${country}_ip src -j DROP
Скрипт рабочий, я его сходу написал и использовал. Ничего не отлаживал, проверок не делал, не оптимизировал. Любой ИИ вам всё это сделает, если нужно будет. У меня такой задачи не стояло.
Это помогло. Спам запросов прекратился. Через несколько дней возобновился. Список IP адресов очень разнообразный - США, Европа. Блокировать по странам не стал. Посмотрел внимательно на запросы. У них почему-то у всех был одинаковый user agent с фразой:
Macintosh; Intel Mac OS X 10_15_7. Пример лога веб сервера привёл на картинке.Решил банить IP по этому признаку. Сначала прошёл по всему логу и собрал всех с этим юзер агентом, кто сделал более одного запроса:
# egrep "Intel Mac OS X 10_15_7" /var/log/nginx/access.log | awk '{print $1}' | sort -n | uniq -c | sort -n | awk '{if ($1 > 1 ) print $2}' > 10_15_7.txtА потом загнал их в список ipset скриптом:
#!/bin/bash
{
echo "create 10_15_7 iphash hashsize 32696 maxelem 262144"
while read -r ip; do
echo "add 10_15_7 $ip"
done < 10_15_7.txt
} > ipset-restore
ipset restore < ipset-restore
И забанил:
# iptables -I INPUT 1 -m set --match-set 10_15_7 src -j DROPЭто частично помогло, но, постоянно лезли новые IP. Собрал ещё один скрипт, который берёт последние 3000 строк лога и банит всех с указанным user agent. Перед запуском создал список и правило для него:
# ipset -N banip iphash hashsize 16348 maxelem 131072# iptables -I INPUT 1 -m set --match-set banip src -j DROPСкрипт:
#!/bin/sh
tail -n 3000 /var/log/nginx/access.log | egrep "Intel Mac OS X 10_15_7" | awk '{print $1}' | sort -n | uniq -c | sort -n | awk '{if ($1 > 0 ) print $2}' > ban.txt
list=$(cat ban.txt)
for ipnet in $list
do
ipset -A banip $ipnet -exist
done
Поставил его в cron на запуск раз в минуту. Примерно через час все адреса оказались в бане и нагрузка упала.
Не знаю, что это было, кто и зачем ддосил этот веб сервер. Ботнет был сильно разнесён географически, но почему-то с одинаковым user agent. Какая-то бессмыслица, но ситуация реальная. Написал заметку по горячим следам.
#iptables #ipset #ddos
👍169👎1