Назад | Перейти на главную страницу

Как установить максимальное количество подключений с помощью nftables?

Я хочу ограничить количество одновременных подключений к данной службе, работающей на сервере 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  }
    }
}