У нас есть сервер Ubuntu 12.04 с httpd на порту 80, и мы хотим ограничить:
- максимальное количество подключений на IP-адрес к httpd до 10
- максимальное количество новых подключений в секунду к httpd до 150
Как мы можем сделать это с iptables?
У нас есть сервер Ubuntu 12.04 с httpd на порту 80, и мы хотим ограничить:
Как мы можем сделать это с iptables?
Ответы:
iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 32 -j REJECT --reject-with tcp-reset
Это приведет к отклонению соединений выше 15 от одного источника IP.
iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 150/second --limit-burst 160 -j ACCEPT
При этом допускается 160 новых соединений (реально пакетов) до того, как будет применено ограничение в 150 НОВЫХ соединений (пакетов) в секунду.
-m conntrack --ctstate
вместо -m state --state
. Conntrack является новым и улучшенным по сравнению с государством.
NEW
соединениям - не делайте этого - он фактически превращает вашу INPUT
цепочку в дефолт accept
!!!
Вы хотите, чтобы следующие правила в 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
# Adjust "--connlimit-above NN" to limit the maximum connections per IP
# that you need.
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
--connlimit-above 10 --connlimit-mask 32 -j DROP
# Adjust "--connlimit-above NNN" to the maximum total connections you
# want your web server to support
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
--connlimit-above 150 -j DROP
Поскольку мы используем -I (согласно запросу OP), мы должны выполнять их в обратном порядке, поэтому «читаем» их снизу вверх.
Я также предлагаю рассмотреть возможность изменения значения NN --connlimit-mask с 32 на 24. Это ограничит полную сеть класса C (максимум 256 IP-адресов в одном диапазоне) до 10 соединений. Вы также можете использовать любой другой бесклассовый номер, например 22 или 30, в зависимости от того, как, по вашему мнению, может использоваться ваша услуга.
Также в зависимости от того, как вы хотите, чтобы клиент вел себя, вы можете использовать «-j REJECT --reject-with tcp-reset» вместо «-j DROP» в двух вышеприведенных правилах или даже только в максимальных 150 соединениях. править.
Если вы ОТКЛЮЧИТЕ соединение, браузер или программное обеспечение, использующее порт 80, сразу же покажет состояние «недоступно», но опция DROP заставит клиента подождать и повторить попытку несколько раз, прежде чем сообщить о сайте как о недоступном. Я склонен склоняться к DROP сам, так как он ведет себя скорее как плохое соединение, чем автономный сервер.
Кроме того, если предел соединения снова падает ниже 150 (или 10), пока он все еще повторяется, то он, наконец, дойдет до вашего сервера.
Однако опция REJECT вызовет на ваш сайт меньший трафик, так как DROP заставит его отправлять дополнительные пакеты во время повторных попыток. Наверное, не все это актуально.
Если, с другой стороны, трафик вашего порта 80 является частью кластера, то REJECT сообщит контроллеру кластера, что он не работает, и прекратит посылать ему трафик на время его ожидания.
Правило RELATED, ESTABLISHED подразумевает, что ваше правило по умолчанию - блокировать весь трафик (iptables -t filter -P INPUT DROP). Это только принимает дальнейшие пакеты, принадлежащие принятым соединениям.
Также --syn говорит ему обращать внимание (или считать) пакеты, которые устанавливают TCP-соединение.
Вам необходимо использовать connlimit
модули, которые позволяют ограничивать количество параллельных TCP-подключений к серверу на IP-адрес клиента (или адресный блок).
/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
--connlimit-above 10 -j DROP