Pull to refresh

Comments 76

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

Но интересно, спасибо!

Ах, да, ещё. Мне кажется, что если мы идём в сторону миллионов, то первая ошибка - это парсинг текстовых логов. Я поискал, nginx вроде, в protobuf или что-то такое не умеет, хотя задача интересная.

Да, это точно. Я полагаю, что даже простое изменение формата лога (просто в виде IP/datetime) сильно бы помогло производительности. Но интересно было решать задачу именно с заданным форматом.

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

Из моих тестов (я проверял производительность journald) я обнаружил, что он может до 30к сообщений в секунду (однопоточный). Мой (на коленке сляпанный с помощью https://docs.rs/journald/latest/journald/index.html) код на расте генерировал эти 30к сообщений с 50% утилизацией (тоже в одно ядро).

Возможно, там все криворучки (меня включая), но я подозреваю, что ответ в другом - все эти itoa, datetime, sprintf'ы (и их эквиваленты в других языках) - очень тяжёлые функции с кучей аллокаций.

.... может быть, нас ждёт новая революция с бинарными логами. (rkyv? zero cost serialization?)

Врядли. Большинству сервисов хватает обычного текста. Тоесть писать это некому.

В "управляемых" облачных сервисах, наверное, имеет смысл. Если есть 1000 экземпляров сервиса и их логи, то почему бы, например, не сэкономить десяток серверов?

Логи нужны не чтобы их писать, а чтобы их читать. Глазами обычно. Удобный поиск с grep -C практически обязателен. И хочется чтобы он работал довольно быстро.

А на самый чёрный день хочется иметь возможность зайти на прод и посмотреть лог глазами. Иногда спасает.

Итого основное железо уходит на хранение и систему работы с логами от этой тысячи серверов, а не на запись лога в файл. Да и возможность типовыми средствами почитать лог прямо на пишущем сервере терять не хочется. Бинарные логи не нужны. Минусов слишком много для такой незначительной экономии железа.

Это ваше частное мнение. Бинарные логи журналди прекрасны. Единственный их недостаток - их не открыть напрямую текстовым редактором. Но будем честны - лог файл на 1 гигабайт и более текстовым редактором вы открывать не будете. А запускать Grep или условный journalctl -u servicename | grep или напрямую условный journalgrep разницы нет. Это как для grpc сделали утилиту grpcurl и опять стало удобно отлаживаться

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

Логи в нормальном режиме работы едут в некое хранилище логов и там уже они бинарные и пожатые. Текст живет только на сервере пишущем логи.

Хранилища логов и все пересылки с импортами проще конфигурить когда все логи одинаковые. Понятно что сделать можно все, но зачем эта лишняя сложность?

Экономия ЦПУ и локального диска от бинарных логов будет на уровне фонового шума. Было бы там процентов 10 все уже давно переехали бы.

Это другой инструмент.

и что? Эластиксерч тоже другой инструмент и его ТОЖЕ надо учить отдельно, и готовить отдельно. И так с любым другим движком для хранения логов.

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

работай на опережение!

Логи в нормальном режиме работы едут в некое хранилище логов 

в этом случае как хранятся локальные логи вообще по барабану

Текст живет только на сервере пишущем логи.

или не текст. Или там вообще нет логов (потому что нефиг давать доступ на конечные сервера, или потому что они отротировались уже)

Хранилища логов и все пересылки с импортами проще конфигурить когда все логи одинаковые.

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

Было бы там процентов 10 все уже давно переехали бы.

не переехали только лишь потому что проще всего писать в файл и не делать голову.

Ну мы все таки в век контейнеров живем. Можно всегда считать что есть одно приложение на сервер пишущее один лог в одно типовое место. Чаще всего stdout. И дальше все настраивать и прикидывать исходя из этого. Зоопарк тут починили, он меня тоже бесил.

не переехали только лишь потому что проще всего писать в файл и не делать голову.

Был бы там нормальный профит в железе переехали бы. И пофиг на удобство. Деньги все считать умеют.

Тот же grpc. На потоке данных от 10Гбит переезд на него окупает все затраты на более сложную поддержку, новые другие тулзы, сложность внутренней структуры и новые проблемы. А вот когда 100Мбит в прыжке поток хотят на него перевести у меня появляются вопросы. Расходы на http и прочие json настолько смешные что удобство и простота становятся важнее.

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

Ну мы все таки в век контейнеров живем. Можно всегда считать что есть одно приложение на сервер пишущее один лог в одно типовое место. Чаще всего stdout. И дальше все настраивать и прикидывать исходя из этого. Зоопарк тут починили, он меня тоже бесил.

12 факторов - это хорошие принципы, но они не бесспорные. С теми же логами - те кто попрошареннее - инструментируют свои приложения и шлют «логи» напрямую в эластик или тот же сентри, чтобы иметь нормальную агрегацию событий. А sentry это реально топ штука. Не разбирать же мультилайн, чтобы категорировать ошибки в софте? И внезапно выясняется, что особой ценности писать в stdout/stderr нет, это удобно только на тестовых стендах. А на проде - у разрабов все равно нет доступа к docker logs/kubectl logs. А ещё Вы явно не сталкивались с ограничением на длину лог строки, если кидать ее в stderr.

Короче - на самом деле тезис о том, что любые логи надо писать в виде текста в stderr/stdout совершенно не бесспорен.

Разбирать мультилайн или смириться с джейсоном это конкретный выбор который надо сделать. Я в принципе ни против одного из них возражать не буду.

Один гарантирует всегда правильный парсинг записей, но усложняет чтение глазами. Второй ровно наоборот. Я скорее за джейсон, но не критично.

А ещё Вы явно не сталкивались с ограничением на длину лог строки, если кидать ее в stderr.

У меня в stdout джава стектрейсы энтерпрайзного уровня пролазят. Ограничение вероятно есть, но оно большое. Влететь под него это прям постараться надо. Если влетели смотрим что за мусор мы тут логируем и перестаем это делать.

«логи» напрямую в эластик или тот же сентри, чтобы иметь нормальную агрегацию событий

Откровенно сложно и не очень маштабируемо и не очень отказоустойчиво. Да и абстранкции страдают.

Представьте что у вас небольшая приложенька на сотенку инстансов и пяток ядер на каждый инстанс сошла с ума и начала во все свои силы писать логи. Прямо вечным циклом.

При локальном логе она умрет только сама. Это нормальный исход. При записи куда-то по сети она вам может положить и всех остальных заодно. Кто тем же кластером для логов пользуется.

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

У меня в stdout джава стектрейсы энтерпрайзного уровня пролазят. Ограничение вероятно есть, но оно большое. Влететь под него это прям постараться надо. Если влетели смотрим что за мусор мы тут логируем и перестаем это делать.

вообще-то нет. Во-первых, там лимит какой-то вполне ощутимый. Типа 8к или 64к, не помню деталей. И, во-вторых, народ влетал. В частности, когда софт пишут одни, а эксплуатируют другие. И, в третьих, совет не логировать мусор - "отличный", так можно договориться до того, что логи вовсе не нужны, так как нужно отделать аудит логи (фиксация которых вообще-то обязательно), логи работы приложений (просто реально текстовый мусор, который нужен только при разборе инцидентов, когда что-то не работает), а скорее нужны логи доступов веб-сервров или вообще трейсинги... Но это другое (с) И в большинстве случаев МЕТРИКИ приложения получаются информативнее, чем логи - с точки зрения оценки правильности работы. А то у нас есть любители вместо того, чтобы делать условный счетчик ошибок - пытаться писать в лог, а потом его тейлить и регекспом разбирать. Ну, что ж - ребятам процессорных тактов не жалко, я тут ничего поделать не могу.

Откровенно сложно и не очень маштабируемо и не очень отказоустойчиво. Да и абстранкции страдают.

на все Ваши аргументы ответ - нет, нет, и еще раз нет.

Сложно - нет, просто подключаем нужную библиотеку конкретного языка (как впрочем это работает и с метриками - тупо подключаем библиотеку прометеуса, вешаем определенные аннотации или определяем свои переменные - профит)

Не масштабируемо? Тоже неправда.

Не отказоустойчиво? Тоже неправда.

Абстракции страдают - может ровно наоборот, это более правильно, потому что позволяет через конфиг определять уровни логирования и все такое.

Представьте что у вас небольшая приложенька на сотенку инстансов и пяток ядер на каждый инстанс сошла с ума и начала во все свои силы писать логи. Прямо вечным циклом.

в этом случае с файлами будет та же самая ситуация - переполнение диска, отказ узла, в случае - если диска много, но логов очень много - коллектор логов начнет жрать ядра как не в себя и генерировать кучу трафика в сторону хранилища логов. Что так, что сяк - будет плохо. При этом на стороне коллектора можно настроить троттлинг, но тогда логи будут теряться. И опять приходим к тому - что если логи не очень нужны, то может их вообще отключить и оставить только реально то, что нужно? Как Вы выше и советуете? И это нисколько не отменяет того, что на стороне приемника (тот же ES, кафка или что там у вас будет) нужно строить доступный для понимания и реалистичный SLA, например, по количеству логов принимаемых от каждого из узлов. И это НЕ ЗАВИСИТ, как это ни странно, от того - шлем ли мы логи journald, fluent'ом, logstash'ом или напрямую из нашего приложения...

При записи куда-то по сети она вам может положить и всех остальных заодно. Кто тем же кластером для логов пользуется.

выше пояснил, почему серить логами плохо в ЛЮБОМ случае, вне зависимости от способа передачи лог файла.

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

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

Я предлагаю договориться что логи это логи. А метрики это метрики. Логи не парсим, автоматизацию поверх не строим, мониторинги на логах не делаем и тому подобное. Метрики при этом ровно наоборот. Глазами не читаем, автоматизацию строим, мониторинги делаем. Собираем и пишем и то и другое. И тут общаемся про логи. У метрик другая цель и другие способы ее достижения.

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

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

Именно. Откажет только ваша приложенька с какой-то ошибкой. Все остальное будет работать и дальше не заметив что что-то произошло. Это и есть целевой результат для такого класса ошибок.

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

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

Я предлагаю договориться что логи это логи. А метрики это метрики. Логи не парсим, автоматизацию поверх не строим, мониторинги на логах не делаем и тому подобное. Метрики при этом ровно наоборот. Глазами не читаем, автоматизацию строим, мониторинги делаем.

access.log в nginx — это логи или метрики?

Очевидно, что метрики, упакованные в логи, то есть жуткий костыль. Так что это все таки «события». Если б это были метрики - это была бы страница в прометеус формате, с нужными для ops engineer (это не ругательство, кстати) проекциями. Например - количество ошибок по категориям - скаляр. Время запросов - разбитое по бакетам различной задержки, что позволило бы считать персентили. Потом ещё разбивка по типам запросов и эндпойнтам. Удивительно, но это все эти данные все так же очень нужны для продвинутых функционалов вроде rate limit и умных предохранителей….

В принципе, очень быстро приходишь к тому, что трейсинги эту всю необходимость закрывают, плюс они более гибкие, так как позволяют снимать не 100% трафика, а какую-то рандомную долю или по какому-то заголовку (для canary релизов). И это работает - потому что обычно системные ошибки равномерным слоем размазаны по всем пользовательским запросам.

... Рано или поздно революция случится. Потому что всем нравится софт, который быстрее в 10 или в 100 раз предыдущего.

Прокси-сервер, построенный из ebpf, io_uring и максимальном количестве zero copy (включая логгинг). Сказка? Миллион коннектов в секунду на одно ядро? (У nginx это сейчас 145k, и это при отключенном логгинге).

революция случилась, https, так что нет ни 1кк rps, ни даже 145к

Во-первых есть куча случаев до/после ssl. Балансировка на транспортном уровне, балансировка после (тем же proxy protocol). Во-вторых, SSL ещё бывает с акселерацией, и там очень высокие показатели.

Во-вторых, SSL ещё бывает с акселерацией, и там очень высокие показатели.

если речь про ktls, то ЕМНИП там хеншейк не оффлоадится.

ясно, что itoa и, особенно,generic реализации sprintf сложновато обойтись без кучи аллокаций, но всегда можно подсунуть свой велосипед

На самом деле всё интереснее. Изначально я подумал про binary log в каком-нибудь protobuf'е, чтобы не возиться с записью IP в строки. Но это же раст! И есть условный rkyv, который позволяет получить сериализацию с нулевым оверхедом (на самом деле нет, потому что данные в памяти чуть менее удачно лежат, но всё равно круто). Если выбранный формат таков, что одновременно обеспечивает и быструю работу прокси, и быстрые логи (а быстрые логи - это быстрые waf'ы/ids'ы и т.д.), то это звучит как пролетарский кулак в лицо интерпретируемой мути (js/python/ruby/node).

Nginx умеет /mirror, а там куда это приходит, уже можно делать что хочешь. Ну как вариант, чтобы отказаться от чтения логов.

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

Оно основано на том, что IP-адрес в виде строки целиком всегда помещается в 128-битный регистр, в который влезает 16 символов, а максимальная длина IP-адреса — 15 символов (12 цифр и 3 точки).

я так понимаю прекрастное будущее с ipv6 не наступило? :-)
а какое решение предложите если наступит?

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

