Browse Source

* f2b dev reports

master
Alex 'AdUser' Z 7 years ago
parent
commit
c2c8819fa4
  1. 128
      projects/f2b/2016-09-11/index.markdown
  2. 105
      projects/f2b/2017-01-04/index.markdown
  3. 6
      projects/index.markdown

128
projects/f2b/2016-09-11/index.markdown

@ -0,0 +1,128 @@
---
title: Отчёт о ходе разработки f2b
tags: devel, f2b
---
Sep 9 23:06:55 f2b[10753]: jail 'asterisk': new ip found -- 89.163.146.93
Sep 9 23:09:50 f2b[10753]: jail 'asterisk': new ip match -- 89.163.146.93 (2/3)
Sep 9 23:12:43 f2b[10753]: jail 'asterisk': new ip match -- 89.163.146.93 (2/3)
Sep 9 23:15:35 f2b[10753]: jail 'asterisk': new ip match -- 89.163.146.93 (2/3)
Sep 9 23:18:40 f2b[10753]: jail 'asterisk': banned ip 89.163.146.93 for 1.0hrs
# ... попался, ублюдок!
Продолжаем неспешно пилить чудо-программу.
С момента [предыдущего](/blog/2016/03/17/f2b/) поста темпы пиления упали, т.к. сказывается "эффект УМВР",
но тем не менее сделано следующее:
---
Control socket для демона
-------------------------
Над реализацией пришлось изрядно посидеть и поэкспериментировать.
Изначально я хотел использовать ``SOCK_STREAM`` и обычный текстовый протокол.
Посидел, написал свою реализацию getline для сокета,
простенький аналог bison'а для разбора команд
и стало мне грустно от осознания объёма кода, который будет это всё обслуживать.
Плюсы:
* с этим может работать любая утилита с помощью netcat/telnet
Минусы, навскидку:
* разбор текстовых команд в виде нескольких токенов - достаточно сложное занятие.
Нужно вычленить строку (в экстремальном случае она может приходить по байту за раз),
побить её на токены, проверить синтаксис, количество аргументов.
Нужно достаточно сложное управление входным буфером:
если не распарсилось полностью - дождаться недостающего, осталось лишнее - хранить.
* перечисленное выше - работает с недоверенными данными из сети -> всё это надо выписывать с упором на безопасность.
* открывается дорога всем нашим любимым сетевым шалостям:
типа открытия 500 соединенений разом и заливки в каждое из них мегабайтной строки,
без малейших признаков "\r" или "\n" -> скажите "здравствуй" исчерпанию памяти или fd.
* ну и такой мелкий штрих: если мы хотим встроенный хелп - из-за тупости клиента,
будьте любезны тащить описание команд на серверную сторону.
...ну и не стоит забывать, что ломание кривонаписанного парсера текстового протокола - это
старая-добрая традиция, ещё начиная со времён sendmail'а и irc.
А уж как народ с самой почтой развлекается, это просто песня.
Поэтому плюнул я на это дело и взял ``SOCK_DGRAM``.
Минусы:
* нужен спецклиент
* негарантированная доставка
Но плюсов в моём случае - много:
* разом снимется проблема с разбором сообщений: readv + проверка длинны пакета.
* никаких висящих соединений: пришёл пакет - обработал, опционально ответил.
* бесплатно получаем управление несколькими инстансами в пределах локальной сети (udp+igmp)[^fn1].
* возможность использовать тот же код в качестве source/backend:
если один хост в сети засёк пидараса - делается рассылка через тот же igmp и все остальные его дружно банят
ещё до того, как он полезет сканить порты на следующий узел.
Простенький клиент
------------------
Появился в силу предыдущего пункта.
Сейчас он умеет все базовые операции: показать статистику, забанить/разбанить, перечитать конфиг, завершиться.
Есть задел и на больше - точная настройка конкретного jail'а, добавление регэкспов "на лету".
redis-backend
-------------
Написан черновик, но пока не тестировался: чтобы его использовать, нужен парный ему source,
а source у нас сейчас прибит гвоздями к файлам.
Растущее время поиска/бана для конкретного ip
---------------------------------------------
Думаю, кто пробовал настроить fail2ban видел в логах "умных" ботов,
после первого бана подстраивающих частоту запросов так, чтоб не попасть под раздачу.
Это работает, но только до той поры, пока период обнаружения фиксирован.
Если он уменьшается по мере того, как растёт число запросов - к ним приходит песец.
На примере: допустим у нас настроено ограничение 5 неправильных запросов в 5 минут.
При фиксированном времени обнаружения бот может сделать 4 запроса, и пойти покурить,
передав эстафету другому боту.
При динамическом времени обнаружения, на эти 4 запроса в первый раз боту придётся
так же подождать 5 минут, а вот в следующий раз - уже 5,5 минут, и т.д.
Вторая идея, логически продолжающая первую - увеличение времени бана при рецидивах.
Это тоже сделано, потому что важно не просто забанить бота, но и порвать ему шаблон.
Третья идея в этом плане - смотреть на "соседей" забаненного ip,
и расширять бан до подсети при необходимости. Этого у меня пока не реализовано.
CMake
-----
* добавлена поддержка GNUInstallDirs
* наведён порядок с путями конфигов, постараюсь больше не менять.
Багфиксы
--------
Без них - никуда. Исправлена пара сегфолтов в коде фильтров.
После этого были сделаны оргвыводы, и притащен strlcpy()
на замену snprintf()/strncpy() из директории уровнем выше.
Обеспечена сборка и работа под бзд. Там же был пойман забавный баг:
fgets(buf, bufsize, file->fd);
...это не работает, если у ``file->fd`` выставлен EOF, даже если файл после этого прибавил пару гигабайт.
Решение - сбрасывать руками перед каждым вызовом через clearerr().
Допускаю, что это ``implementation-defined`` поведение.
Ну и кое-что по мелочи, типа выключения буферизации у логфайла.
[^fn1]: Это планируется, пока играюсь с point-to-point через unix-сокет.

105
projects/f2b/2017-01-04/index.markdown

@ -0,0 +1,105 @@
---
title: Отчёт о ходе разработки f2b
tags: devel, f2b
---
Jan 4 19:52:33 f2b[4090]: jail 'portknock': restored ban of ip 85.121.165.15 (23.9hrs remain)
Jan 4 19:52:33 f2b[4090]: jail 'portknock': restored ban of ip 95.154.82.19 (23.9hrs remain)
Jan 4 19:52:33 f2b[4090]: jail 'portknock': restored ban of ip 78.171.148.130 (24.0hrs remain)
Jan 4 19:52:33 f2b[4090]: jail 'portknock': restored ban of ip 221.194.47.224 (24.0hrs remain)
# ... сидеть, обезьяны, срок ещё не вышел!
С момента предыдущего [отчёта](/blog/2016/09/11/f2b-devel-status/) сделано следующее:
---
source сделан загружаемым модулем
----------------------------------
... по аналогии с фильтром и бакендом. Ранее было прибито к файлам.
Тоже через libdl, интерфейс смотреть в sources/source.h, примеры реализации - в том же каталоге, любой /*.c/
redis source/backend
--------------------
Предыдущий пункт позволил реализовать source для redis.
Это позволило "делиться" банами с другими хостами.
Сейчас оно работает уже пару месяцев без перерыва, 4 хоста с f2b + 1 redis-сервер.
mcast source/backend
--------------------
Также добавлен аналог предыдущего модуля, но работающий через multicast,
что позволяет обойтись без redis-сервера, но ограничивает расположение
хостов одним multicast-доменом (т.е. одна и та же сеть, если не применять
костыль в виде igmpproxy и подобного).
Пока недостаточно оттестировано.
portknock source
----------------
Для выявления заведомых ботов. Позволяет повесить, например, /типа/ открытый telnet,
а по коннекту -- банить подключившегося, ибо нехер.
Если скомбинировать с вышеупомянутым redis'ом - получим распределённый honeypot.
Любой пидорас, спаленный за сканированием этого "telnet"'а будет немедленно забанен на всех хостах с f2b
(а то и во всей защищаемой сети в случае граничного роутера).
Приготовьтесь сразу юзать ipset или нечто подобное, хостов будет много.
За три часа часа работы в таком режиме набегает под две сотни, а за сутки - тысяча-полторы хостов (при бане на сутки).
doxygen и прочая документация
-----------------------------
В всех заголовках добавлены doxygen'овы комментарии для структур, дефайнов и функций.
Вобщем, задокументировано всё, на что оно ругалось при генерации доков.
Также, существенно расширены доки по установке и настройке, добавлены примеры конфигов.
state
-----
Добавлена возможность хранить и восстанавливать список банов при рестарте.
Сделано тупо через файлик с записямии, когда какой ip был забанен и когда его выпускать.
Особой производительности там не требуется, файлик переписывается только при очередном бане.
Если будет тормозить - тогда будем думать.
Клиент / управление
-------------------
Реализована команда set для jail'ов. Теперь порог срабатывания и прочие параметры можно поменять без рестарта.
Реализована перезагрузка списка regexp'ов для фильтра (аналогично).
Для пришедшего пакета теперь проверяется количество аргументов.
Сделано с прицелом на будущую реализацию управления по igmp.
Утилиты
-------
Переработаны утилитки для тестов различных компонентов.
Также, они переименованы для приведения к одному виду /f2b-*-test/.
Все утилиты сейчас могут использовать тот же кусок конфига,
что и сам демон (с минимальными исправлениями, вроде пути к библиотеке).
Переименованы некоторые команды, в частности:
* ban -> ip ban
* show -> ip status
* release -> ip release
* regex stats -> filter stats
* regex add -> regex reload
TODO
----
Что ещё надо будет в ближайшее время.
* select() вместо sleep() -- при большом списке файлов плывёт время обработки.
* белый список для подсетей (реализация ipv4-only сложности не представляет, но хотелось бы её сделать и для ipv6 тоже)
* реорганизовать имена загружаемых модулей (сложности с cmake, оно очень сильно хочет сделать именование вида libFOO.so)
* reload для конкретного jail'а
* добавить возможность использовать как просто udp, так и udp multicast для клиента (сейчас - только unix-сокет)

6
projects/index.markdown

@ -8,4 +8,8 @@ title: Проекты
* [SMS Notification System (SNS)](/projects/sns/)
* [Редактирование торрент-файлов](/projects/torrents_editor/)
* [f2b, легковесная замена fail2ban](/articles/2016/03/17/f2b/)
* f2b, легковесная замена fail2ban
* [анонс, 2016-03-17](/articles/2016/03/17/f2b/)
* [отчёт о разработке, 2016-09-11](/projects/f2b/2016-09-11/)
* [отчёт о разработке, 2017-01-04](/projects/f2b/2017-01-04/)

Loading…
Cancel
Save