LINUX.ORG.RU

OpenShield v0.2.4

 , openshield, ,


2

2

Привет, $username!

Хотел рассказать о своём проекте OpenShield. OpenShield – это фарвол для Linux с контролем сетевой активности отдельных приложений, написанный на Rust. Для управления используется терминальный интерфейс, а фильтрацией пакетов занимается nftables с возможностью переключения на iptables. В режиме обучения программа пропускает исходящий трафик и автоматически создаёт разрешающие правила. Затем можно перейти в режим Enforcing: соединения, для которых нет разрешающего правила, будут блокироваться. Правила можно привязывать к cgroup, пути исполняемого файла и параметрам запуска, дополняя ограничениями по адресам, портам и протоколам. Поддерживаются действия accept, drop и reject, а также временное отключение правил без их удаления.

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

Я написал на GitHub, что OpenShield является форком opensnitch, наверное это не совсем так, поскольку заимствована лишь идея, а код написан заново, отличаются механизмы работы и задачи приложения. Поэтому точнее было бы назвать OpenShield самостоятельной реализацией, вдохновлённой OpenSnitch. В OpenSnitch заметный акцент сделан на интерактивном контроле исходящих соединений через графический интерфейс; также есть управление системным фаерволом и несколькими узлами. В OpenShield я делаю упор на локальную политику защиты хоста и работу через терминал, в том числе на серверах без графического окружения. Основной сценарий — собрать правила в режиме обучения, проверить их и перейти к фильтрации по явно разрешённым соединениям.

Отдельное внимание уделяется поведению при ошибках. В режиме Enforcing невозможность достоверно определить приложение не должна превращаться в разрешение трафика: неоднозначная атрибуция приводит к блокировке соответствующего пакета. При критических сбоях предусмотрен аварийный режим BlockAll. Изменять правила и режим работы может только root, а наблюдение доступно участникам группы openshield. Управление и мониторинг разделены между локальными Unix-сокетами с проверкой учётных данных клиента; сетевого управляющего API нет.

Демон и TUI написаны на Rust, в собственном коде запрещён unsafe. Дополнительно ограничены размеры сообщений, очереди и время обработки запросов, предусмотрены проверки сохранённого состояния и тесты поведения при перегрузке. Это не обещание отсутствия уязвимостей и не утверждение, что OpenSnitch небезопасен, а описание выбранных инженерных приоритетов. Обучение тоже не определяет, заслуживает ли приложение доверия: оно лишь фиксирует наблюдавшуюся активность, поэтому полученные разрешения необходимо проверять перед включением Enforcing.

Довольно продолжительное время было уделено производительности приложения, однако она пока остаётся слабым местом при большом количестве коротких соединений и интенсивном исходящем UDP-трафике, особенно состоящем из множества небольших пакетов. Здесь важнее не столько объём переданных данных, сколько количество пакетов и новых соединений, для которых требуется определить приложение.

Это связано со стоимостью проверки правил, привязанных к приложениям. Обычные сетевые правила — адреса, порты, протоколы и интерфейсы — обрабатываются непосредственно ядром через nftables или iptables. Если же решение требует проверки приложения, пакет передаётся демону через NFQUEUE. Демон устанавливает владельца сокета, проверяет идентичность процесса и сопоставляет её с условиями правила: путём исполняемого файла, cgroup, аргументами запуска и другими заданными признаками. Такая проверка существенно дороже сравнения адреса и порта.

Для TCP предусмотрено ускорение: после авторизации соединения его established-трафик может обрабатываться в ядре через conntrack с проверкой поколения политики. Поэтому длительное разрешённое TCP-соединение обычно обходится дешевле постоянного открытия новых. Для UDP, не разрешённого отдельным сетевым правилом, проверка приложения повторяется для каждого пакета, требующего прикладного решения. Именно этот сценарий особенно чувствителен к PPS: даже небольшой по мегабитам поток способен заметно загрузить демон и увеличить задержки. Используемые кеши ускоряют поиск владельца, но не заменяют проверку актуальности его идентичности безусловным повторным разрешением.

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