Пока читал, куча мыслей промелькнула: А nginx хотя бы теоретически может угнаться по скорости генерирования логов за таким разбором? А action (блокирование) как быстро станет узким местом? И (если блокировать по одному IP), то как быстро заблокируется /0? А еще стало интересно, получится ли эффективная работа fail2ban в ip6? И можно ли еще ускориться парсингом на GPU?

Скорость логгирования сложно сказать, но nginx даёт 145к коннектов в секунду на ядро (http, без логов). С логами будет кратно меньше.

Кстати, логи можно собирать с нескольких серверов. nginx умеет логировать в rsyslog, а тот умеет пересылать логи по сети.

В имеющейся схеме парсер логов запускается раз в минуту, и чем меньше времени (и, соответственно, ресурсов) он будет отъедать при разборе накопившегося — тем лучше.

UFO just landed and posted this here

Если взять просто разделение строк по memchr, то производительность выходит порядка 0,26Гб/0,173 с = ~1,5 Гб/с.

В оригинальной статье про simdjson указано, что на Skylake@3,4GHz парсинг происходил со скоростью 2,2Гб/с. На виртуалке тоже Skylake, но на частоте 2,3GHz, что при пересчёте даёт те же 1,5 Гб/с.

Таким образом, если задействовать AVX, который использует memchr , и делить на строки одновременно с парсингом, то, думаю, схожей производительности можно и добиться. Как-нибудь надо будет попробовать...

А 12 Гб/с simdjson достигает, судя по той же таблице на с. 17, на select, то есть выборке из уже разобранного дерева. Кстати, в этом он не чемпион, его обгоняет sajson.

UFO just landed and posted this here

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

Может быть как-то регексовый парсинг (может быть с упором именно на парсинг логов) можно вынести в отдельную быструю утилиту, так чтобы ее можно было легко соединить потом и с fail2ban и с любым другим скриптовым обработчиком логов. Чтобы писать логику на удобных скриптовых языках и при этом не тормозить на парсинге. (Примерно как ни один скриптовый язык не делает zip/gzip своими силами, это было бы фантастически медленно, все используют внешние либы или утилиты).

 (Примерно как ни один скриптовый язык не делает zip/gzip своими силами, это было бы фантастически медленно, все используют внешние либы или утилиты).

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

Может быть как-то регексовый парсинг (может быть с упором именно на парсинг логов) можно вынести в отдельную быструю утилиту

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

Только не в протобаф а во flatbuffers. Протобаф гонится за компактностью, поэтому там varint используется. Flatbuffers же в приоритете имеет скорость и zero copy.

Что сказать.. Статья интересная. Спасибо автору за это. Хороший пример программирования.


Но я категорически против использования fail2ban в проде.

Во-первых, это лишний компонент. 

Во-вторых, это глючный компонент. А что вы думали? Я уже рассказывал байку, как правильный конфиг f2b привел к взлому телефонии из-за бага в том, что он не матчил tcp/udp порты.

В третьих, это медленно. Грепать или тейлить логи зашквар. Не понимаю, чем было бы хуже написать плагин на Lua для nginx и там трепать соединения.

В четвертых, f2b это попросту опасно. Пора привыкнуть к тому, что клиент далеко не определяется тупо айпи адресом. Запросто за одним айпи могут быть сотни пользователей. Это возможно как в мобильных сетях (привет мегафон с его натом), так и в случае корпоративных сетей (когда выход в инет делается с одного шлюза). И бан одного пользователя приводит к недоступности сервиса для всех. Повторяю. НЕЛЬЗЯ ИСПОЛЬЗОВАТЬ F2B для ПУБЛИЧНЫХ сервисов. Для частных - еще куда ни шло, но там он не нужен, потому что есть другие механизмы контроля

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


@amarao какой бинарный логгинг, окстись. Тут энвой в ядро хотят затащить, чтобы быстрее работало, а ты journald разгонять пытаешься, который вообще НЕ ДЛЯ ЭТОЙ задачи.


Далее поговорим о технических вещах. F2b работает через айпитейблз. Это зашквар. Потому что nftables и прочее. Как там с их поддержкой? Все ок? А еще это медленно. Если хотим быстро - надо фигачить ebpf. И, удивительно, решения для этого есть.


Давайте попробуем подискутировать.

Это да.. fail2ban отличный пример того, как решая одну проблему (клиент не может пройти авторизацию) можно придумать себе парочку других (вместо унылого подсчёта криптографии при установлении соединения процессор занят обработкой regexpов и заполнением таблиц в памяти ядра).

Немного более прямо было бы писать логи в изначально машиночитаемой формате (sql?).

А так, fail2ban нужен только затем чтобы админу было чем заняться ;)

sql - это язык запросов.

Логи можно было бы писать в JSON. Это бы сохранило и читабельность (ну хотя бы относительную в отличии от бинарных логов) и более удобный парсинг через jq вместо grep.

json - это ещё хуже (в смысле быстродействия).

sql - это не только язык, но и изначально форматированные данные (не нужно парсить дату/время/ip) + возможность поиска/сортировки

sql - это не только язык, но и изначально форматированные данные (не нужно парсить дату/время/ip) + возможность поиска/сортировки

sql - это не формат

json - это ещё хуже (в смысле быстродействия). 

это хоть какой-то компромисс. Но все равно все сводится к тому, что есть поле message, которое становится помойкой для всего.

еще добавлю

@BugM подумайте еще вот о чем. Бинарный формат в journald обеспечивает надежное хранение и контроль целостности логов. В случае - если мы логи пишем просто в текстовые файлы - где гарантии того, что лог будет цельный? Что какой-то Васян или программа по ошибке его наполовину не затрет ? А с json, @Semy, так вообще песня. Положили мы его в файл. А лог по какой-то причине транкейтнулся. Результат очень простой - jq просто при парсинге этого лога возьмет и сломается... Не, такой подход не годится...

sql - это не формат

В смысле хранения данных - нет, не формат. В смысле доступа к данным - очень даже да. Данные парсить не нужно, они уже типизированные. Но я не настаиваю ;)

Если лог обрезался почему то не по границе строки, то text тоже будет поломан, а json упаковывается в строку. Поэтому я подразумеваю, что он "условно читаем". Визуально воспринимается он плохо, но хоть grep'нуть по нему можно. Одним словом -- компромисс.

Бинарный формат в journald обеспечивает надежное хранение и контроль целостности логов. В случае - если мы логи пишем просто в текстовые файлы - где гарантии того, что лог будет цельный? Что какой-то Васян или программа по ошибке его наполовину не затрет ?

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

Текстовый и даже json формат дает возможность почитать что осталось при разрушенной, частично удаленной и любой другой порушенной записи. Просто глазами и грепом читать можно. А вот даже простейший разрушенный протобаф прочитать где-то между нетривиально и невозможно.

Тоже пишем в минусы бинарных форматов.

Так, а чем заменить-то? Пример - веб-сервер, SSH надо защитить качественно, ключи не вариант (нужны пароли).

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

ключи не вариант (нужны пароли).

не нужны. Если это не так - Вы что-то делаете не так. Либо накидывайте конкретные кейсы, можно обсудить

@ky0

Понимаю, что такой вариант подходит не для всех случаев, но для бана активно долбящихся в какую-нибудь API — то, что надо. Nginx, ограничив спамера через limit_req, отправляет его айпишник в error_log, который, в свою очередь, просматривает f2b и в какой-то момент блокирует уже на сетевом уровне.

я объяснил почему это не работает. Представьте себе, что Ваши клиенты сидят на каком-нибудь таймвебе, ECS или любом другом шареном хостинге и у них РАЗНЫЕ токены для доступа к Вашему АПИ, но айпишники общие. Вы реально будете их блочить на сетевом уровне, ау?

Ну ОК, подумал, какой-то менеджмент ключей можно сделать. Перебор/брутфорс больше не грозит? Можно не блокировать попытки подбора?

Успешным подбором? Перегрузкой файла с логами и места для логов?

Подобрать ключ? Вы это серьезно?

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

Перегрузкой файла с логами и места для логов?

бредовый аргумент. Кладите логи на отдельную ФС и не блокируйте выполнение основного функционала, если логирование сломалось.

Успешным подбором?

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

Я гарантирую, что если злоумышленник вошел по ключу, то это означает не то, что он его подобрал, а то, что он его с*#^$*#$^* у владельца ключа... И это проблема гораздо более серьезная, чем подбор пароля (мало ли там еще остальные доступы этого пользователя в другие сервисы уже похеканы)...

Да и вообще сделайте наконец-то OTP вход по SSH... И, да, это возможно...

подобрать ключ задача не реальная в текущих реалиях
особенно если админ не наркоман и сделал конфиг sshd с таймаутами и безопасными ciphers.

единственное чем грозит попытка подбора ключей (логинов и паролей) в таком случае это увеличенная нагрузка на проц и сеть, и от этого обычно спасает перевесить ssh с дефолтного порта на рандомный, а ещё лучше прикрыть его vpn и/или portknocking.

и да, толку будет больше чем от f2b

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

А где? Не нашёл

вот теперь увидел «тут» :)

увеличенная нагрузка на проц и сеть

Fail2ban сам обеспечивает нагрузку на проц ;) С чем боролись, как говорится.

не нужны. Если это не так — Вы что-то делаете не так. Либо накидывайте конкретные кейсы, можно обсудить

Стоит домашний сервер, на котором крутится Nextcloud, к которому подключен мобильный клиент, который умеет авторизацию только по паролю. Используя f2b можно разобрать логи Nextcloud и сварганить защиту от перебора паролей. В принципе Nextcloud и сам умеет защищаться от брутфорса, но только таймаутом, а тут проблема убирается в корне сразу на целый день/неделю/месяц/год) Но со всеми вытекающими рисками блокировки сети за NAT. Однако если доступ к облаку на сервере осуществляется с определённых статичных IP, то это несущественно. А есть какая-то простая и незамороченная альтернатива в подобной ситуации?
  1. перевесить nextcloud на нестандартный порт (не 80,443, а какой-нибуль 30200)

  2. сделать впн, вывешивать nextcloud на приватный ip, на телефоне зафигачить vpn клиента

  3. your choice...

Используя f2b можно разобрать логи Nextcloud и сварганить защиту от перебора паролей. В принципе Nextcloud и сам умеет защищаться от брутфорса, но только таймаутом, а тут проблема убирается в корне сразу на целый день/неделю/месяц/год) 

Вы сами дали ответ на свой вопрос. f2b тут нафиг не нужен. Рейт лимит и защита от брутфорса прекрасно делается на уровне приклада или reverse proxy перед ним (nginx).

Я еще, кстати, надеюсь, что у Вас nextcloud по tls наружу торчит?

Перевешивание сервисов на нестандартные порты, причём не «круглые» — это кажется первым пунктом вообще везде делать надо. Это закрывает кучу моментов, иначе боты одолеют.

Сервер старый, стек LAMP в котором обычный HTTPS через самоподписной SSL сделан и прочая ламповая партизанщина. Я лет 5 назад цикл мануалов на хабре делал. С тех пор никакой эволюции не было ибо как-то не до этого. Хотя поддержка Debian 9 этим летом заканчивается. Да и для локалки нормально было, а сейчас в сети торчит только потому что там ничего важного нет)
UFO just landed and posted this here
Это Mesh на основе WireGuard? Звучит очень привлекательно, спасибо за наводку.
UFO just landed and posted this here

К сожалению, доступ к сайтам на сервере по SSH нужен куче агентств. Тут нужно что-то типа Teleport по хорошему, но он дико дорогой в Enterprise версии.

используйте бесплатную, она прекрасно работает.

И, да, телепорт - это по сути ssh по сертификатам.

Альтернативы:

ssh по otp

ssh по короткоживущим сертификатам - пример - https://smallstep.com/docs/tutorials/ssh-certificate-login

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

https://t.me/ru_teleport

ключи не вариант (нужны пароли).

ну ладно, пароли так пароли, pwgen -Bs 16, тыкаем в любой.


если же у вас пароль «год канонизации святого Доминика папой Григорием IХ», то fail2ban вас никак не спасёт, перебор паролей сегодня зачастую идёт распределённо.

UFO just landed and posted this here

Да, по-настоящему оптимальный подход конечно не в том, чтобы сначала сохранять в файл (!) текстовый (!) лог через миллион системных вызовов и тонны оверхеда, а потом парсить его питоном (!), а реализовать эти счётчики прям в процессе принимающем соединения за пару десятков инструкций :)

внезапно, лет 5 тому назад - я решал похожую задачу. Был некий лог, который тейлился скриптом на перле. Это было не очень поддерживаемо (перл вообще как ЯП уже вроде как умер, но в то время это было прям на острие технологий). Я его переписал на python. Чтобы Вы думали - производительность упала (!). Не то, чтобы сильно, но просела. Так что я прямо на практике убедился в том, что перл реально побыстрее пайтона работает. Другой вопрос, что в общем-то никто от этого не пострадал. И, да, с одной стороны я горжусь тем, что заскриптовал и это решение крутится в проде, с другой - не горжусь, потому что такие же костыли и лучше было придумать альтернативное решение с более вменяемой архитектурой... Но не было тогда ни времени, ни бюджета на это

UFO just landed and posted this here

fail2ban - отличный инструмент

  1. Это инструмент для конкретной задачи и он с ней справляется хорошо

  2. Если у вас кривые правила в фаерволе не какой f2b не поможет

  3. Достаточно для большинства кейсов, я не верю что у вас на телефонии или nginx больше чем 2к rps, или больше чем 2к строк в сек. прилетает в логи. Грепать и тайлить логи это нормально так делают большинство logstash fluentd и т.д.. А хранить логи в файлах локально это в первую очередь надежно и быстро в отличии отправке по сети. Анализ трафика на лету как правило выходит дороже и опасней.

  4. Если так хочется баньте ip+port для udp он меняется раз в 30 минут по умолчанию или не меняется вовсе днями. С tcp сложней, но даже те провайдеры кто прячет пользователей за nat как правило присваивают 1 ip на пользователя и ротейтят с какой то периодичностью, а не прячут овер +100500 узверей за 1 ip. Так что проблема в большинстве надумана. С организациями немного сложней но для этого есть белые списки.

  5. Вас хостер первым попросит свалить с его хостинга, при хорошем ddos могут и с ДЦ попросить свалить. Если вы достаточно жирный клиент то поставщик как правило сам решает вопрос ddos-а, за отдельные деньги или уже в пакете, соответствующим оборудованием и это не как не в плоскости f2b, да и инструмент решает иные задачи.

  6. Fail2ban - работает на python его легко править, в нем легко разобраться для него легко писать правила. В конечном итоге f2b делает ровно 2-е вещи вызывает cli командочку для того что бы забанить и cli командочку для того что бы разбанить. Что вы там будете вызывать это ваш вопрос, не нравится iptables используйте любой другой фаервол, для ускорения вполне можно юзать ipset. Не знаю что такое ebpf но если он умеет добавлять правила и удалять cli командой то f2b с этим справится. Можете на fail2ban легко сделать не добавление правила а отправку сообщеньки в тот же telegram с ip и идти руками проверять, что там происходит. Всяко лучше чем проспать и что то делать когда уже клиенты приходят.

Это в первую очередь простой инструмент закрывающий вопрос с назойливыми ботами и мамкиными кулхацкерами. В случае с asterisk это вообще маст хев, там sip обрабатывается в 1 ядро, брутить могут так что на остальных клиентов cpu не хватает и если таких не банить страдают остальные клиенты. А если у вас публичный сервис для всех и масштабы соответствующие у вас с вероятностью в 99% кластер, и там простым f2b уже не обойтись. Ну или мощности позволяют забить на вопрос борьбы с мамкиными кулхацкерами.

Мой посыл такой это инструмент закрывающий вопрос брутфорса паролей на сервисе будь то sip, ssh или что то еще, почти из коробки, требующий минимальных усилий на внедрение. И это все отлично работает пока вы вмещаетесь на 1 сервер. Когда вы не влазите на 1 сервер то и решения нужно применять соответствующие.

не убедительно, от слова совсем.

Это инструмент для конкретной задачи и он с ней справляется хорошо

define что это за конкретная задача?

Если у вас кривые правила в фаерволе не какой f2b не поможет

проблема была не в файрволле, а в самом f2b. Может мне еще ссылку на ишью дать? Не проблема, кстати, только поискать надо будет поиском. Он (f2b) как был студенческой поделкой без каких-либо гарантий, так и остался. Это не промышленные штуки вроде nginx - которыми пользуются все, на скейле, да еще и есть коммерческая версия с поддержкой.

Знаете, уровень большинства инструкций в интернете точно такой же. Что там обычно делают? Ставим центос линукс (потому что это же почти RHEL!!!). Затем отключаем SElinux (это же сложно его настраивать, давайте сразу отключим). Потом давайте затащим nginx или апач. И в довершение подпихнем f2b...

Грепать и тайлить логи это нормально так делают большинство logstash fluentd и т.д.. А хранить логи в файлах локально это в первую очередь надежно и быстро в отличии отправке по сети. Анализ трафика на лету как правило выходит дороже и опасней.

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

Если так хочется баньте ip+port для udp он меняется раз в 30 минут по умолчанию или не меняется вовсе днями. ....

я уже ничего не хочу, мне пофиг, я в состоянии дзена и без f2b и сервисы защищены.

А если у вас публичный сервис для всех и масштабы соответствующие у вас с вероятностью в 99% кластер, и там простым f2b уже не обойтись

чтд

А куда денутся все эти преимущества при реальном бане IP? накладные расходы на вызов iptables всё ускорение нивелируют.

При реальном бане с запасом хватает скорости наивной реализации, а бан делается пачкой через ipset, потому что добавление правил по одному в iptables, конечно же, сильно тормозит (в том числе и обработку длинной цепочки правил). Кстати, в README репозитория есть инструкции на этот счёт.

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

Понимаю, что такой вариант подходит не для всех случаев, но для бана активно долбящихся в какую-нибудь API — то, что надо. Nginx, ограничив спамера через limit_req, отправляет его айпишник в error_log, который, в свою очередь, просматривает f2b и в какой-то момент блокирует уже на сетевом уровне.

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

  1. Похоже, что архитектуры нету,. Миллион строк логов на том же хосте, где и фронтенд ? А там еще и постфикс крутится? :) и сислог , и крон с logratade? А почему бы и нет ;). Ну если баним на апстолах на том же хосте...

  2. Проблема разбора миллионов строк логов с ~40k bare-metal ( и бог знает сколько контейнеров) была решена почти 10 лет назад уже знакомыми с 6-го этажа одного бизнесцентра в моем городе и успешно применялась ( а может и сейчас применяется) в одном из 2-х двухбуквенных сайтов Рф.

    Так как все равно логи льем на сервера логгирования, то именно там до записи на FS стоит мелкая незаметная крохотулька https://github.com/quadrantsec/sagan, в те времена не такая навороченная, но так же быстрая.

П.С. Забанить DDoS iptables вы все равно не сможете, т.к. DDoS - это когда в 10Г канал вам вдувают 50Г трффика...

Вы совершенно правы, и именно поэтому статья располагается в разделе "ненормальное программирование". Практических целей у дальнейших оптимизаций нет, просто было интересно.

1 А как архитектурно правильно сделать?

Действительно, непонятно, зачем вобще блокировать веб-клиентов через пакетный фильтр, да еще и путем вычурного парсинга логов, когда с этим отлично справляется сам веб-сервер? Причем с возможность шарить блокировки между всем кластером фронтов.

Sign up to leave a comment.

Articles