Pull to refresh

Comments 33

Есть (overflow:permissive)

Скорее уж overflow:deny-all плюс фиксированный IP для аварийного доступа в PerSourcePenaltyExemptList

А permissive, если я правильно понял, при достаточно мощной атаке как раз позволит пробить PerSourcePenalty и загрузить уже основной процесс sshd, так что и администратор не пробьётся.

Спасибо за комментарий. Думаю, что при достаточно мощной атаке не только эта фича не поможет, а, в принципе, ничего не спасет. Но, как мне кажется, критичные сервера, на которые проводят мощные атаки, не святят ssh наружу. По крайне мере, не должны светить.

Вообще бы с этим вопросом разобраться, если уж использовать PerSourcePenalty. Сейчас перечитал man sshd_config и, скорее всего, да, я изначально понял этот механизм неправильно.

Режим overflow включается, если количество IP (а не подключений!) превышает max-sources4 / max-sources6, которые каждый по дефолту 65536. Что-то у меня подозрения, что при атаке с такого количества адресов средний сервер действительно умрёт куда раньше, чем до этого overflow, какой бы режим ни был выбран, вообще дойдёт дело. Да и вообще, для нас простых людей гораздо реалистичнее сценарий, когда несколько сошедших с ума ботов долбятся с одних и тех же IP каждые N миллисекунд, чем когда идёт DDoS с тысяч IP, да ещё и именно на SSH. Первое у себя видел, от второго Бог пока миловал :)

А вот есть ли механизм защиты от перегрузки процесса при большом количестве одновременных соединений (а не IP)? Я такого не нашёл. Получается, что если sshd-session захлебнётся, мы теряем пациента. А захлебнётся он, IMHO, всё-таки быстрее, чем nftables, работающий в kernel space. Так что ещё один плюсик в карму fail2ban (помимо того, что он нам, конечно, и для других jail'ов всё равно нужен)

можно попробовать на тестовом стенде запустить многопоточный брутфорс при чем с нескольких IP. Но это нужно делать когда сервера физические. Намоем стенде все виртуалки, не думаю, что при таком сетапе эксперимент будет чистым. Так как брут сам по себе будет нагружать ЦПУ, и это может сказаться на подопытной ВМ.
Я, кстати, не уверен, что такую нагрузку можно сгенерировать таким способом. Хотя идея привлекательная. Было бы интересно такое реализовать.
Ну и как я писал в статье, наличие этой фичи, не означает, что f2b теперь не нужен.

У меня есть физические (собственно, только на них SSH наружу и торчит), но я не настолько заинтересовался вопросом, чтобы так заморочиться :)

Понимаю. У меня просто спортивный интерес. Я из пачнота сначала вообще не понял про что речь. Потом погуглил немного и не нашёл чего-то, что объяснило весь функционал. Решил разобраться. Так статья и появилась.

Если стоит как в Azure по умолчанию - аутентификация только по ключу, то всё это не актуально?

И хотел ещё уточнить - а за сколько не продаёте?

аутентификация только по ключу, то всё это не актуально?

Так мы ж защищаемся не от того, что кто-то реально подберёт пароль (у тех, кто дошёл до настройки подобных механизмов, в любом случае или только по ключу, или пароль, который подбирать вечность), а от того, чтобы долбящиеся в надежде подобрать пароль боты нам сервер не нагружали. А они всё равно долбятся и пытаются авторизоваться по паролю, даже если сервер принимает только ключи.

Понял, спасибо большое

Нет, аутентификация по ключу спасает от того, что пароль всё таки подберут. Но пытаться всё равно будут, так как снаружи не видно пароль у Вас там или ключи.

Уточняю, ни за сколько не продаю =)

Ясно, спасибо за объяснение и за статью. Есть повод теперь её внимательно прочитать.

снаружи таки видно, но некоторые тупые боты все равно долбятся, даже если ssh сервер явно отвечает, что только по ключу)

А как же:

KbdInteractiveAuthentication no

сразу возвращает [Permission denied (publickey)] без возможности ввода пароля

Ключи защищают от взлома, а не от нагрузки. Толпа ботов легко положит тебе sshd просто попытками рукопожатий

Когда количество отслеживаемых источников превышает лимит, сервер переходит в «мягкий» режим: перестаёт добавлять новые IP в таблицу штрафов, но не блокирует их. Это предотвращает DoS-атаку на сам механизм защиты. Эффективность механизма при этом значительно снижается.

По-моему, у вас тут фактическая ошбка: тут утверждается, что при заполнении таблицы новые соединения автоматически разрешаются. Но давайте посмотрим документацию:

There are two operating modes: deny-all, which denies all incoming connections other than those exempted via PerSourcePenaltyExemptList until a penalty expires, and permissive, which allows new connections by removing existing penalties early (default: permissive).

