Я хочу ограничить количество одновременных подключений к данной службе, работающей на сервере Linux. Насколько я понимаю, это можно сделать в iptables
используя connlimit
модуль. Так, например, если я хотел ограничить количество одновременных подключений к моему SSH-серверу (и предполагая, что политика по умолчанию отклонена), тогда это должно разрешить 10 одновременных подключений, при этом 11-е будет отклонено (записано из памяти):
iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-upto 10 -j ACCEPT
Дело в том, что на новых серверах, которые я создаю, я хочу реализовать брандмауэр, используя nftables
. Хотя я могу найти connlimit
упомянутый на странице руководства, он просто указывает consider native interface. Refer to Meters
. Порывшись вокруг Meters, хотя это выглядит потрясающе для ограничения скорости, я не могу найти ничего, что предполагало бы, что я могу сделать эквивалент connlimit
.
Итак, учитывая, что я хочу использовать nftables
, как мне создать правило, которое будет соответствовать только до X одновременных подключений?
Есть новое расширение nft_connlimit это было добавлено начиная с ядра Linux 4.18, обеспечивая ct count
выражение.
В этом случае эквивалентные правила (с нуля) будут такими:
nft flush ruleset
nft add table ip filter
nft add chain ip filter input '{ type filter hook input priority 0; }'
nft add rule ip filter input tcp dport 22 ct count 10 counter accept
# nft add rule ip filter input tcp dport 22 counter reject with tcp reset
Некоторые замечания:
По-прежнему counter
не является обязательным и используется для получения счетчика с nft list ruleset
чтобы узнать, сколько раз сработало правило.
Замена прежде всего ip
с участием ip6
получит эквивалент для IPv6. Теперь что интереснее использовать inet
чтобы получить комбинированный подсчет SSH-подключений IPv4 и IPv6 вместе, так как они учитываются conntrack вместе.
Следует избегать использования ядер между 4.19.0 и 4.19.9, потому что использование этой функции, скорее всего, приведет к сбою хоста. (Скоро) ядро 4.20 и ядро 4.19.10 включают несколько патчей, связанных с conncount, исправлением сбоев и неправильного подсчета. Состояние неизвестно для ядра 4.18.x.
ОБНОВИТЬ: ограничение на сеть, а не только на IP, что эквивалентно iptables ' --connlimit-mask
Перечитывать скудная документация из начального патча в списке рассылки netfilter-devel, ct count
не ограничивается автономным использованием (или ограничивается приведенным выше примером). Его можно использовать в meter
выражение / список для более сложного использования.
Если кто-то хочет отклонить подключения к порту 2222 (где какой-то процесс прослушивает) более 3 подсчетов подключений на любой случайный / 24 сетевой исходный IP-адрес, следует использовать это правило (начиная с nft 0.9.0 / kernel 4.19.10):
nft add rule ip filter input tcp dport 2222 meter test-2222-count-meter '{ ip saddr & 255.255.255.0 ct count over 3 }' counter reject with tcp reset
Это создаст метр список назван test-2222-count-meter
который будет динамически добавлять соответствующие данные «карты» (для каждой другой сети / 24, соответствующей соединению). Я не уверен, удаляются ли устаревшие данные (например, сети / 24, больше не имеющие подключения) через сборку мусора или нет.
Содержимое счетчика может быть перечислено (он не будет показывать достигнутый счетчик, а только динамически добавляемые «карты» при появлении новых сетей). Например, после некоторых подключений из 10.0.3.1
, 10.0.3.66
, 10.0.4.5
и 172.31.4.5
:
# nft list meter ip filter test-2222-count-meter
table ip filter {
meter test-2222-count-meter {
type ipv4_addr
size 65535
elements = { 10.0.3.0 : ct count over 3 , 10.0.4.0 : ct count over 3 , 172.31.4.0 : ct count over 3 }
}
}