iptables с hashlimit и «--state NEW» блокирует слишком много новых подключений

Я установил ограничение скорости, чтобы остановить атаки методом перебора на мой ssh-сервер. Я использую следующие правила iptables:

iptables -A INPUT -p tcp -m tcp --dport 22 -m hashlimit --hashlimit-upto 4/min
--hashlimit-burst 6 --hashlimit-mode srcip --hashlimit-name ssh
--hashlimit-htable-expire 60000 -m state --state NEW -j ACCEPT

iptables -A INPUT -m tcp -p tcp --dport 22 -m state --state NEW -j REJECT

Когда я открываю одно SSH-соединение (например, через PuTTY), а затем, через минуту, пытаюсь открыть другое (например, для передачи файла), второе соединение иногда отклоняется без ответа от сервера . Если мне удастся открыть второе соединение SSH, а затем я попытаюсь открыть третье соединение, это станет еще сложнее (высокая вероятность отсутствия ответа.)

Я убедился, что когда я отключаю вышеуказанные правила, все работает нормально. Увеличение - hashlimit-up до и / или - hashlimit-burst помогает, но не решает проблема полностью - это только снижает вероятность ее возникновения. Отказ по-прежнему случается, но если я отключу правило iptables, этого никогда не произойдет.

Что происходит? В приведенных выше правилах iptables говорится, что количество TCP-пакетов, связанных с новыми подключениями, должно быть ограничено до 4 в минуту. Так что я легко смогу открывать до 4 соединений в минуту.

1
задан 18 June 2020 в 01:00
1 ответ

(Отвечая на мой собственный вопрос, чтобы оставить запись для других.)

Ваше первое правило:

iptables -A INPUT -p tcp -m tcp --dport 22 -m hashlimit --hashlimit-upto 4/min
--hashlimit-burst 6 --hashlimit-mode srcip --hashlimit-name ssh 
--hashlimit-htable-expire 60000 -m state --state NEW -j ACCEPT

не делать того, что, по вашему мнению, он делает. Когда вы говорите -m tcp, -m hashlimit и -m state, вы вызываете три модуля iptables. Вы думаете, что хеш-лимит будет применяться только к пакетам, удовлетворяющим всем остальным условиям правила. Но это не то, что происходит. Вместо этого модули выполняются в порядке, указанном в правиле. (Насколько мне известно, этот факт не является интуитивно очевидным и нигде явно не задокументирован.)

В приведенном выше правиле -m hashlimit предшествует -m state. Это означает, что каждый TCP-пакет (а не только НОВЫЙ пакет) будет первым отправляться в модуль ограничения хэшей. Hashlimit подсчитает этот пакет и, если он находится в пределах 4/мин, он будет передан в состояние -m. Только теперь модуль state может просмотреть пакет и проверить, представляет ли он новое соединение.

В вашем случае вы открываете свое первое SSH-соединение, которое время от времени передает некоторые пакеты.Эти пакеты не являются «НОВЫМИ» пакетами, поэтому они не отбрасываются (условие --state NEW во втором правиле не выполняется). Но они обрабатываются по хэшлиму и будут учитываться в вашем 4/мин лимите. Если они приходят достаточно быстро, они израсходуют квоту, и если вы затем попытаетесь открыть другое соединение, первый пакет для этого соединения столкнется с квотой, и ваше первое правило не будет соответствовать.

Очевидным решением является изменение порядка:

iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m hashlimit
--hashlimit-upto 4/min --hashlimit-burst 6 --hashlimit-mode srcip --hashlimit-name ssh 
--hashlimit-htable-expire 60000 -j ACCEPT

В общем, я думаю, что хорошее эмпирическое правило состоит в том, чтобы всегда ставить -m hashlimit последним в правиле iptables.

4
ответ дан 17 June 2020 в 22:00

Теги

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