То есть, это нет так — сервер продолжает добавлять новые записи, но чтобы освободить под них место в таблице, выкидывает наименее заштрафованные старые. Можно даже заглянуть в исходники и увидеть там красноречивый комментарий:

/* Delete the soonest-to-expire penalties. */

https://github.com/openssh/openssh-portable/blob/ac4a41265a3beccba7dc6f45c657298311280f01/srclimit.c#L311

Спасибо за уточнение, поправил этот момент в статье. Карму, к сожалению, начислить не дает. По этому могу только плюсануть.

Ещё одна мысль возникла - это же дело надо как-то мониторить (и просто статистики ради, и чтобы отлавливать аномальные всплески). Для fail2ban есть экспортер, а тут что-то сходу ничего готового из коробки не нашёл. Хотя написать тривиально, если формат лога стабильный. Можно даже не полноценный экспортер, а скриптик, который пишет файл для textfile collector node-exporter'а.

Сервис можно, он в journal пишет события, а syslog-ng разбирай как хочешь, ну или rsyslog настроить логика та же

[Unit]Description=Forward SSH penalty events to central syslogAfter=network.target sshd.service[Service] Type=simple ExecStart=/bin/sh -c 'journalctl -u sshd -f --output=cat -n0 | grep --line-buffered "activating.*penalty" | nc logs.company.ru 514' Restart=always RestartSec=5 User=root[Install] WantedBy=multi-user.target

Fail2Ban нужен. Он более универсален, например у меня он настроен на тех, кто ищет на сайте .env, .git да и просто конфиги от вордпресса. А, ну да, ещё банит всех, кто запрашивает .php файлы.

Плюс, насколько я понимаю, механизм фильтрации Fail2Ban работает на ядерном уровне, в данном случае фильтрация реализована на уровне приложения. Поэтому я не стал бы так оптимистично оценивать ресурсоемкость этой функции. Фича удобная, если требуется защита только для ssh, так как не требует развёртывания и настройки дополнительного программного обеспечения. Если Fail2Ban уже развёрнут, то лучше (имхо) ограничениями управлять централизованно.

Нет, сам Fail2Ban не работает на уровне ядра. Это userspace-демон, который крутится как обычный процесс и взаимодействует с системой через уже существующие механизмы ядра. По факту, f2b читает логи и на основании их производит какие-то действия.
В статье я подвел итог, что "новая" фича не заменяет f2, а дополняет. Тем более, что последний не только с ssh работает.

Если Fail2Ban уже развёрнут, то лучше (имхо) ограничениями управлять централизованно.

в поведении по умолчанию поведение достаточно мягкое, если не тюнить "под себя", то стоит хотя бы не выключать. Хуже не будет, а нагрузку на сервер может снизить, при сильном брутфорсе.

На уровне ядра работают правила блокировки/фильтрации, которые формирует F2B. В данной реализации, насколько я понимаю, блокировка/фильтрация на уровне userspace. За информацию про такую возможность спасибо. Её наличие целесообразно учитывать при принятии решений об организации защиты.

Защита на уровне приложения тут выгоднее тем, что она вообще не тратит ресурсы на постоянное логирование и парсинг текста

Никто и не спорит, статья просто про то, что для базовой защиты ssh теперь из коробки есть встроенный инструмент

Ещё есть Crowdsec. Тоже настраивается как угодно, читает что угодно, анализирует что угодно. Блокирует тоже на любом уровне. Хоть через iptables/nftables блокируйте, хоть через nginx или traefik. А ещё капчи может показывать, если плагин для принятия решения это поддерживает.

max-sources6:65536 — то же для IPv6

Э… а можно лучше подсетями?.. :(

Можно

PerSourceNetBlockSize

Specifies the number of bits of source address that are grouped together for the purposes of applying PerSourceMaxStartups limits. Values for IPv4 and optionally IPv6 may be specified, separated by a colon. The default is 32:128, which means each address is considered individually.

И на PerSourcePenalties тоже распространяется.

Спасибо большое, Иван! Узнал из вашей статьи что появилась такая функция. Буду ей пользоваться.

Есть ещё port knoking

Вот там вообще всем отдается ошибка )

Заголовок так себе) fail2ban это ведь не только про ssh

fail2ban вообще не про это. Он ловит триггер и генерирует действие.
Например по неверному паролю к ssh блочит доступ источника к вебу.

Хорошая фича для серверов, куда лень тащить лишние зависимости. От скрипт-кидди спасет, а от направленного DDoS тут уже только на уровне L3/L4 резать надо

DDoS и на L7 распространяется.

И тогда резать приходится уже на уровне конечного сервиса/приложения.

Тот же waf для веб-сервисов этим занимается (crowdec etc.), напр.

Sign up to leave a comment.

Articles