Основные методы защиты сервера от DDOS атак
Защита сервера от DDOS атак с помощью iptables
Первым делом сбросим все правила для всех цепочек, разрешим входящие только по тем протоколам и портам, которые используются повседневно, установим политики по умолчанию применяемые для цепочек если для соединений в них нет подходящего правила:
# устанавливаем политику полного доступа для цепочки INPUT
iptables -P INPUT ACCEPT
# сбрасываем все правила, для всех цепочек
iptables -F
# добавляем разрешающее правило для локального интерфейса
iptables -A INPUT -i lo -j ACCEPT
# Разрешаем пакеты по уже установленным соединениям
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Разрешаем доступ только к веб и SSH
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT
# Разрешаем проброс пакетов для локального интерфейса
# Не имеет смысла для рабочих станций и серверов
iptables -A FORWARD -i lo -j ACCEPT
# Ставим политики по умолчанию применяемые для цепочек
# если для соединений в них нет подходящего правила
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# сохраняем правила
service iptables save
Создадим дополнительную цепочку LIMIT для правил устанавливающих лимиты и с кажем что проходящие по цепочке INPUT соединения должны сначала быть обработаны правилами в цепочке LIMIT
iptables -N LIMIT
iptables -I INPUT -j LIMIT
Главное в цепочку LIMIT НЕ добавить "iptables -A LIMIT -j DROP" ибо закроем всё, для всех и для себя включительно!
Добавим соответствующее правило ограничивающее количество одновременных соединений с одного и того же ИП адреса:
# Ограничиваем максимальное число «полуоткрытых» TCP-соединений
# с одного и того же IP-адреса
# В браузерах количество подключений к серверу ограничивается 16 соединениями,
# желательно вспомнить и про тех, кто может висеть за NAT-ом.
# Значение параметра --connlimit-above нужно подбираеть оптимально
iptables -A LIMIT -p tcp --syn -m multiport --dports 80,443 -m connlimit \
--connlimit-above 32 -j LOG --log-level 4 --log-prefix "[FW SYN DROP]: "
iptables -A LIMIT -p tcp --syn -m multiport --dports 80,443 -m connlimit \
--connlimit-above 32 -j DROP
# то же только для DNS
iptables -A LIMIT -p udp --dport 53 -m connlimit --connlimit-above 8 -j LOG \
--log-level 4 --log-prefix "[FW DNS DROP]: "
iptables -A LIMIT -p udp --dport 53 -m connlimit --connlimit-above 8 -j DROP
При обнаружении ИП с которого будет попытка установить более 32 соединений, событие будет записано в журнал с пометкой "[FW SYN DROP]:", а сам пакет будет сброшен (DROP). Тем, у кого старая версия ядра и фаервола где нет возможности юзать connlimit, поможет анти ддос шел-скрипт на базе tcpdump или netstat.
Теперь оправдание тому, почему используется дополнительная цепочка LIMIT... Принимая входящие из цепочки INPUT в цепочку LIMIT мы можем более гибко шаманить правилами - т.е. приняв пакет нам нужно с ним что-то сделать - ACCEPT, DROP, REJECT, NFQUEUE, QUEUE или RETURN. С действиями ACCEPT, DROP, REJECT, RETURN думаю всё ясно, а вот по поводу NFQUEUE и QUEUE поясню как я их понял из доков - действие NFQUEUE ставит пакет в очередь на обработку пользовательским демоном (процессом), например "-j NFQUEUE --queue-num ?", где знак вопроса является номером очереди, действие же QUEUE является устаревшей версией NFQUEUE.
Если RETURN применяется к правилу в пользовательской цепочке, то обработка прекращается с возвратом пакета в центральную для дальнейшей обработки, а если RETURN применяется к правилу в центральной цепочке, то применяется политика цепочки по умолчанию, в нашем случае DROP.
Создадим дополнительную цепочку BAN для постоянно заблокированных ИП и с кажем что проходящие по цепочке INPUT должны быть обработаны правилами в цепочке BAN:
iptables -N BAN
iptables -I INPUT -j BAN
Добавляем ИП которые нужно блокировать, например:
iptables -A BAN -s 58.218.199.250 -j DROP
Цепочку BAN нужно поставить первой, её можно будет использовать для связки tcpdump + iptables или netstat + iptables. Например можно написать скрипт, который по крон-у будет анализировать аномалии в соединениях и заносить ИП в цепочку BAN, которую при каждом своем запуске по крон-у, например каждые 10 мин, будет её сбрасывать iptables -F BAN, а потом снова анализировать соединения и банить подозрительных. ИП 58.218.199.250 принадлежит какому-то китайскому роботу, который постоянно щупает один и тот же каталог, не припомню какой - можете смело его банить
В конце цикла работы скрипта, ему можно подсовывать список неугодных ИП которые заблокированы на постоянной основе, хотя для этого можно оставить цепочку BAN, а для скрипта работающего с tcpdump + iptables или netstat + iptables создать отдельную цепочку ANTIDDOS
Главное в дочерние цепочки НЕ добавить правило типа "iptables -A BAN -j DROP" ибо закроем всё, для всех и для себя включительно!
Также для установки правил лучше использовать команду iptables, а не редактировать файл /etc/sysconfig/iptables вручную!
В нашу цепочку LIMIT можно добавить ещё одно полезное правило, которое поможет отсекать спуферастов с записью в сисьлог
Когда по еще не открытому соединению, приходит пакет, на котором установлены флаги SYN и ACK, а такая комбинация флагов свойственна только для ответа на SYN-пакет, то это значит, что кто-то послал SYN-пакет другому хосту от нашего имени, и ответ пришел к нам.
Согласно этому правилу, наш хост должен ответит RST-пакетом, после чего атакуемый хост должен закрыть соединение.
iptables -A LIMIT -m conntrack --ctstate NEW,INVALID -p tcp \
--tcp-flags SYN,ACK SYN,ACK -j LOG --log-level 4 --log-prefix "[FW SPUF REJECT]: "
iptables -A LIMIT -m conntrack --ctstate NEW,INVALID -p tcp \
--tcp-flags SYN,ACK SYN,ACK -j REJECT --reject-with tcp-reset
Можно рассмотреть ещё одно полезное правило ограничивающее создание новых соединений в определённый промежуток времени:
# Если с одного адреса за последние 300 секунд (5 минут)
# было 5 или более новых соединений — сбрасываем пакет
iptables -A LIMIT -m conntrack --ctstate NEW -m recent --update \
--seconds 300 --hitcount 5 -j LOG --log-level 4 --log-prefix "[FW NEW DROP]: "
iptables -A LIMIT -m conntrack --ctstate NEW -m recent --update \
--seconds 300 --hitcount 5 -j DROP
Если всё работает как нужно, тогда сохраняем правила service iptables save.
- Использование фаервола - закрыть все порты кроме используемых повседневно, остановить лишние сервисы, запретить пинг для скрытия машины от различных злонамеренных роботов пингующих и сканирующих диапазоны ИП, проверять входящие пакеты на их соответствие стандартам стека протоколов TCP;
- Сменить стандартные номера портов для FTP и SSH;
- Регулярно анализировать критические сообщения из .лог файлов сервера, например при помощи Logwatch и делать адекватные выводы;
- Своевременное обновление всего системного и прикладного ПО;
- Снять с автоматической загрузки все сервисы находящиеся в публичном доступе, включая веб сервера nginx и httpd: chkconfig httpd off and chkconfig nginx off, что поможет получить доступ к серверу в случае непрерывной ДДОС атаки на эти сервисы;
- Использовать PHP ака Fast CGI + акселераторы типа eAccelerator или APC;
- Выполнить тонкую настройку сетевых параметров ядра через sysctl;
- Возможно использовать дополнительное ПО вроде mod_evasive или анти ддос шел-скрипты на базе tcpdump или netstat;
- Выбрать правильный диспетчер ввода/вывода и оптимизировать использование оперативной и виртуальной памяти.
Защита сервера от DDOS атак с помощью iptables
Первым делом сбросим все правила для всех цепочек, разрешим входящие только по тем протоколам и портам, которые используются повседневно, установим политики по умолчанию применяемые для цепочек если для соединений в них нет подходящего правила:
# устанавливаем политику полного доступа для цепочки INPUT
iptables -P INPUT ACCEPT
# сбрасываем все правила, для всех цепочек
iptables -F
# добавляем разрешающее правило для локального интерфейса
iptables -A INPUT -i lo -j ACCEPT
# Разрешаем пакеты по уже установленным соединениям
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Разрешаем доступ только к веб и SSH
iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -j ACCEPT
# Разрешаем проброс пакетов для локального интерфейса
# Не имеет смысла для рабочих станций и серверов
iptables -A FORWARD -i lo -j ACCEPT
# Ставим политики по умолчанию применяемые для цепочек
# если для соединений в них нет подходящего правила
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# сохраняем правила
service iptables save
Создадим дополнительную цепочку LIMIT для правил устанавливающих лимиты и с кажем что проходящие по цепочке INPUT соединения должны сначала быть обработаны правилами в цепочке LIMIT
iptables -N LIMIT
iptables -I INPUT -j LIMIT
Главное в цепочку LIMIT НЕ добавить "iptables -A LIMIT -j DROP" ибо закроем всё, для всех и для себя включительно!
# Ограничиваем максимальное число «полуоткрытых» TCP-соединений
# с одного и того же IP-адреса
# В браузерах количество подключений к серверу ограничивается 16 соединениями,
# желательно вспомнить и про тех, кто может висеть за NAT-ом.
# Значение параметра --connlimit-above нужно подбираеть оптимально
iptables -A LIMIT -p tcp --syn -m multiport --dports 80,443 -m connlimit \
--connlimit-above 32 -j LOG --log-level 4 --log-prefix "[FW SYN DROP]: "
iptables -A LIMIT -p tcp --syn -m multiport --dports 80,443 -m connlimit \
--connlimit-above 32 -j DROP
# то же только для DNS
iptables -A LIMIT -p udp --dport 53 -m connlimit --connlimit-above 8 -j LOG \
--log-level 4 --log-prefix "[FW DNS DROP]: "
iptables -A LIMIT -p udp --dport 53 -m connlimit --connlimit-above 8 -j DROP
При обнаружении ИП с которого будет попытка установить более 32 соединений, событие будет записано в журнал с пометкой "[FW SYN DROP]:", а сам пакет будет сброшен (DROP). Тем, у кого старая версия ядра и фаервола где нет возможности юзать connlimit, поможет анти ддос шел-скрипт на базе tcpdump или netstat.
Теперь оправдание тому, почему используется дополнительная цепочка LIMIT... Принимая входящие из цепочки INPUT в цепочку LIMIT мы можем более гибко шаманить правилами - т.е. приняв пакет нам нужно с ним что-то сделать - ACCEPT, DROP, REJECT, NFQUEUE, QUEUE или RETURN. С действиями ACCEPT, DROP, REJECT, RETURN думаю всё ясно, а вот по поводу NFQUEUE и QUEUE поясню как я их понял из доков - действие NFQUEUE ставит пакет в очередь на обработку пользовательским демоном (процессом), например "-j NFQUEUE --queue-num ?", где знак вопроса является номером очереди, действие же QUEUE является устаревшей версией NFQUEUE.
Если RETURN применяется к правилу в пользовательской цепочке, то обработка прекращается с возвратом пакета в центральную для дальнейшей обработки, а если RETURN применяется к правилу в центральной цепочке, то применяется политика цепочки по умолчанию, в нашем случае DROP.
Создадим дополнительную цепочку BAN для постоянно заблокированных ИП и с кажем что проходящие по цепочке INPUT должны быть обработаны правилами в цепочке BAN:
iptables -N BAN
iptables -I INPUT -j BAN
Добавляем ИП которые нужно блокировать, например:
iptables -A BAN -s 58.218.199.250 -j DROP
Цепочку BAN нужно поставить первой, её можно будет использовать для связки tcpdump + iptables или netstat + iptables. Например можно написать скрипт, который по крон-у будет анализировать аномалии в соединениях и заносить ИП в цепочку BAN, которую при каждом своем запуске по крон-у, например каждые 10 мин, будет её сбрасывать iptables -F BAN, а потом снова анализировать соединения и банить подозрительных. ИП 58.218.199.250 принадлежит какому-то китайскому роботу, который постоянно щупает один и тот же каталог, не припомню какой - можете смело его банить
В конце цикла работы скрипта, ему можно подсовывать список неугодных ИП которые заблокированы на постоянной основе, хотя для этого можно оставить цепочку BAN, а для скрипта работающего с tcpdump + iptables или netstat + iptables создать отдельную цепочку ANTIDDOS
Главное в дочерние цепочки НЕ добавить правило типа "iptables -A BAN -j DROP" ибо закроем всё, для всех и для себя включительно!
В нашу цепочку LIMIT можно добавить ещё одно полезное правило, которое поможет отсекать спуферастов с записью в сисьлог
Согласно этому правилу, наш хост должен ответит RST-пакетом, после чего атакуемый хост должен закрыть соединение.
iptables -A LIMIT -m conntrack --ctstate NEW,INVALID -p tcp \
--tcp-flags SYN,ACK SYN,ACK -j LOG --log-level 4 --log-prefix "[FW SPUF REJECT]: "
iptables -A LIMIT -m conntrack --ctstate NEW,INVALID -p tcp \
--tcp-flags SYN,ACK SYN,ACK -j REJECT --reject-with tcp-reset
Можно рассмотреть ещё одно полезное правило ограничивающее создание новых соединений в определённый промежуток времени:
# Если с одного адреса за последние 300 секунд (5 минут)
# было 5 или более новых соединений — сбрасываем пакет
iptables -A LIMIT -m conntrack --ctstate NEW -m recent --update \
--seconds 300 --hitcount 5 -j LOG --log-level 4 --log-prefix "[FW NEW DROP]: "
iptables -A LIMIT -m conntrack --ctstate NEW -m recent --update \
--seconds 300 --hitcount 5 -j DROP
Если всё работает как нужно, тогда сохраняем правила service iptables save.