Как стать автором
Обновить

Укрепление Nginx с помощью Fail2ban: тестируем и оцениваем «профит»

Время на прочтение10 мин
Количество просмотров20K
Всего голосов 53: ↑51 и ↓2+49
Комментарии47

Комментарии 47

Спасибо за статью! Использую fail4ban как обязательный инструмент для защиты от брутфорса по ssh. Подключение nginx по вашей схеме, думаю, тоже будет полезным.

Использую fail4ban как обязательный инструмент для защиты от брутфорса по ssh.

не проще поставить нормальные пароли? а лучше вовсе запретить парольную авторизацию в ssh

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

Наличие нормального пароля (да и безпарольная авторизация тоже) вообще никак не спасают от толп ботов, постоянно тыкающих в стандартные порты с минимальной задержкой между попытками

это вызывает какие-то проблемы?

Ага. Сервер лагает. Потому что ботов - дофига. И если они тебя выбрали - то придет не один ботнет, а сразу штук 5-10 разных. И долбиться они будут одновременно.
Еще очень люблю ботнеты, которые заводят на сайте аккаунты - постоянно, снова и снова, десятками и сотнями в час. Если с ними не бороться, то через год у тебя бОльшая часть базы данных будет занята только вот этими пустыми аккаунтами.

Сервер лагает. Потому что ботов — дофига

странно, никогда такого не замечал. даже на виртуалках в минимальной конфигурации за несколько баксов в месяц.


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

fail2ban мне не кажется удачным средством для решения этой проблемы

странно, никогда такого не замечал

Иногда прилетает реально много ботов. Редко, но бывает. Да и в целом - ну напрягает же, что постоянно долбятся - а вдруг получится? Ну чисто по теории вероятности)

fail2ban мне не кажется удачным средством для решения этой проблемы

Угу, пока решаю собственным костылем на уровне php - перехватываю все post-запросы и проверяю по набору примитивных условий. От 99,9% ботов это спасает, остальных - мало и особого вреда они нанести не могут (ну и их можно тупо по ip вручную забанить)

fail2ban вообще решение так себе, при больной атаке он съедает все русурсы сервера для анализа логов, поделка фигова...

Не первый раз встречаю, как пишут детальное регулярное выражение, и не понимаю, зачем?
например:

failregex = ^\s*[[a-z]+] \d+#\d+: *\d+ limiting requests, excess: [\d.]+ by zone "(?:%(ngx_limit_req_zones)s)", client: <HOST>,

Почему бы не записать проще:
failregex = .+ limiting requests, excess: .+ client: <HOST>,
?

В регулярках хороший вариант - описывать подробно шаблон выражения. Слишком широкое выражение допускает намного больший разброс совпадающих значений. В случае с большим количеством логов могут быть пересечения в найденных логах.

В конкретно этом случае соглашусь, допустимо указать Ваш вариант.

Такая защита морально устарела и поможет на совсем уж простых ботнетах. Можно ее "наворачивать" но гибкости не получится. Как вариант, рассмотреть уже более продвинутый варианты где для блокировок используются наполняемые вредоносными тредами базы. Например, crowdsec или bitninja

Crowdsec - действительно хорошее open source 'продолжение' fail2ban. А bitninja только в полных платных тарифах даёт защиту от Dos.

Несомненно, стоит оценивать критичность защищаемого сервиса и использовать более эффективные распределенные системы очистки трафика

Будем реалистами - от brute force (подбор паролей) это помогает, от DDoS - не смешите.
Без "внешней" фильтрации с DDoS не справиться.

Не совсем так. Если речь о веб-приложении, которое работает исключительно через TLS и реагирует только на TCP трафик 443 порта, то средства fail2ban дают ощутимый эффект. Даже довольно крупные ботнеты быстро оказываются в клетке. Но, к сожалению, в клетке оказываются внешние IP адреса. То есть, клиенты за NAT, в котором так же находится бот, оказываются заблокированными вместе с ботом. Раньше это было неприятно. Сейчас, в связи с более широким распространением IPv6, уже терпимо.

