Ограничить количество одновременных подключений в iptables

Дата: 26.04.2017Метки:

Допустим у вас есть обычный 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