Допустим у вас есть обычный VPS, где крутится популярный среди группы людей сайт и вы хотите защитить его от примитивных атак недоброжелателей. Основная задача которых состоит в том, что бы вызвать исчерпание вычислительных ресурсов VPS с помощью искусственно спровоцированной нагрузки на сервер. В следствие которой, память уйдет в swap и подключится к серверу станет проблематично.
В таком случае для ограничения потребления ресурсов сервера наиболее эффективно использовать cgroups
— механизм ядра, который ограничивает вычислительные ресурсы для групп процессов. Используя cgroups
мы можем предотвратить полную утилизацию вычислительных ресурсов процессора и памяти сервера, которые могут вызваны нагрузкой на веб-сервер и PHP. Таким образом мы всегда можем сохранить контроль над сервером и обеспечить доступ к серверу по SSH.
О использовании cgroups
я постараюсь рассказать позже. Но даже если правильно настроить cgroups
, в случае всплеска нагрузки, работа сайта будет нарушена. Как вариант решения проблемы предлагаю с помощью iptables
ограничить количество одновременных подключений к серверу. Таким образом можно попытаться отсечь основной источник нагрузки, сохранив доступность ресурса для других посетителей.
Ситуацию я привел в качестве примера, но думаю, что ее можно адаптировать для других задач. Теперь переходим непосредственно к примеру, для начала добавьте следующие правила в iptables
:
iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT iptables -t filter -I INPUT -p tcp --dport 80 -m state --state RELATED,ESTABLISHED -j ACCEPT
Здесь мы разрешаем все входящие соединения на порт 80 нашего сервера. Чтобы ограничить количество одновременных подключений к серверу с одного ip-адреса, необходимо добавить следующие правила:
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 30 --connlimit-mask 32 -j DROP
Это правило устанавливает ограничение на 30 одновременных подключений с одного ip-адреса.
Если вам необходимо ограничить количество одновременных подключений со всех ip, тогда необходимо использовать следующую команду:
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 500 -j DROP
Пример готового скрипта для ограничения подключений к серверу:
iptables -F INPUT iptables -P INPUT DROP iptables -P FORWARD ACCEPT iptables -P OUTPUT ACCEPT iptables -A INPUT -i lo -j ACCEPT iptables -A INPUT -m conntrack --ctstate INVALID -j DROP iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -I INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 2 -j DROP