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

Как упомянул Хауке, проблема скорее всего в SELinux. Вы пытаетесь изменить разрешения для другого пользователя/режима? ls -lZ предоставит вам файл с конкретным контекстом selinux.

Примером может быть:

rw-r--r--. root root system_u:object_r:etc_t:s0       rhel-source.repo

если контекст неправильный, это не сработает.
в этом случае # restorecon /etc/yum.repos.d/*исправит контексты.

Что касается вашего скрипта, в конце вам, вероятно, следует выполнить команду restorecon в каталоге /etc/yum.repos.d, чтобы убедиться, что контексты в файлах репо правильные. После этого ОС будет работать с ними.

2
13.11.2019, 12:28
1 ответ

Вы можете сделать это с помощью nftables , используя ядро ​​>= 4.18 (, протестированное здесь с ядром 5.3 )и nftables >= 0.9.1 для его connlimit счетчик функция (и динамический флаг ). Это более гибко, чемiptables connlimit , потому что вы можете выбрать при создании метранабор , селектор (с )и маски, на которых ограничение будет применяться, в то время как для iptables существует только несколько возможных селекторов (, не включающих порт ), что, вероятно, потребовало бы иметь одно правило для каждого порта.

Вот адаптация примера из вики , за исключением того, что мы отслеживаем входящие TCP-порты вместо исходящих IP-адресов, чтобы ответить на вопрос ОП. Любое TCP-соединение с одним и тем же локальным портом между 2300 и 2500 после того, как уже установлено два, будет отклонено TCP RST. Я понимаю, что ct state new — это просто оптимизация, позволяющая избежать попыток добавить из пути пакета новый элемент для каждого входящего пакета в соединении, а не только первого.

nft файл правил для загрузки сnft -f:

flush ruleset

table ip my_filter_table {
       set my_connlimit {
               type inet_service
               size 65535
               flags dynamic
       }

       chain my_input_chain {
               type filter hook input priority filter; policy accept;
               tcp dport 2300-2500 ct state new add @my_connlimit { tcp dport ct count over 2 } counter reject with tcp reset
       }
}

Соответствующие соединения будут создавать записи в my _connlimit:в записях селектора, которые создаются динамически, а не в текущих счетчиках (, которые обрабатываются connlimit с использованием conntrack записи пользователя ). Для этого конкретного случая, вероятно, было бы достаточно установить размер набора в 2500 -2300+1=201. Добавленные элементы автоматически исчезнут (по крайней мере в ядре 5.3 ), когда больше не будет связанного счетчика (, т.е. :все соединения на этом порту были закрыты ).Пример после установления одного или двух соединений на порту 2301:

# nft list set ip my_filter_table my_connlimit
table ip my_filter_table {
        set my_connlimit {
                type inet_service
                size 65535
                flags dynamic
                elements = { 2301 ct count over 2  }
        }
}

UDP работал бы так же, за исключением того, что conntrack обычно истечет время ожидания записи между 30 и 120 с (было 180 с до )после последней активности, поскольку фактического соединения нет. Также можно использовать конкатенациювместо простого набора в качестве счетчика, например, чтобы ограничить это для каждого IP-адреса сервера плюс порт , а не просто для каждого порт для сервера с несколькими IP-адресами, например:

flush ruleset

table ip my_filter_table {
       set my_connlimit {
               type ipv4_addr. inet_service
               size 65535
               flags dynamic
       }

       chain my_input_chain {
               type filter hook input priority filter; policy accept;
               tcp dport 2300-2500 ct state new add @my_connlimit { ip daddr. tcp dport ct count over 2 } counter reject with tcp reset
       }
}

Примечание :, чтобы избежать подсчета локальных соединений в счетчике, соединения, проходящие через устройство lo , следует обходить. Например:

# nft insert rule ip my_filter_table my_input_chain iif lo accept
1
27.01.2020, 22:24

Теги

Похожие вопросы