Ограничить количество одновременных подключений в 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

Failed to execute ban jail ‘sshd’ action ‘iptables-multiport’

Связи с тем, что для выхода в интернет я использую статический IP, мне достаточно редко приходится использовать fail2ban на своих серверах. Я предпочитаю просто закрыть доступ к SSH в iptables. После настройки VMmanager, был автоматически установлен пакет fail2ban. После чего в логах стали регулярно появляться ошибки следующего содержания:

2016-08-13 05:43:23,463 fail2ban.actions        [1011]: NOTICE  [sshd] Ban 91.224.160.106
2016-08-13 05:43:23,565 fail2ban.action         [1011]: ERROR   iptables -w -n -L INPUT | grep -q 'f2b-sshd[ \t]' -- stdout: ''
2016-08-13 05:43:23,565 fail2ban.action         [1011]: ERROR   iptables -w -n -L INPUT | grep -q 'f2b-sshd[ \t]' -- stderr: ''
2016-08-13 05:43:23,565 fail2ban.action         [1011]: ERROR   iptables -w -n -L INPUT | grep -q 'f2b-sshd[ \t]' -- returned 1
2016-08-13 05:43:23,565 fail2ban.CommandAction  [1011]: ERROR   Invariant check failed. Trying to restore a sane environment
2016-08-13 05:43:23,667 fail2ban.action         [1011]: ERROR   iptables -w -D INPUT -p tcp -m multiport --dports ssh -j f2b-sshd
iptables -w -F f2b-sshd
iptables -w -X f2b-sshd -- stdout: ''
2016-08-13 05:43:23,667 fail2ban.action         [1011]: ERROR   iptables -w -D INPUT -p tcp -m multiport --dports ssh -j f2b-sshd
iptables -w -F f2b-sshd
iptables -w -X f2b-sshd -- stderr: "iptables v1.4.21: Couldn't load target `f2b-sshd':No such file or directory\n\nTry `iptables -h' or 'iptables --help' for more information.\niptables: No chain/target/match by that name.\niptables: No chain/target/match by that name.\n"
2016-08-13 05:43:23,667 fail2ban.action         [1011]: ERROR   iptables -w -D INPUT -p tcp -m multiport --dports ssh -j f2b-sshd
iptables -w -F f2b-sshd
iptables -w -X f2b-sshd -- returned 1
2016-08-13 05:43:23,667 fail2ban.actions        [1011]: ERROR   Failed to execute ban jail 'sshd' action 'iptables-multiport' info 'CallingMap({'ipjailmatches':  at 0x182b050>, 'matches': u'2016-08-13T05:43:07.237432 skvm1.powervps.ru sshd[850]: Invalid user admin from 91.224.160.106\n2016-08-13T05:43:09.504130 skvm1.powervps.ru sshd[852]: Invalid user admin from 91.224.160.106\n2016-08-13T05:43:11.811482 skvm1.powervps.ru sshd[856]: Invalid user admin from 91.224.160.106\n2016-08-13T05:43:14.043115 skvm1.powervps.ru sshd[858]: Invalid user admin from 91.224.160.106\n2016-08-13T05:43:22.962543 skvm1.powervps.ru sshd[878]: Invalid user support from 91.224.160.106', 'ip': '91.224.160.106', 'ipmatches':  at 0x181ded8>, 'ipfailures':  at 0x182b0c8>, 'time': 1471056203.463139, 'failures': 5, 'ipjailfailures':  at 0x182b140>})': Error stopping action

Сначала я грешил на использования ключа iptables -w в добавляемых правилах.

nano /etc/fail2ban/action.d/iptables-common.conf

В конце файла вы увидите параметр lockingopt и комментарий к нему:

# Option:  lockingopt
# Notes.:  Option was introduced to iptables to prevent multiple instances from
#          running concurrently and causing irratic behavior.  -w was introduced
#          in iptables 1.4.20, so might be absent on older systems
#          See https://github.com/fail2ban/fail2ban/issues/1122
# Values:  STRING
lockingopt = -w

Тогда я решил проверить версию установленного пакета:

# iptables --version
iptables v1.4.21

Но причина была не в этом. После продолжительного гугления, проблема оказалась связана с конфигом jail.local, в который вносит изменения VMmanager в процессе установки. Чтобы починить fail2ban, откройте файл:

nano /etc/fail2ban/jail.local

Закомментируйте содержимое файла, и добавьте строки как в примере ниже:

# ISPsystem start
#[sshd]
#maxretry = 5
#enabled = true
# ISPsystem end

[DEFAULT]
bantime = 3600
banaction = iptables-multiport

[sshd]
maxretry = 5
enabled = true

После перезапуска fail2ban, с довольным видом любуемся на результат:

2016-08-14 10:36:01,828 fail2ban.jail           [23203]: INFO    Jail 'sshd' started
2016-08-14 10:36:01,947 fail2ban.actions        [23203]: NOTICE  [sshd] Ban 78.47.79.193

Настройка iptables для IPv6

Ранее я уже описывал процесс настройки iptables для Linux VPS. В этой записи я расскажу как использовать аналогичные правила для IPv6-подключения. В Linux для работы с протоколом IPv6 есть отдельная версия утилиты iptables — ip6tables.

В примере ниже вы можете увидеть набор правил для ip6tables, которые я использую на своем WEB-сервере. Как вы уже заметили, список достаточно небольшой. Разрешены входящие ICMP-пакеты и открыты порты 80 и 443.

ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT

ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
ip6tables -I INPUT 1 -i lo -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j ACCEPT

ip6tables -A INPUT -p tcp --dport http -j ACCEPT
ip6tables -A INPUT -p tcp --dport https -j ACCEPT

Для того чтобы сохранить настройки, выполните команду:

ip6tables-save > /etc/ip6tables.conf

Чтобы восстановить настройки ip6tables:

ip6tables-restore < /etc/ip6tables.conf

Сохранить/восстановить настройки iptables

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

Чтобы быстро восстановить настройки iptables, можно сохранить текущую конфигурацию в текстовый файл. Для этого в начале необходимо добавить все правила, а затем чтобы сохранить настройки iptables в текстовый файл, выполним команду ниже:

iptables-save > /etc/iptables.conf

Для того чтобы восстановить настройки iptables, выполните команду:

iptables-restore < /etc/iptables.conf

Если необходимо автоматически восстанавливать настройки iptables после каждой перезагрузки сервера, добавьте команду в содержимое файла /etc/rc.conf