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

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

У нас есть сервер Ubuntu 12.04 с httpd на порту 80, и мы хотим ограничить:

  • максимальное количество подключений на IP-адрес к httpd до 10
  • максимальное количество новых подключений в секунду к httpd до 150

Как это сделать с помощью iptables?

решение1

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 НОВЫХ подключений (пакетов) в секунду.

решение2

Вам нужны следующие правила в 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), нам придется делать это в обратном порядке, то есть «читать» их снизу вверх.

Я также предлагаю рассмотреть --connlimit-mask изменение NN с 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-соединение.

решение3

Вам необходимо использовать connlimitмодули, которые позволяют ограничить количество параллельных TCP-подключений к серверу на один клиентский IP-адрес (или блок адресов).

/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
      --connlimit-above 10 -j DROP

Связанный контент