Приложение собирается для Debian 12 и 13, Ubuntu 22.04, 24.04 и 26.04, Fedora 43 и 44, AlmaLinux 9 и 10, Rocky Linux 9 и 10, openSUSE Leap 16.0, openSUSE Tumbleweed, Alpine Linux 3.23 и 3.24, а также Arch Linux. В зависимости от дистрибутива предусмотрены пакеты для x86_64 (amd64), 32-разрядного x86 (i586/i686), ARMv5, ARMv6, ARMv7, ARM64 (aarch64), PowerPC 64 LE (ppc64le), IBM Z (s390x) и RISC-V 64 (riscv64). Это общий перечень архитектур: не каждая комбинация дистрибутива и архитектуры входит в матрицу сборки.

Предрелизные проверки установки пакетов и функциональные тесты фаервола выполняются:

  • на x86_64 — для всех перечисленных дистрибутивов и версий;
  • на ARM64 — для всех перечисленных, кроме Arch Linux;
  • на 32-разрядном x86 — для Debian 12 и 13, AlmaLinux 10, Alpine Linux 3.23 и 3.24, openSUSE Tumbleweed.

Всего получается 37 комбинаций дистрибутива и архитектуры. Для каждой проверяются nftables и резервный iptables, включая обучение, переход в Enforcing и применение правил. Отдельный performance gate запускается на openSUSE Tumbleweed x86_64.

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

Скачать и попробовать приложение можно по последнему актуальному тегу v0.2.4

Сильно не пинайте, буду благодарен за любые отзывы и комментарии.

Спасибо, что дочитали до конца.

★★★★★

Проверено: hobbit ()

По описанию это терминальный интерфейс для nftables и iptables.

Вопрос к автору поста: по каким причинам человек должен этим пользоваться? Причина - код на Раст, избавлен от ошибок с памятью не считается.

Ivan_S
()

это фарвол для Linux с...

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

drfaust ★★★★★
()
Ответ на: комментарий от Ivan_S

Не совсем. nftables/iptables здесь — backend, а TUI — только интерфейс управления демоном.

Смысл проекта в правилах уровня приложения. Например: разрешить конкретному /usr/bin/foo определённой версии, запущенному с такими-то аргументами и/или в таком cgroup, ходить только на заданные адреса и порты. Для этого OpenShield устанавливает, какому процессу принадлежит соединение, и уже потом принимает решение. В Enforcing неоднозначность при такой атрибуции трактуется в сторону блокировки.

Плюс есть Learning: запустил систему, собрал реально используемые приложениями соединения, просмотрел получившиеся правила и переключился в default-deny Enforcing.

Обычные правила по IP/порту/протоколу/интерфейсу вообще остаются в nftables и не гоняются через userspace. nftables сам умеет, например, UID и cgroup, но штатного правила вида «вот именно этот executable с этой версией файла и таким argv может устанавливать такие соединения» там нет.

Поэтому если нужна просто удобная морда к nftables — пользоваться OpenShield действительно особого смысла нет. Если нужен application-aware firewall без GUI, особенно на сервере, — ради этого он и делался. Rust тут причина примерно в последнюю очередь.

unclestephen ★★★★★
() автор топика
Ответ на: комментарий от Ivan_S

А зачем?

Язык здесь не фича для пользователя и не предмет религиозного выбора. Мне нужен системный демон, который работает с NFQUEUE/netlink, /proc, сокетами, конкурентно обрабатывает события и довольно много парсит внешних данных. Rust для этой задачи меня устраивает.

Переписывать всё на C исключительно ради того, чтобы убрать слово Rust из описания проекта, — довольно странная инженерная задача.

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

unclestephen ★★★★★
() автор топика

три вопроса:

1. что сподвигло ?

2. кроме локал-хоста где-нибудь пробовалось ?

3. кто в команде кроме AI

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov
  1. что сподвигло ?

написал в стартовом посте, хотелось терминальный аналог OpenSnitch

  1. кроме локал-хоста где-нибудь пробовалось ?

пока нет

  1. кто в команде кроме AI

никого

unclestephen ★★★★★
() автор топика
Ответ на: комментарий от unclestephen

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

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

Ivan_S
()
Ответ на: комментарий от unclestephen
  1. кто в команде кроме AI

никого

А говорят стабильности нет.

PunkPerson ★★
()
Ответ на: комментарий от unclestephen

Разумеется начинают. Я вот лично начал и пишу. Просто об этом из каждого утюга не транслируется.

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

Ivan_S
()
Последнее исправление: Ivan_S (всего исправлений: 1)