Вам никогда не заливали по несколько гигабит UDP или HRE трафика? Не попадали под wordpress ping с тысячи хостов? А как fail2ban потребляет ресурсы? Он легко по пожиранию ресурсов переплёвывает целевые приложения на сервере. Так же знаменит своими ложными срабатываниями, иногда превращающих сервер в недоступную вещь в себе. Поэтому требует пристального и постоянного внимания.
В настройках nginx есть настройки, позволяющие блонировать нежелательный трафик. А в связке с Lua это можно делать более гибко.

На сервер, где закрыты все порты, кроме одного TCP, в веб-приложение, которое просто обеспечивает REST API и принимает исключительно авторизованных клиентов? Нет, не заливали )

Принимающие порты почти не важны. Вам просто забивают канал до всего вашего стека.

fail2ban способен защитить от слабого L7-DDoS.

Давайте по порядку. Если речь о перегрузке входящего канала, то это вообще не моя забота, а ЦОД, перекрывающего ответы на широковещательные ICMP или UDP пакеты. Моя забота лишь дропать как UDP, так и ICMP на файрволле и не забыть о net.ipv4.tcp_syncookies = 1.

Для того, чтобы перегрузить сервер, нужно вообще сначала авторизоваться.

Для того, чтобы перегрузить исходящий канал, надо чтобы размер моего ответа был существенно больше, чем размер запроса. Начинается это с размера HELLO, которое у сервера намного больше, чем у клиента. Но так как это уже рукопожатие TLS, то к этому моменту fail2ban становится применим.

Давайте по порядку.

Это атака на истощение канала. Могут даже все до одного порта закрыты, и ничего не поможет. А когда сервер поднят у хостера (распространённое решение), то ваш сервер быстро потушит хостер, может даже на совсем. Чтобы не вызывать аффекта других клиентов. Причём, атака может быть кратковременной. Буквально нескольких секунд хватит.

Если речь о перегрузке входящего канала, то это вообще не моя забота, а ЦОД,

Когда размещаете сервер в ЦОД, заключается договор кроме прочего по оплате входящего/исходящего трафика. И ЦОДу может быть по барабану насколько легитимный к вам льётся трафик. Он просто выставит счёт в конце месяца. Допустим, вам наваливают 100 Мб/с совершенно левого трафика по протоколу gre. Он никак не влияет на рабочий трафик по ТСР, никоем образом не трогает файервол и не укладывает широкий канал в 1 Гб/с. Но ЦОД считает весь трафик и в конце месяца выставляет счёт за 32,85 Тб мусорного трафика и плюс ваш рабочий трафик.

широковещательные ICMP или UDP пакеты

Разве такие бывают?

Для того, чтобы перегрузить сервер, нужно вообще сначала авторизоваться.

Имеется в виду не перезагрузка сервера (рестарт ОС), а перегруз сетевого канала трафиком. Сетевой карточке всё равно какие в sysctl.conf указаны правила и что там дропается в файерволе, когда она работает на пределе своих 1 Гб/с.

fail2ban практически никак не защищает от запросов, которые нагружают, а иногда укладывают СУБД. Достаточно неспеша слать запросы со скоростью один запрос в 5 - 10 секунд и будет невероятное веселье: вэб-сервер и бэкенд совершенно ненагружены, а база еле вывозит - по факту сайт кое-как отрабатывает запросы отличные от /. Это не такая распространённая атака как заливание запросов в корень сайта, чаще встречается, когда сайтом сайтом решили заняться чуть серьёзнее. Есть ещё более изощрённые атаки. И на TLS тоже.

Это атака на истощение канала.

Я же написал уже - это не моя проблема, а ЦОД.

заключается договор кроме прочего по оплате входящего/исходящего трафика

Только TCP на 443 порт, что и указано в договоре. И по фиг мне на GRE, UDP, ICMP и т.п. Сами не заблокировали - сами и виноваты. Захотят судиться - пожалуйста. Я не заплачу им ни копейки, спокойно перенеся сервис в другой ЦОД.

> широковещательные ICMP или UDP пакеты

Разве такие бывают?

Зря Вы пытаетесь участвовать в профессиональной дискуссии ничего даже не слышав о Smurf и Fraggle атаках.

> Для того, чтобы перегрузить сервер, нужно вообще сначала авторизоваться.

