Все мои серверы используют SSH на нестандартном порту (987), и я хочу навсегда заблокировать все IP-адреса, которые пытаются подключиться к порту 22.
Теперь у меня есть правило iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j DROP
но это правило не добавляйте IP в iptables как заблокированный, только текущее соединение разрывается.
Может ли iptables добавить IP как глобально заблокированный (отключить соединение на любом другом порту) после первой попытки соединения на порту 22?
Полные правила:
iptables -N SSH
iptables -A SSH -p tcp -m tcp --dport 22 -m state --state NEW -j DROP
iptables -A SSH -p tcp -m tcp --dport 987 -m state --state NEW -m recent --rcheck --set --rsource
iptables -A SSH -p tcp -m tcp --dport 987 -m state --state NEW -m recent --rcheck --update --seconds 300 --hitcount 4 --rsource -j DROP
Спасибо!
(Я использую iptables v1.8.4 (устаревшая версия))
ОБНОВЛЕНИЕ 1 : Благодаря @AB
Подключения к порту 22, управляемому ipset с блоком IP-адресов 86400 секунд (1 день).
Подключения на порт 987 ма naged iptables с блоком 300 секунд после 4 попыток подключения (неудачных или успешных) в течение 300 секунд.
ipset create ssh22 hash:ip timeout 86400
iptables -N SSH22
iptables -A SSH22 -p tcp -m tcp --dport 22 -m state --state NEW -j SET --add-set ssh22 src
iptables -A SSH22 -m set --match-set ssh22 src -j DROP
iptables -N SSH
iptables -A SSH -p tcp -m tcp --dport 987 -m state --state NEW -m recent --name ssh --set --rsource
iptables -A SSH -m recent --name ssh --update --seconds 300 --reap --hitcount 4 --rsource -j DROP
ОБНОВЛЕНИЕ 2 : Окончательная iptables
рабочая версия:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -s XXX.XXX.XXX.XXX/32 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 987 -m state --state NEW -m recent --set --name ssh --rsource
-A INPUT -m recent --update --seconds 300 --reap --hitcount 4 --name ssh --rsource -j DROP
-A INPUT -p tcp -m tcp --dport 22 -j SET --add-set ssh22 src
-A INPUT -m set --match-set ssh22 src -j LOG --log-prefix "[SSH 22] " --log-level 4
-A INPUT -m set --match-set ssh22 src -j DROP
-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp --icmp-type echo-request -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 987 -j ACCEPT
-A INPUT -i lo -p all -j ACCEPT
COMMIT
недавний является ненормальным совпадением: оно не просто фильтрует, но также вносит изменения (что обычно выполняется в цели, а не в совпадении): изменение записей в списке . Его нужно использовать дважды, как вы уже делали в другом месте: один раз для установки списка и один раз в любом случае для проверки списка. Во второй раз не следует проверять что-либо еще, поэтому любое соединение с IP-адресом к чему-либо будет совпадать и отключаться, а не только к порту 22.
SSH вашей пользовательской цепочки должен вызываться из INPUT (или FORWARD ) перед использованием любого общего правила с отслеживанием состояния, такого как -m conntrack --ctstate ESTABLISHED, RELATED -j ACCEPT
.
Итак, замените начало вашей цепочки:
iptables -N SSH
iptables -A SSH -p tcp -m tcp --dport 22 -m state --state NEW -m recent --name banip --rsource --set -j DROP # -j DROP could be left: the next rule would do it.
iptables -A SSH -m recent --name banip --rsource --update -j DROP
You затем можно добавить свои дополнительные правила для порта 987. Поскольку они не указывают имя списка, они будут использовать DEFAULT
, что не будет мешать banip
.
Должен вы хотите, чтобы срок действия этих IP-адресов истекал через некоторое время (например, 12345 с), вы также должны добавить, например, - секунды 12345 --reap
после параметра - update
как задокументирован .
По умолчанию список последний может принимать 100 записей, поэтому для использования недавнего в качестве запрещенного списка, xt_recent модуль ядра должен быть загружен, [11 73112] перед загрузкой правил iptables с опцией типа ip_list_tot = 65535
, потому что список, который может содержать только 100 записей, вероятно, недостаточно велик для реализации запретного списка. Этот параметр является глобальным для всех размеров списков.
Вам также следует рассмотреть возможность использования вместо него ipset , как описано ниже, поскольку он обычно более гибкий.
После некоторого уровня сложности достигается, лучше использовать сопутствующий фреймворк ipset . ipset может обрабатывать произвольные большие хешированные списки различных сетевых типов (IP-адрес, (TCP и / или UDP) порт ...).
Вы можете сделать это с помощью iptables ] set
match и SET
target + ipset
. ipset будет действовать как память.
Создайте набор с помощью вспомогательного инструмента ipset
:
ipset create banip hash:ip
Это создаст хешированный набор с 65536 записями по умолчанию, что намного лучше, чем 100 или 255. См. Руководство, чтобы узнать, как создать более крупный набор, если необходимо (однажды определенный размер набора не может быть увеличен из пути пакета, только путем дальнейшего использования команды ipset
). Вы можете предварительно заполнить, сохранить, восстановить, перечислить содержимое этого набора и т. Д. С помощью соответствующих команд ipset
.
Приведенные выше правила можно заменить на:
iptables -N SSH
iptables -A SSH -p tcp -m tcp --dport 22 -m state --state NEW -j SET --add-set banip src
iptables -A SSH -m set --match-set banip src -j DROP
Если вы хотите, чтобы записи истекли Самый простой - создать набор с параметром тайм-аута.
Один из методов для fail2ban - использовать ipset (но триггер исходит из файлов журнала, а не пути пакета
Возможны и другие методы, например, использование nftables (и его встроенных наборов ) вместо iptables + ipset . Не стесняйтесь его протестировать.
Я согласен с ответом @JA.
Однако я сделал хочу поделиться своим проектом XDP Firewall с открытым исходным кодом здесь , который должен быть в состоянии достичь этого. Инструмент использует XDP и должен уметь блокировать трафик намного быстрее, чем IPTables, если ваша сетевая карта поддерживает XDP-native. В противном случае,она должна иметь ту же скорость, что и IPTables, если вы используете режим XDP-generic / SKB (большинство сетевых адаптеров / современных ядер должны поддерживать это).
Единственными недостатками использования этой программы являются:
Он использует файл конфигурации для определения правил фильтрации. На данный момент нет команд для добавления / удаления правил фильтрации.
После перезапуска программы черный список IP-адресов будет удален.
Я надеюсь реализовать команды, которые будут добавлять правила фильтрации и сохранять их автоматически в будущем вместе с возможностью навсегда блокировать IP-адреса, которые также поддерживают перезапуск.
В вашем случае должна работать следующая конфигурация:
interface = "changeme";
updatetime = 15;
filters = (
{
enabled = true,
action = 0,
tcpopts = (
{
enabled = true,
dport = 22,
blocktime = 9999999999
}
)
}
);
Это будет блокировать пакеты, нацеленные на порт назначения 22 через TCP для 9999999999
секунд (при необходимости вы можете увеличить это значение, поскольку параметр конфигурации blocktime
относится к типу uint64_t
).
Надеюсь, это поможет в вашем случае!
IPtables не может самостоятельно управлять такого рода динамическим анализом. Судя по вашему описанию, на самом деле вам нужен инструмент, который управляет такими правилами за вас.
В целом, я могу порекомендовать fail2ban
и denyhosts
для этого конкретного случая, но могут быть и другие.
Я успешно попробовал оба с аналогичным вариантом использования. Вы можете настроить разные правила для разных портов и протоколов, срок действия правила, максимальное количество попыток и многие другие параметры.
Официальные ссылки: