core.firewall
Управление одним правилом файрвола: порт, протокол, источник, действие.
core.firewall приводит одно правило файрвола (port/proto/source/action) к состоянию present или absent. Backend выбирается автоматически по установленному управляющему исполняемому файлу — ufw (проверяется первым) или firewalld; состояния идемпотентны, сверка идёт разбором вывода CLI. Модуль работает только с конкретным правилом и никогда не трогает default policy и «включён/выключен» файрвола. Требует root.
Требования
- Rootтребуется
- Сторона
soul-side - Коллекция
soulstack.network - Категория
network
run_as_rootexec_subprocessАвто по установленному управляющему исполняемому файлу (не по Soulprint): ufw проверяется первым (чаще на debian-парке), затем firewalld (firewall-cmd, redhat-парк). Ни один не найден — шаг падает (no supported firewall detected). iptables сознательно отложен: нужна chain-семантика и ip(6)tables-save, не покрываемые парой add/delete одного правила.
Состояния
core.firewall.present — Правило файрвола существует (port/proto/source/action).
Правила не было и оно добавлено (сверка по ufw status / firewall-cmd --list-ports / --list-rich-rules).
Правило уже присутствует.
Параметры
| Параметр | Тип | Обяз. / дефолт | Описание |
|---|---|---|---|
port | int | required | Порт 1..65535. |
proto | stringtcp | udp | optional | Протокол tcp|udp (default tcp). |
action | stringallow | deny | optional | Действие allow|deny (default allow). |
source | string | optional | IPv4 CIDR или одиночный IPv4 (default any). IPv6 не поддержан в MVP. |
zone | string | optional | Зона firewalld (default — default zone). |
Пример — Разрешить PostgreSQL из внутренней подсети
- name: Allow PostgreSQL from internal subnet module: core.firewall.present params: port: 5432 proto: tcp action: allow source: 10.0.0.0/8Output
| Поле | Тип | Описание |
|---|---|---|
changed | bool | |
backend | ufw | firewalld | |
port | int | |
proto | string | |
action | string | |
source | string (только если задан, в нормализованной форме) | |
zone | string (только если задан) |
core.firewall.absent — Правило удалено.
Правило было и удалено.
Правила нет.
Параметры
| Параметр | Тип | Обяз. / дефолт | Описание |
|---|---|---|---|
port | int | required | Порт 1..65535. |
proto | stringtcp | udp | optional | Протокол tcp|udp (default tcp). |
action | stringallow | deny | optional | Действие allow|deny (default allow). |
source | string | optional | IPv4 CIDR или одиночный IPv4. |
zone | string | optional | Зона firewalld. |
Пример — Убрать ранее добавленное правило
- name: Remove the PostgreSQL rule module: core.firewall.absent params: port: 5432 proto: tcp source: 10.0.0.0/8Output
| Поле | Тип | Описание |
|---|---|---|
changed | bool | |
backend | ufw | firewalld | |
port | int | |
proto | string | |
action | string |
Справочник
Семантика backend-ов
Одно и то же правило по-разному транслируется в ufw и firewalld; идемпотентность в обоих случаях проверяется разбором вывода CLI (хрупкого между версиями, покрыт строгими тестами).
| Backend | Как транслируется правило | Проверка идемпотентности |
|---|---|---|
| ufw | present/absent → ufw allow|deny … / ufw delete …. Без source — краткая форма (80/tcp); с source — развёрнутая (proto tcp from <src> to any port <n>). | Парсинг табличного ufw status (учитываются direction-токены IN/OUT; IPv6-зеркала (v6) игнорируются). |
| firewalld | Простое allow без source → --add-port / --remove-port. Правило с source или action: deny → rich-rule (deny → reject). Мутации идут через --permanent + явный firewall-cmd --reload. | Простое правило — в --list-ports, rich-rule — в --list-rich-rules. |
Заметки
- IPv6 не поддержан в MVP — отвергается на Validate: оба backend-а работают только с IPv4, тихий приём IPv6 дал бы зацикленный add/drift.
- source нормализуется к канонической форме: одиночный IP → /32, CIDR с host-битами схлопывается к адресу сети.
- Идемпотентность — разбор вывода CLI (ufw status / firewall-cmd --list-*), хрупкого между версиями инструментов; покрыт строгими unit-тестами на зафиксированных образцах.
Безопасность и умолчания
- Работает только с конкретным правилом (add/delete): никогда не трогает default policy и никогда не включает файрвол целиком — нет ufw enable, systemctl start firewalld, правок ufw default / target зоны. Включение файрвола с дефолтной deny-политикой на удалённом хосте мгновенно отрезало бы SSH и потеряло управление.
- Инвариант покрыт unit-тестом: Apply не генерирует ни одной enable/default-команды.
- firewalld: мутации идут через --permanent + явный firewall-cmd --reload — правило переживает рестарт; --reload применяет permanent-конфиг в runtime, не перезапускает службу и не меняет default policy.
- Привилегии — декларация, не runtime-повышение прав: манифест объявляет run_as_root + exec_subprocess для статической сверки soul-lint с allowed_capabilities хоста; backend-вызовы идут с привилегиями процесса soul-агента (под root), повышения прав внутри модуля нет.