Имеется в виду не перезагрузка сервера (рестарт ОС), а перегруз сетевого канала трафиком.

Где Вы увидели слово "перезагрузка"?

СУБД.Достаточно неспеша слать запросы

Ну если кого-то головы нет, то у него СУБД может принимать запросы без авторизации. Но я то явно указал:

нужно вообще сначала авторизоваться

И тут единственная проблема, которая как раз и решается fail2ban:

Начинается это с размера HELLO, которое у сервера намного больше, чем у клиента. Но так как это уже рукопожатие TLS, то к этому моменту fail2ban становится применим.

Я же написал уже — это не моя проблема, а ЦОД.

ну-ну. случаи, когда ЦОД просто гасит сервер, говоря «тут ДОС пришёл, идите куда-нибудь ещё» не так уж и редки.

И идет такой ЦОД в далекое пешее путешествие, потеряв клиента из ТОП-20 крупнейших частных компаний РФ. Хотя пока мне такой ЦОД не попадался. Как-то прогибались под клиента.

просто к вам хороший ddos, который кладёт каналы ДЦ, не приходил )

Разные приходили. В Москве от ЦОД к M9 два по 100 гигабит. Часть оборудования непосредственно в M9. Если честно, не припоминаю ни одного случая, когда каналы M9 положили. Пример приведете?

может быть ресурсы в рунете никому и не интересны, крупные западные игроки говорят о атаках в терабиты в секунду.
хотя, помнится, несколько лет назад qiwi успешно ддосили, ЕМНИП там речь шла о сотнях гигабит.

Проблема в том, что это надо через М9 сначала эти терабиты прогнать. А они чуть ли не первые в РФ по компетенции в борьбе с DDoS атаками.

Так же следует понимать, что публичных ресурсов то у меня нет, в отличии от Qiwi. Все или через двухфакторную авторизацию, или через ViPNet, где заставили, или pre-shared keys для ботов, или вообще внутри intranet VPN по Kerberos.

не припоминаю ни одного случая, когда каналы M9 положили. Пример приведете?

Как сейчас помню под конец 2016 года к ним прилетело среди ночи 600 Гб и вопль они тогда подняли знатный, что пришлось многим инженерам проснуться. А некоторым не удалось домой попасть. Так что было и у них веселье.

В контексте статьи: вы всё-таки рекомендуете fail2ban как современное средство защиты от нынешних атак? То бишь положившись на ваше профессиональное мнение, можно безбоязненно ставить и не боятся всяких wordpress ping атак, брута паролей и "пинга смерти"? Причём даже в случае, когда свой сайтик размещу у хостера (поднимать в облаке иногда дорого и муторно, идти в ДЦ со своим сервером тоже не с руки). Гарантировано будет работать, защищать от атак и при этом не выжирать ресурсы и не блокировать доступы, как некоторые антивирусные решения?

Так же следует понимать, что публичных ресурсов то у меня нет, в отличии от Qiwi. Все или через двухфакторную авторизацию, или через ViPNet, где заставили, или pre-shared keys для ботов, или вообще внутри intranet VPN по Kerberos.

Для доступа к форме двухфакторной авторизации надо же как-то подключаться, если это не в локальной сети происходит (тогда гарантировано никакая атака не страшна). Люди как-то подключаются из интернета для авторизации? Только не говорите, что у вас белые списки для доступа к форме авторизации.

Как сейчас помню под конец 2016 года к ним прилетело среди ночи 600 Гб

Ну вот, даже на такие копейки (для них) они очень оперативно отреагировали. И что-то не помню я, чтобы при этом какие-то хосты на M9 лягли. Я не утверждал, что M9 никогда не атаковали. Я просил пример, когда атака на них привела к отказу к обслуживанию. И не увидел от Вас такого примера.

В контексте статьи: вы всё-таки рекомендуете fail2ban как современное средство защиты от нынешних атак?

Как я уже неоднократно указывал выше, я рекомендую fail2ban для защиты TLS, чтобы не перегрузить исходящий канал серверным HELLO, который существенно больше клиентского.

Для доступа к форме двухфакторной авторизации надо же как-то подключаться