я Little Snitch-ом пользовался еще на Intel-Mac и всё время думал: почему его нет на Linux. Конечно, ты слышал, что автор оригинала сделал версию для Linux, но она полукоммерческая (кажется)

обязательно попробую, спасибо!

powerguy ★★★
()
Ответ на: комментарий от unclestephen

жаль, там один из ключевых в сниче был в GUI-попапе, который выскакивал при новой попытке соединения без правил. Типа отследить background коннеты.

powerguy ★★★
()

Могу сделать предположение, если программа на расте, значит она весит полтора гигабайта.

Hangover
()
Ответ на: комментарий от Hangover

Вовсе нет, посмотри пакеты сначала, прежде чем предположения делать

unclestephen ★★★★★
() автор топика
Ответ на: комментарий от Hangover

Чтобы написать программу на этом яп, которая запускает nftables или iptables, большой бинарник не нужен. Так что да, фанаты of the programming language скажут, что мол вон оно как, бинарник не весит много. И мол очередной проект на this language.. Но там можно и на шелле написать то же самое.

Ivan_S
()
Последнее исправление: Ivan_S (всего исправлений: 2)
Ответ на: комментарий от Ivan_S

Ты второй раз описываешь не OpenShield, а какую-то придуманную программу, которая «запускает nftables или iptables».

nftables/iptables здесь устанавливают правила в ядро и отправляют трафик, требующий определения приложения, в NFQUEUE. Дальше демон должен определить сокет и процесс-владелец, проверить executable, его версию, UID, cgroup, argv, сопоставить всё это с политикой и вернуть verdict. В Enforcing ошибка или неоднозначность атрибуции должна закончиться блокировкой, а не разрешением.

Для TCP после первой успешной проверки соединение ещё переводится на conntrack fast path, чтобы не гонять каждый пакет через userspace.

Написать на shell команды, которые создадут цепочки nftables, конечно, можно. Только это примерно такая же замена OpenShield shell-скриптом, как echo GET | nc — замена браузера.

Если же предлагается реализовать NFQUEUE consumer, IPC, атрибуцию процессов, хранение и проверку состояния, Learning и всю логику политик набором внешних утилит, вызываемых из shell, то основная программа просто переедет в эти утилиты.

unclestephen ★★★★★
() автор топика
Ответ на: комментарий от BruteForce

Я рад, уже писал, что Rust здесь просто как вариант

Думаю что хайп уйдёт, но будет что-то другое на волне хайпа

И точно так же будет хейтится, а Rust к тому времени уже будет состоявшимся и скучным, в пиджаке и с пузиком

unclestephen ★★★★★
() автор топика
Ответ на: комментарий от drfaust

Телефонные мошенники уговорили старушку переписать квартиру на Rust!

Smacker ★★★★★
()

Обычные сетевые правила — адреса, порты, протоколы и интерфейсы — обрабатываются непосредственно ядром через nftables или iptables. Если же решение требует проверки приложения, пакет передаётся демону через NFQUEUE. Демон устанавливает владельца сокета, проверяет идентичность процесса и сопоставляет её с условиями правила: путём исполняемого файла, cgroup, аргументами запуска и другими заданными признаками.

Сабж позволяет управлять «обычными сетевыми правилами» или работает только с приложениями?

micronekodesu ★★★
()
Ответ на: комментарий от Ivan_S

. Я вот лично начал и пишу.

А этот код с нами сейчас в одной комнате?

zloelamo ★★★★
()
Ответ на: комментарий от micronekodesu

Да, позволяет. Обычные сетевые правила — адреса, порты, протоколы, интерфейсы — можно задавать в OpenShield и они устанавливаются в nftables для обработки непосредственно ядром.

Application-aware правила — это дополнительный уровень. Упор сделан на том, чтобы при необходимости добавить к условию правило вроде «разрешить firefox обращаться на TCP/443» или привязать правило к cgroup/UID и т. п.

При этом не каждое правило обязательно проходит через NFQUEUE: в userspace отправляется только трафик, для которого требуется дополнительная проверка, связанная с приложением.

unclestephen ★★★★★
() автор топика

отличная идея!

sunjob ★★★★★
()

Я все думаю написать систему, которая частично пересекается с этой. А именно, менкджер песочниц, который сводит сетевые неймспейсы, директории на диске и bwrap, flatpak и systemd-run. Но пока не могу сообразить все детали логики.

zloelamo ★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.