Удаление одного порта из правила firewall часто приводит к неожиданным сбоям, потому что правило почти всегда описывает несколько комбинаций трафика, а не один конкретный доступ. Правильный подход — рассматривать правило как множество потоков (flows) и удалить только конкретный кортеж: (source, destination, protocol/port).

Короткий ответ

Удаление порта из allow-правила — это задача вычитания множеств, а не простое редактирование. Если правило содержит несколько источников, назначений и сервисов, оно разрешает декартово произведение этих множеств:

Allowed = S × D × P

Корректное конечное состояние должно быть эквивалентно:

NewAllowed = OriginalAllowed − {конкретный поток}

Поскольку большинство межсетевых экранов не поддерживают “вычитание” внутри одного правила, это достигается через рефакторинг:

  • Явно разрешить потоки, которые должны остаться (retained flows) и пересекаются с удаляемым.
  • Су́зить исходное широкое правило так, чтобы оно больше не совпадало с удаляемым кортежем.
  • Проверить, что удалён только нужный поток и не добавлены новые разрешения.

Почему удаление порта — операционно рискованная операция

Правило firewall с группами объектов — это не одна строка разрешения. Это матрица разрешений. Если правило определяет множества:

  • S — источники
  • D — назначения
  • P — сервисы (protocol/port)

Фактически разрешено:

Allowed = S × D × P

Пример: если |S| = 3, |D| = 4, |P| = 5, то правило разрешает 3 × 4 × 5 = 60 потоков. Удалив один сервис, вы удалите его сразу для 12 потоков (3 × 4).

Почему интерфейс вводит в заблуждение

GUI большинства firewall показывает правило как одну строку — это создаёт ложное ощущение атомарности. Но если в правиле есть группы адресов/сервисов или “any”, оно разворачивается в комбинаторную матрицу.

При удалении TCP/443 система пересчитывает:

S × D × (P − {443})

Изменение применяется ко всем комбинациям. Именно поэтому “маленькие правки” ломают продакшен, особенно когда:

  • сервисные группы переиспользуются в нескольких политиках;
  • широкие правила покрывают разные зоны/окружения;
  • объекты пересекаются (вложенные группы, дубли подсетей);
  • в полях встречается “any”.

Практический пример

Исходное правило

Rule 1010 — Action: Allow

Источники

  • 10.10.0.0/24
  • 10.20.5.0/24

Назначения

  • 192.168.10.10
  • 192.168.10.20

Сервисы

  • TCP/80
  • TCP/443
  • TCP/3389

Количество потоков:

2 × 2 × 3 = 12

Требование

Удалить только: 10.10.0.0/24 → 192.168.10.20 : TCP/3389

Остальные 11 потоков должны сохраниться.

Что произойдёт при простом удалении TCP/3389

Новое количество потоков:

2 × 2 × 2 = 8

RDP будет удалён для обеих подсетей и обоих серверов — это нарушает требование и создаёт сбой.

Правильное вычитание множества

Удаляемый кортеж:

{10.10.0.0/24} × {192.168.10.20} × {TCP/3389}

Нужно сохранить:

Все исходные потоки − этот кортеж

Ручной рефакторинг правил

Удаляемый поток: 10.10.0.0/24 → 192.168.10.20 : TCP/3389. Подход: явно сохранить пересекающиеся разрешения и сузить широкое правило так, чтобы удаляемый поток не совпадал ни с одним allow.

Шаг 1 — Сохранить пересекающиеся разрешённые потоки

Оставляем:

  • 10.10.0.0/24 → 192.168.10.20 : TCP/80
  • 10.10.0.0/24 → 192.168.10.20 : TCP/443

Создаём правило выше исходного:

Rule 1008: Allow
  Source:      10.10.0.0/24
  Destination: 192.168.10.20
  Service:     TCP/80, TCP/443

Шаг 2 — Су́зить исходное правило

Исключаем комбинацию источника и назначения из широкого правила. Один из понятных вариантов — разделить по назначениям:

Rule 1010 (Modified): Allow
  Source:      10.10.0.0/24, 10.20.5.0/24
  Destination: 192.168.10.10
  Service:     TCP/80, TCP/443, TCP/3389
Rule 1011 (New): Allow
  Source:      10.20.5.0/24
  Destination: 192.168.10.20
  Service:     TCP/80, TCP/443, TCP/3389

Если Rule 1008 расположен выше Rule 1010/1011, удалённый поток не совпадает ни с одним allow-правилом и блокируется политикой по умолчанию (implicit deny) либо отдельным deny ниже по базе правил.

Автоматизация детерминированного вычитания

Ручной расчёт быстро становится ненадёжным, если источников/назначений много, сервисы сгруппированы или объекты переиспользуются в других правилах. В таких случаях лучше генерировать итоговый набор правил из явного “Original − Removed”, а не подбирать split вручную.

Для этого можно использовать Firewall Rule Splitter:
https://nttools.ru/en/firewall-rule-splitter/

Инструмент моделирует правило как SRC × DST × SERVICE, удаляет заданные потоки и формирует минимальный эквивалентный набор правил без расширения доступа и без случайных перекрытий.

Входные данные / Результаты / Контроль безопасности

Входные данные

  • Источники: IP, CIDR или “any”.
  • Назначения: IP/host (или “any”).
  • Сервисы: protocol/port (например, tcp/443, udp/53).
  • Потоки для удаления: явные кортежи (src → dst : service).
  • Стратегия группировки и лимит объектов в правиле: управляют формой вывода и количеством правил.

Результаты

  • Человекочитаемые правила: итоговые allow-правила после вычитания.
  • JSON-экспорт: для ревью и автоматизации.
  • CSV-экспорт: удобно для тикетов/согласований.
  • Ссылка на сессию: воспроизводимость входных данных при peer review.

Контроль безопасности

  • Детерминированное вычитание: результат строго соответствует “Original − Removed”.
  • Контроль области: снижает риск случайного расширения доступа при ручном рефакторинге.
  • Проверяемость: вывод + экспорт позволяют валидировать намерение до внедрения.
  • Воспроизводимость: share-сессии уменьшают расхождения между инженерами и ревьюерами.

Чеклист проверки

До изменения

  • Определён точный кортеж для удаления (src, dst, protocol/port).
  • Оценена размерность правила (|S| × |D| × |P|).
  • Проверено, используется ли сервис/группа в других правилах.
  • Сохранён бэкап/снимок конфигурации и определён план отката.

После изменения

  • Удалённый поток действительно блокируется (проверка на новой сессии).
  • Соседние “похожие” разрешённые потоки работают (тот же src/dst, другие порты).
  • Проверены счётчики совпадений правил/логи (новые правила реально матчятся).
  • Не появилось новых разрешений из-за wildcard/“any”.

Практические замечания

  • Stateful-сессии могут скрыть ошибку. Существующие TCP-сессии иногда продолжают жить после изменения политики. Валидируйте на новых соединениях или сбрасывайте релевантное состояние.
  • Переиспользуемые объекты — скрытая зависимость. Не редактируйте общие сервисные группы без проверки ссылок/владельцев. Часто безопаснее создать новый узкий объект.
  • NAT влияет на атрибуцию совпадения. В разных платформах матчинг может происходить до или после трансляции. При проверке убедитесь, что тестируете адреса, по которым реально идёт match.

Когда правило лучше разделить заранее

Рефакторинг обязателен, если:

  • разные подсети требуют разного набора сервисов;
  • в правиле более ~5–7 сервисов и оно часто меняется;
  • требования комплаенса/сегментации различаются по зонам;
  • встречается “any” в нескольких полях, и матрица становится слишком большой для ручного контроля.

Заключение

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

Надёжный подход: определить точный удаляемый поток, явно сохранить пересекающиеся разрешения, сузить широкое правило и валидировать результат по негативным и позитивным сценариям. При росте сложности используйте автоматизацию, чтобы получить детерминированный “Original − Removed” до внедрения.