Все равно сначала TLS, а уже после установления сессии - логин, пароль и пин с RSA токена. Так что смотрим выше.

Все равно сначала TLS, а уже после установления сессии - логин, пароль и пин с RSA токена.

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

Как понял из ваших комментариев, вы рекомендуете этот продукт, потому что активно используете в вашей компании? Поэтому настоятельно рекомендуете. Также у вас довольно большая статистика по атакам, на основании которой можете утверждать, что атаки на протокол TLS превалируют над остальными типами атака, не исключено что значительно.

Ну если кого-то головы нет, то у него СУБД может принимать запросы без авторизации.

Посмотрите на большинство простых и популярных CMS (WP) и распространённых фреймворков (symfony, laravel и т. п.), а также сайты на них. Некоторые из них люди пилят в одиночку. Поэтому возможно всё.

атаки с перемешиванием очерёдностей отправки пакетов, или преждевременной отправки пакета FIN и прочие вариации на параметрах протокола.

Я изначально упомянул о необходимости установки net.ipv4.tcp_syncookies = 1, если TCP порт торчит в дикий интернет. Но это явно уход от темы про fail2ban.

Поэтому настоятельно рекомендуете.

Я бы не сказал, что настоятельно. Для легаси или блоба - это хоть какой-то выход. В самописном веб-сервисе эффективней все же делать защиту от DDoS на уровне OSI L7 в коде, а не долгими путями через файл журнала с поиском регулярных выражений.

Посмотрите на большинство простых и популярных CMS (WP)

Если выбираешь что-то простое и популярное, то о SLA и безопасности лучше забыть сразу. Или прятать это в интранет, что дает хоть какие-то гарантии.

атаки на протокол TLS превалируют над остальными типами

Не надо меня троллить. "Золотого молотка" не бывает. В сфере защиты от DDoS атак - тем более. Никакой самый продвинутый аппаратный комплекс не сможет защитить от DDoS атаки по TLS. Разве что подменяя сертификаты и декодируя траффик, что еще хуже.

Никакой самый продвинутый аппаратный комплекс не сможет защитить от DDoS атаки по TLS. Разве что подменяя сертификаты и декодируя траффик, что еще хуже.

Не открою никакого секрета, но большинство из известных компаний, предоставляющих защиту от DDoS атак, декодируют на своей стороне TLS трафик. Они специально для этого просят предоставить сертификаты. Несколько лет назад был довольно громкий скандал с cloudflare. При определённых запросах к сервису можно было получить содержимое кеша nginx с приватными данными.

Откройте секрет и назовите хоть одну такую компанию в РФ со ссылкой на соответствующее приложение к договору.

Вы уж простите, но уж лучше недоступность сервиса из-за DDoS, чем утечка конфиденциальных данных. Размеры потенциальных убытков на порядки различаются.

И это даже не затрагивая то, что не учитывая логику работы веб-приложения, хоть сколь-нибудь эффективно противостоять DDoS атаке по установленному TLS каналу все равно не получится.

Привеодил ранее пример с Cloudflare и тем как в содержимом кеша оказались чувствительные данные. Начто похожее было у Akamai, утверждать не буду. Только как вы лично представляете защиту от атаки на L7? У защищающей стороны будет только несвязный набор битиков в случае TLS.

Поэтому, когда с разработчиками садимся на начальном этапе наброски проекта, этот вопрос поднимается тоже. По моему опыту в 146% случаев крутят у виска и просто кивают в сторону TLS, который по их мнению спасёт ото всего. В таком виде проект уходит в разработку и переживает не один релиз. Рано или поздно приходят они самые атаки и начинается веселье. Помимо отваливающихся приложений и нехватки ресурсов может всплыть и эта штука. Когда она доходит до безопасников, веселье приобретает невыносимый характер - просто так прикостылить шифрование дело не такое простое.

Бывает интересная сторона поведения со стороны специалистов ops (sysops, devops, devsecops). Они слепо верят в идею, что настоящий IP адрес сервера нигде не должен светиться (а то вдруг злодеи атакуют ip адрес сервера напрямую), опэтому проект сразу размещают за CF (благо у него есть бесплатные планы защиты) ещё на этапе тестрирования.

