В этой статье мы разберем, как создать эффективный защитный периметр, используя только Bash, iptables, fail2ban и утилиты анализа логов. Вы получите готовые скрипты для внедрения на своих серверах.
Данная информация предназначена для услуг: VPS хостинг или Облачный хостинг
Понимание угрозы: какие DDoS-атаки блокирует Bash?
Прежде чем писать код, определим векторы атак, с которыми может справиться скриптовой подход.
| Тип атаки | Суть | Эффективность защиты через Bash |
|---|---|---|
| SYN Flood | Массовая отправка SYN-пакетов без завершения handshake | Частичная (через настройки iptables и sysctl) |
| HTTP Flood | Тысячи запросов к веб-странице (GET /) | Высокая (анализ access.log + ограничение по User-Agent) |
| Slowloris | Медленное открытие соединений | Высокая (через модуль connlimit) |
| DNS Amplification | Запросы к открытому DNS-резольверу | Низкая (это проблема сети хостинга) |
| Brute-force SSH | Перебор паролей по SSH | Высокая (связка fail2ban + custom bash) |
Скрипты не заменят специализированный Anti-DDoS аппаратный модуль, но позволят отсеять до 85% «мусорного» трафика на уровне L3-L7.
Важно: Все примеры ниже протестированы на CentOS 7/8, Ubuntu 20.04/22.04 и Debian 11/12.
Базовая настройка ядра Linux для смягчения атак
Прежде чем писать скрипты, нужно укрепить сам стек TCP/IP. Поместите следующие параметры в файл /etc/sysctl.d/99-ddos-protect.conf:# Защита от SYN Flood
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_max_syn_backlog = 4096
# Ограничение таймаутов полуоткрытых соединений
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_tw_reuse = 1
# Защита от ICMP-флуда (ping flood)
net.ipv4.icmp_echo_ignore_all = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Ограничение на количество одновременных соединений с одного IP
net.netfilter.nf_conntrack_max = 65536
sysctl -p /etc/sysctl.d/99-ddos-protect.conf
#!/bin/bash
# watch_syn_flood.sh
LIMIT=500
CURRENT=$(ss -tan state syn-recv | grep -c "SYN-RECV")
if [ $CURRENT -gt $LIMIT ]; then
echo "`date` - Обнаружен SYN Flood: $CURRENT полуоткрытых соединений" >> /var/log/ddos.log
# Вызов подсистемы блокировки (см. раздел 5)
/usr/local/bin/ddos_blocker.sh --syn
fi
* * * * * sleep 30; /usr/local/bin/watch_syn_flood.sh
Скрипт для анализа access.log и блокировки HTTP-флуда
Самый распространенный способ положить сайт — это HTTP-флуд с подменой User-Agent. Напишем скрипт, который каждую минуту анализирует логи веб-сервера (nginx/apache) и блокирует подозрительные IP через iptables.
Алгоритм работы скрипта http_flood_detector.sh
-
Определить временной диапазон (последние 60 секунд).
-
Собрать IP-адреса, сделавшие более N запросов (для среднего хостинга N=200).
-
Исключить доверенные IP (свой офис, поисковые боты).
-
Добавить их в цепочку
INPUTiptables с отклонением.
Полный код скрипта:#!/bin/bash
# /usr/local/bin/http_flood_detector.sh
LOG_FILE="/var/log/nginx/access.log" # или /var/log/apache2/access.log
LIMIT_REQUESTS=200
BAN_TIME=600 # секунд (10 минут)
WHITELIST_FILE="/etc/ddos/whitelist.txt"
BLACKLIST_CHAIN="DDOS_HTTP"
# Создаем цепочку в iptables, если ее нет
iptables -L $BLACKLIST_CHAIN -n >/dev/null 2>&1
if [ $? -ne 0 ]; then
iptables -N $BLACKLIST_CHAIN
iptables -I INPUT -p tcp --dport 80,443 -j $BLACKLIST_CHAIN
fi
# Функция для логирования
log() {
echo "[`date '+%Y-%m-%d %H:%M:%S'`] $1" >> /var/log/ddos_http.log
}
# Анализ логов за последнюю минуту
TIME_MARK=`date --date='1 minute ago' '+%d/%b/%Y:%H:%M'`
TMP_FILE=$(mktemp)
awk -v time="$TIME_MARK" '$4 ~ time {print $1}' $LOG_FILE | sort | uniq -c | sort -nr > $TMP_FILE
log "Анализ завершен. Обработано записей: $(wc -l < $TMP_FILE)"
# Загрузка белого списка
declare -A WHITELIST
while read ip; do
WHITELIST["$ip"]=1
done < $WHITELIST_FILE
# Блокировка нарушителей
while read count ip; do
if [ $count -gt $LIMIT_REQUESTS ] && [ -z "${WHITELIST[$ip]}" ]; then
# Проверяем, не заблокирован ли уже
iptables -L $BLACKLIST_CHAIN -n | grep -q "$ip"
if [ $? -ne 0 ]; then
iptables -A $BLACKLIST_CHAIN -s $ip -j DROP
log "ЗАБЛОКИРОВАН $ip (запросов: $count)"
# Добавляем автознятие блокировки
(
sleep $BAN_TIME
iptables -D $BLACKLIST_CHAIN -s $ip -j DROP
log "СНЯТА БЛОКИРОВКА $ip"
) &
fi
fi
done < $TMP_FILE
rm -f $TMP_FILE
Настройка прав:
chmod 700 /usr/local/bin/http_flood_detector.sh
mkdir -p /etc/ddos
echo "127.0.0.1" > /etc/ddos/whitelist.txt
echo "8.8.8.8" >> /etc/ddos/whitelist.txt
Cron для запуска раз в минуту:* * * * * /usr/local/bin/http_flood_detector.sh >/dev/null 2>&1
Бывает, что злоумышленник использует медленные атаки (Slowloris, RUDY) — создает тысячи соединений с сервером, но почти не передает данные. Здесь на помощь приходит модуль iptables connlimit. Напишем скрипт, который динамически устанавливает пороги.
Скрипт dynamic_conn_limit.sh
Этот скрипт достаточно запустить один раз после перезагрузки (например, из /etc/rc.local). Однако для адаптивной защиты лучше поместить его в cron с проверкой текущей нагрузки:
*/5 * * * * /usr/local/bin/dynamic_conn_limit.sh
Почему это эффективно? При DDoS-атаке с ботнета (5000 уникальных IP) каждый IP создает не более 25 соединений, что для сервера с 4 ГБ RAM является абсолютно безопасной нагрузкой. А настоящему пользователю 25 параллельных соединений на сайт — более чем достаточно.
Автоматическая блокировка по гео (geoip) с помощью bash + ipset
Атаки часто приходят из определенных стран. Если ваш проект работает только для РФ или Европы, можно отсечь весь трафик из других регионов на уровне ядра. Это снижает нагрузку на 70-90% во время массированной атаки.
Скрипт geoip_block.sh (использует базу MaxMind):#!/bin/bash
# Блокирует все страны, кроме указанных
ALLOWED_COUNTRIES="RU UA BY KZ"
IPSET_NAME="geo_whitelist"
# Установка утилиты для работы с geoip
if ! command -v geoiplookup &> /dev/null; then
apt-get install geoip-bin geoip-database -y
fi
# Создаем ipset
ipset create $IPSET_NAME hash:net 2>/dev/null
# Загружаем список всех разрешенных диапазонов
TMP_LIST="/tmp/allowed_nets.txt"
> $TMP_LIST
for COUNTRY in $ALLOWED_COUNTRIES; do
echo "Загрузка диапазонов для $COUNTRY"
wget -qO- "http://www.ipdeny.com/ipblocks/data/countries/$COUNTRY.zone" >> $TMP_LIST
done
# Заполняем ipset
while read net; do
ipset add $IPSET_NAME $net 2>/dev/null
done < $TMP_LIST
# Применяем правило iptables
iptables -I INPUT -m set --match-set $IPSET_NAME src -j ACCEPT
iptables -I INPUT -p tcp --dport 80,443 -j DROP # Все, кроме белого списка
echo "Геоблокировка активирована. Разрешены: $ALLOWED_COUNTRIES"
Недостаток: база устаревает, требует обновления раз в месяц. Добавьте в cron:
0 0 1 * * /usr/local/bin/geoip_block.sh
Комплексный скрипт мониторинга и самолечения
Объединим все описанные выше модули в единую систему ddos_warden.sh. Он будет работать в фоне как демон (или через systemd).
Основной код комбайна
Установка как сервиса Systemd:
Логирование, отчетность и Grafana
Скрипты генерируют логи в /var/log/ddos*.log. Для визуализации атак и проверки эффективности напишем простой парсер в bash, который раз в час отправляет статистику в Telegram.
Скрипт ddos_report.sh:
Настройте cron:0 * * * * /usr/local/bin/ddos_report.sh
Тестирование защиты (как убедиться, что скрипты работают)
Прежде чем доверить защиту продакшену, проведите тест на изолированном сервере или VPS с тестовым сайтом.
Инструменты для симуляции DDoS:
#hping3 (SYN flood):
hping3 -S --flood --rand-source YOUR_IP -p 80#ab (Apache Bench) для HTTP флуда:
ab -n 10000 -c 500 http://YOUR_SITE/#slowloris (Perl-скрипт):
perl slowloris.pl -dns YOUR_SITE -port 80 -timeout 30 -num 500
Проверка блокировки:
Ожидаемый результат: через 1-2 минуты IP-адрес тестового клиента попадает в черный список, сайт перестает отвечать только для него, остальные пользователи работают штатно.
Ограничения и когда стоит переходить на профессиональный Anti-DDoS
Важно понимать: bash-скрипты не спасут от амплификационных атак (NTP, DNS, memcached) с трафиком 10+ Гбит/с. Сетевой канал обычного выделенного сервера просто переполнится, и скрипт даже не получит управление.
Когда нужен аппаратный или облачный Anti-DDoS:
-
Трафик атаки превышает 1 Гбит/с (предел гигабитного порта).
-
Атака на уровне L7 с ротацией User-Agent и подменой TLS fingerprint.
-
Целевой ресурс — онлайн-банкинг, биржа, госсайт (SLA 99.99%).
Однако для 90% проектов на shared hosting или VPS описанные скрипты позволяют выиграть время и сохранить доступность.