Перейти к основному содержимому

Как устроено управление файрволом в qf

Это обзорный док для тех, кто открыл qf впервые и хочет понять как из объектов интерфейса собирается работающее правило фаервола — прежде чем читать частные гайды. Здесь — общая модель и один сквозной пример. Глубина по каждой теме — в соседних доках (ссылки в конце).

qf — централизованный фаервол: правила задаются в одном месте (Control Plane, веб-UI) и сами доставляются на нужные машины, где их применяет агент в ядре (eBPF). Вручную на самих машинах ничего настраивать не нужно.


Пять объектов и как они связаны

Всё управление строится на пяти сущностях. Поток — сверху вниз: лейблы решают, кого касается политика; политика несёт правила; правила фильтруют трафик.

HOST машина с агентом. Носит LABELS (пары key=value).
│ лейблы приходят двумя путями: из enrollment-токена и от групп.

HOST GROUP ярлык на пачке хостов. Даёт своим членам общие LABELS.
│ (лейбл самого хоста перекрывает групповой при конфликте ключа)

▼ Эффективные лейблы хоста = объединение(лейблы хоста + лейблы всех его групп)

POLICY SELECTOR + список RULES.
│ selector ← сопоставляется с эффективными лейблами хоста → «кого касается»
│ rules ← что делать с трафиком на этих хостах

RULE direction (ingress/egress) + action (allow/deny) + match (порты/proto/CIDR)

OBJECT GROUP переиспользуемый набор: ipset (CIDR) / portset (порты) / hostset.
правило ссылается на него по UUID вместо ручного списка адресов/портов.
ОбъектЧто этоЗачем
HostМашина с установленным агентомОбъект защиты; носит лейблы
LabelПара key=value на хостеПо ним политика находит свои хосты
Host GroupИменованная группа хостов с общими лейбламиУправлять лейблами пачки хостов в одном месте
PolicyСелектор + набор правилСвязывает «кого» (селектор) и «что» (правила)
RuleОдно разрешение/запретСобственно фильтрация трафика
Object GroupПереиспользуемый набор IP/портов/хостовНе дублировать списки адресов в правилах

Ключевая идея: политика находит хосты по лейблам, а не по именам машин. Пишете селектор env=prod — политика действует на любой хост (текущий и будущий) с этим лейблом. Имена хостов нужны только для точечных исключений.


Эффективные лейблы

Хост получает лейблы из двух источников:

  1. Enrollment-токен — при подключении хоста к флоту токен «штампует» на него заданные лейблы (например role=web, env=prod). Это основной путь.
  2. Host Group — если хост состоит в группе, он наследует лейблы группы.

Итоговый набор, по которому работают селекторы, — эффективные лейблы:

эффективные лейблы = лейблы всех групп хоста ⊕ собственные лейблы хоста
(при конфликте ключа собственный лейбл хоста побеждает)

Именно эффективные лейблы, а не «сырые», сопоставляются с селектором политики.


Как политика находит хост (selector)

Селектор политики — это условие на лейблы. Хост попадает под политику, если его эффективные лейблы удовлетворяют селектору.

  • Все лейблы сразу (AND)matchLabels. Селектор {role=web, env=prod} матчит хост только если у него есть оба лейбла.
  • Любой из вариантов (OR) — несколько блоков (anyOf). В UI собирается неявно: добавили несколько групп/хостов в «Host selector» → получаете OR.
  • Конкретная машина — по имени (для точечных исключений).
  • Все машины — match-all; UI требует подтверждения (защита от случайного применения на весь флот).

Новая политика по умолчанию никого не защищает — пока в «Host selector» пусто, правила написаны, но ни на одной машине не действуют. Это специально.

Подробно — selector.md.


Порядок правил: first-match-wins и default-ALLOW

На одном хосте может действовать много правил (из одной или разных политик). Для каждого пакета правила проверяются по порядку:

  1. Политики: меньше Priority = раньше (главнее).
  2. Внутри политики: правила по своему Priority.
  3. Первое подходящее правило сработало → остальные для этого пакета не смотрятся.
  4. Не подошло ни одно правило → пакет пропускается (default-ALLOW).

Default-ALLOW = фаервол режет только то, на что есть явный deny. Забыли правило — трафик пройдёт, машина не отрежется сама. Это осознанный выбор (fail-open): сегментация — это явные deny на конкретные порты при разрешённом по умолчанию трафике.

⚠️ Никогда не делайте deny без match (запрет всего) и не блокируйте порт 22 — отрежете доступ к серверу целиком, включая управление. Запреты — всегда на конкретные порты или адреса.

ℹ️ Enforcement применяется к L4 = TCP / UDP / ICMP / ICMPv6. Прочие протоколы (SCTP, GRE, ESP/IPsec, OSPF и т.п.) датапас не парсит — по умолчанию они проходят без правил (даже дефолтный deny к ним не применяется). Опциональный agent-флаг QF_DENY_UNKNOWN_PROTO включает fail-closed для такого трафика. Подробнее и радиус — ops-runbook.md → §8.4 «Неподдержанные L4».

Подробно про правила, приоритеты, версии/откат — policy-management.md.


Object Groups — переиспользуемые наборы

Чтобы не вписывать одни и те же списки адресов/портов в каждое правило, их выносят в именованный набор, на который правило ссылается:

ТипСодержитПример
ipsetCIDR/IP10.0.0.0/16, 203.0.113.5
portsetПорты и диапазоны443, 8080-8090
hostsetСелектор → динамически резолвится в IP подходящих хостов«IP всех role=db»

Правка набора каскадно обновляет все политики, где он используется. Набор, на который ссылается правило, нельзя удалить (защита от «висячих» ссылок). Подробно — fleet-management.md.


Сквозной пример: закрыть порт на всех prod-web

Задача: запретить входящие подключения на TCP-8080 на всех web-серверах окружения prod.

  1. Лейблы на хостах. Убедиться, что у нужных машин есть лейблы role=web и env=prod. Штатно они приезжают из enrollment-токена при подключении хоста; либо их даёт Host Group (см. шаг 2).
  2. (если нужно) Host Group. Host Groups → New group → имя prod-web, лейблы role=web, env=prod → добавить машины. Члены группы наследуют эти лейблы.
  3. Политика. Policies → New policy → имя, например close-8080.
  4. Host selector. Задать условие по лейблам: role=web и env=prod. Политика будет действовать на все подходящие хосты — и на будущие тоже.
  5. Правило. Add rule: Direction ingress, Action deny, Protocol tcp, Dst ports 8080.
  6. Preview impact. После нажатия открывается точный список хостов и какие правила изменятся, до применения — видно, не задето ли лишнее.
  7. Save. Правила компилируются и за пару секунд уезжают на все подходящие хосты. Хост офлайн — получит их при следующем подключении. Новая prod-web машина позже — подхватит правило автоматически.

Разбор «почему не идёт трафик»: на странице хоста — вкладка Ruleset (что реально применено), Verdicts (сработавшие log/deny), Counters (рост счётчика правила). См. раздел «Разбор инцидента» в operator-guide.md.


Куда дальше

ХочуЧитать
Пройти весь UI по шагам (со скриншотами)operator-guide.md
Понять правила, match-поля, приоритеты, версииpolicy-management.md
Разобраться, кому применяется политика (лейблы, AND/OR)selector.md
Управлять большим парком, токены, группы, каскад, IaCfleet-management.md
Понять статусы хоста (active/pending/degraded/stale)host-statuses.md

Частые заблуждения

  • «Создал политику с правилами, но ничего не блокируется.» Селектор пуст — политика ни на кого не действует. Условие задаётся в «Host selector».
  • «Селектор матчит по имени хоста.» Нет — по эффективным лейблам. Имя нужно только для точечного исключения на одну машину.
  • «deny не срабатывает.» Выше по приоритету стоит allow, который ловит трафик первым (first-match-wins). Разбирается по Priority.
  • «Забыл правило — машина отрежется.» Наоборот: default-ALLOW, непокрытый трафик проходит. Отрезает только явный deny.
  • «Обычный токен заведёт хост в группу.» Нет — токен задаёт только лейблы. Членство в группе — отдельный шаг (или bulk-токен с target_group_id).