Asterisk хорошо fail2ban прикрывал еще этак в 2005-2006 году.

У меня только один вопрос - а вы серьезно пишете про защиту от DDoS уже на клиентском порту в 2022 году? Даже не смешно, вы вроде как компания авторитетная...

А ничего смешного нет. Они пишут про атаки на L7, и fail2ban — вполне нормальный способ из «бесплатных». L2—L4 действительно фильтруются выше в нормальных ЦОД — статья не об этом.

да не нормальный он. слишком тяжеловесный, плюс сама идея блокировки по анализу логов выглядит плохо.
единственный плюс: его можно прикрутить почти ко всему, что шевелится пишет логи.
но использовать fail2ban в связке с nginx, серьёзно?

Любое решение, кроме сигнатурных, основано на анализе статистики сенсора. И логи сервера - это классический вариант.
А вы какое решение предпочитаете? Поделитесь мудростью, а лучше опытом, пожалуйста?

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


ну а защите от брутфорса паролей ИМХО не место на reverse proxy.


Любое решение, кроме сигнатурных, основано на анализе статистики сенсора. И логи сервера — это классический вариант

ну не самый лучший, но приемлемый.
а вот парсить их на перле — идея так себе.

для защиты фронта от излишней нагрузки в моих случаях отлично подошёл limit-req

ну и допишу: если возможностей ванильного нжинкса по лимитированию запросов не хватало бы, то смотрел бы на более сложные решения.


например, писать нужные сообщения в кастомный лог (в котором нет не относящихся к проблеме строк) в удобном для парсинга формате (да хоть json), ну и написать за вечер парсер на каком-нибудь go, который будет реализовывать функционал fail2ban, не такой гибкий, но более производительный.


другой вариант — взять модули для работы с мемкэшем/прометеем/etc из openresty и переместить большую часть логики прямо в nginx/openresty. но мне с первого взгляда кажется, что это решение будет проигрывать первому и по производительности, и по надёжности.


впрочем, уверен, что всё украдено до нас и за тот же вечер нагуглится готовое решение.


ну а правильнее всего, конечно, rate-limit реализовывать на фронте (притом делать его достаточно легковесным), ибо на прокси просто нет достаточной информации для отделения ботов от нужных посетителей.


P. S. ну и уже много раз написали, что от серьёзной атаки самому защититься невозможно, аплинк что в 1, что в 10 гигабит легко забивается мусорным трафиком даже небольшой по сегодняшним меркам атаки.

Расскажите как защищают от ddos сегодня.

Есть альтернативы Fail2Ban, не выжирающие такие кучи ресурсов?

Не эффективнее ли частоту запросов ограничивать сразу брандмауэром (iptables и т.п.)?

Типа

-A INPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW -m limit --limit 128/sec --limit-burst 64 -j ACCEPT

Пытался перенастроить на ipset, не взлетело. Поделитесь ссылкой на толковый мануал, если есть.

На несильно навороченном роутере (2 ядра 4 гига) постоянные пустые запросы в гигантском количестве намертво вешали fail2ban за 1-2 часа. Количество забаненных ip исчислялось десятками тысяч. Приемлемый выход найден только так: каждые 30 мин (по крону - подбирал экспериментально время) скриптом на питоне шерстил лог nginx и отбирал по своему условию примерно 1-2-3 тыс последних ... как их назвать? ддосеров? Сокращал список до уникальных и скармливал этот список ipset'у. Как итог - стало зна-а-а-чительно спокойнее.

Игрался ранее настройками nginx'а в плане ограничения кол-ва запросов и тп. Не впечатлило. Почему-то стал тормозить доступ к внутренним сайтам.

В реальности на серьезном проекте один fail2ban не справится. Да и блочить брутфорсера на 30 секунд - странное занятие. Сильно выручает cloudflare в паре с fail2ban. Ну и при серьезной атаке с одного адреса приходит не больше одного-двух запросов, тем более если это ipv6 (большие диапазоны стоят очень дешево), и fail2ban не поможет, только будет расти его лог файл... ИМХО!

В качестве блокирующего правила можно выставить blackhole в /config/action.d/route.conf, чтобы после срабатывания правила не нагружать сеть и ресурсы машины.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий