15%

Сэкономьте 15% на всех хостинговых услугах

Проверьте свои навыки и получите скидку на любой тарифный план

Используйте код:

Skills
Начать
21.10.2024
3 +1

Введение в Firewalld: динамическое управление брандмауэром на Linux

Firewalld — это демон управления межсетевым экраном пользовательского пространства для Linux, который предоставляет динамический интерфейс на основе зон поверх бэкендов фильтрации пакетов на уровне ядра iptables и nftables. В отличие от статических инструментов межсетевого экрана, требующих полного перезапуска службы для применения изменений правил, Firewalld изменяет правила netfilter на лету — сохраняя активные TCP-сессии и устраняя простои при обновлении политик.

Это руководство охватывает все операционные уровни Firewalld: его архитектурную модель, абстракции зон и служб, расширенные правила, конфигурацию времени выполнения и постоянную конфигурацию, а также точные команды, необходимые для безопасного управления производственным сервером.

Почему Firewalld заменил статические рабочие процессы iptables

Традиционное управление iptables означает написание правил в shell-скрипты или плоские конфигурационные файлы, а затем сброс и перезагрузку всего набора правил при каждом изменении. На загруженном сервере этот цикл сброса и перезагрузки обрывает активные соединения и создаёт кратковременное окно, в котором фильтрация не активна.

Firewalld решает эту проблему с помощью демона, активируемого через D-Bus (firewalld), который хранит авторитетное состояние правил и передаёт изменения ядру постепенно. Результатом являются атомарные обновления правил без прерывания соединений — критически важно для любого сервера, выполняющего постоянные рабочие нагрузки, такие как базы данных, VPN-туннели или долгоживущие API-соединения.

Когда вы настраиваете среду VPS Хостинга и вам нужно усилить её безопасность без перезагрузки или прерывания служб, Firewalld является естественным операционным выбором для дистрибутивов семейства RHEL и многих дистрибутивов семейства Debian.

Основная архитектура: как Firewalld взаимодействует с ядром

Понимание стека под Firewalld предотвращает неправильную конфигурацию и помогает отлаживать неожиданное поведение.

User Space
┌─────────────────────────────────────────────┐
│ firewall-cmd / firewall-config / D-Bus API  │
└────────────────────┬────────────────────────┘
                     │ D-Bus
┌────────────────────▼────────────────────────┐
│              firewalld daemon               │
│  (zone engine, service definitions, rich    │
│   rule parser, direct rule passthrough)     │
└────────────────────┬────────────────────────┘
                     │ nftables / iptables backend
Kernel Space
┌────────────────────▼────────────────────────┐
│           netfilter (kernel module)         │
└─────────────────────────────────────────────┘

Начиная с RHEL 8 и Fedora 32, Firewalld по умолчанию использует бэкенд nftables. В более старых системах или явно настроенных средах он использует бэкенд iptables. Вы можете проверить или переопределить активный бэкенд в /etc/firewalld/firewalld.conf с помощью директивы FirewallBackend.

Критическая ошибка: Никогда не смешивайте прямые команды iptables или nft с Firewalld на одном интерфейсе. Firewalld владеет таблицами netfilter, которые он создаёт; правила, вставленные вручную за пределами демона, будут молча перезаписаны при следующей перезагрузке.

Ключевые концепции Firewalld

Зоны

Зона — это именованный уровень доверия, применяемый к сетевому интерфейсу или диапазону исходных адресов. Каждый пакет, входящий в систему, сопоставляется с зоной, назначенной его входящему интерфейсу, и набор правил зоны определяет, что разрешено.

Firewalld поставляется со следующими предопределёнными зонами, упорядоченными от наиболее до наименее разрешительных:

ЗонаПолитика по умолчаниюТипичный случай использования
`trusted`Принять всёВнутренние лабораторные сети, loopback
`home`Отклонить, выбранные службы разрешеныДомашняя LAN с известными устройствами
`internal`Отклонить, выбранные службы разрешеныВнутренний корпоративный сетевой сегмент
`work`Отклонить, выбранные службы разрешеныОфисная сеть, умеренный уровень доверия
`public`Отклонить, разрешены SSH/DHCPv6Интерфейсы, обращённые в интернет
`external`Отклонить, включена маскировкаВнешний интерфейс маршрутизатора/NAT-шлюза
`dmz`Отклонить, разрешён SSHСерверы демилитаризованной зоны
`block`Отклонить с ICMP admin-prohibitedЯвное отклонение с ответом
`drop`Молча отброситьВраждебные источники, максимальная скрытность

Архитектурный нюанс: Зона может быть привязана к сетевому интерфейсу (например, eth0) или к исходному CIDR (например, 192.168.1.0/24). Привязка на основе источника имеет приоритет над привязкой на основе интерфейса, что позволяет применять различные политики к трафику, поступающему на один физический интерфейс из разных подсетей — паттерн, распространённый в мультиарендных или контейнеризированных средах.

Службы

Служба в Firewalld — это файл определения XML, хранящийся в /usr/lib/firewalld/services/ (системные значения по умолчанию) или /etc/firewalld/services/ (пользовательские переопределения). Каждый файл объявляет порты, протоколы и дополнительные вспомогательные модули, необходимые для именованного приложения.

Например, определение службы https открывает TCP-порт 443 и не загружает дополнительных вспомогательных модулей ядра. Служба ftp открывает TCP-порт 21 и загружает вспомогательный модуль nf_conntrack_ftp для обработки динамического согласования портов канала данных FTP.

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

Чтобы вывести список всех доступных определений служб в вашей системе:

firewall-cmd --get-services

Чтобы просмотреть XML-определение конкретной службы:

cat /usr/lib/firewalld/services/https.xml

Расширенные правила

Расширенные правила расширяют модель зон условной логикой, которую простая абстракция служб/портов не может выразить. Они поддерживают сопоставление по исходным и целевым адресам, диапазонам портов, протоколам, временным окнам и состоянию соединения, а также могут запускать действия, включая accept, drop, reject, log и audit.

Синтаксис расширенных правил следует структурированной грамматике:

rule [family="ipv4|ipv6"]
  [source address="addr[/mask]" [invert="true"]]
  [destination address="addr[/mask]" [invert="true"]]
  [service name="service-name"] | [port port="port" protocol="tcp|udp"]
  [log [prefix="prefix"] [level="level"] [limit value="rate/duration"]]
  [audit]
  [accept|drop|reject [type="reject-type"]]

Практический пример — ограничение частоты попыток входа по SSH до 3 в минуту с любого отдельного источника IPv4, затем регистрация и отбрасывание превышения:

firewall-cmd --zone=public --add-rich-rule='
  rule family="ipv4"
  service name="ssh"
  log prefix="SSH_RATELIMIT " level="warning" limit value="3/m"
  accept' --permanent
firewall-cmd --zone=public --add-rich-rule='
  rule family="ipv4"
  service name="ssh"
  drop' --permanent

Граничный случай: Порядок расширенных правил имеет значение. Firewalld оценивает расширенные правила в порядке их добавления в зоне. Если вы добавите широкое правило drop перед конкретным правилом accept, правило accept никогда не будет достигнуто. Всегда добавляйте более конкретные правила первыми.

Конфигурация времени выполнения и постоянная конфигурация

Это наиболее важное с операционной точки зрения различие в Firewalld и источник наиболее распространённых производственных ошибок.

ПараметрВремя выполненияПостоянная
Место храненияВ памяти (состояние демона)XML-файлы `/etc/firewalld/`
Когда применяетсяНемедленноПосле `–reload` или перезагрузки
Сохраняется после перезагрузкиНетДа
Безопасно для тестированияДаТребует перезагрузки для проверки
РискТеряется при перезапускеСохраняется после перезагрузок

Рекомендуемый рабочий процесс для производственных изменений:

  1. Примените правило только во время выполнения (без флага --permanent) и убедитесь, что оно работает как ожидается.
  2. Если всё верно, примените то же правило с --permanent, чтобы записать его на диск.
  3. Выполните firewall-cmd --reload, чтобы синхронизировать постоянную конфигурацию с состоянием времени выполнения и подтвердить соответствие.

Этот рабочий процесс предотвращает классический сценарий, когда администратор добавляет правило --permanent, перезагружает и обнаруживает, что заблокировал себе доступ по SSH — потому что тест во время выполнения выявил бы проблему до того, как она стала постоянной.

Установка и включение Firewalld

Firewalld установлен по умолчанию на RHEL, CentOS Stream, Fedora, AlmaLinux и Rocky Linux. На Debian и Ubuntu его необходимо устанавливать явно.

RHEL / CentOS Stream / AlmaLinux / Rocky Linux:

sudo dnf install firewalld

Debian / Ubuntu:

sudo apt-get update && sudo apt-get install firewalld

Примечание для пользователей Ubuntu: Если ufw активен, отключите его перед включением Firewalld, чтобы избежать конфликтующих правил netfilter:

sudo ufw disable
sudo systemctl disable ufw

Запустите и включите демон:

sudo systemctl start firewalld
sudo systemctl enable firewalld

Убедитесь, что демон запущен и бэкенд ядра активен:

sudo firewall-cmd --state
sudo firewall-cmd --info-zone=public

Основные команды Firewalld

Проверка текущего состояния

Проверка статуса демона:

sudo firewall-cmd --state

Вывод списка всех активных зон с назначенными интерфейсами и источниками:

sudo firewall-cmd --get-active-zones

Отображение полного набора правил для конкретной зоны:

sudo firewall-cmd --zone=public --list-all

Отображение полного набора правил для всех зон одновременно:

sudo firewall-cmd --list-all-zones

Управление зоной по умолчанию

Зона по умолчанию применяется к любому интерфейсу, явно не назначенному другой зоне:

sudo firewall-cmd --get-default-zone
sudo firewall-cmd --set-default-zone=public

Назначение интерфейса зоне

sudo firewall-cmd --zone=internal --change-interface=eth1 --permanent
sudo firewall-cmd --reload

Ошибка: В системах, использующих NetworkManager, назначения интерфейс-зона, выполненные через firewall-cmd, могут быть переопределены профилем подключения NetworkManager при повторном подключении. Задайте зону постоянно в подключении NetworkManager:

nmcli connection modify "Wired connection 1" connection.zone internal

Добавление и удаление служб

Разрешить HTTP в публичной зоне во время выполнения:

sudo firewall-cmd --zone=public --add-service=http

Сделать постоянным:

sudo firewall-cmd --zone=public --add-service=http --permanent

Удалить службу:

sudo firewall-cmd --zone=public --remove-service=http --permanent

Открытие и закрытие конкретных портов

Открыть TCP-порт 8080 во время выполнения:

sudo firewall-cmd --zone=public --add-port=8080/tcp

Открыть диапазон UDP-портов постоянно:

sudo firewall-cmd --zone=public --add-port=60000-61000/udp --permanent

Удалить порт:

sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanent

Добавление IP-адресов в белый и чёрный списки

Разрешить весь трафик из доверенной подсети управления:

sudo firewall-cmd --zone=trusted --add-source=10.0.0.0/24 --permanent

Заблокировать весь трафик с конкретного IP (отбрасывание на основе источника):

sudo firewall-cmd --zone=drop --add-source=203.0.113.45/32 --permanent

Перенаправление портов

Перенаправить внешний TCP-порт 2222 на внутренний SSH-порт 22 (полезно для скрытия стандартного SSH-порта без изменения sshd_config):

sudo firewall-cmd --zone=public --add-forward-port=port=2222:proto=tcp:toport=22 --permanent
sudo firewall-cmd --reload

IP-маскировка (NAT)

Включить маскировку во внешней зоне, чтобы позволить VPS, действующему как шлюз, выполнять NAT трафика из частной подсети:

sudo firewall-cmd --zone=external --add-masquerade --permanent
sudo firewall-cmd --reload

Перезагрузка и синхронизация конфигурации

Применить все постоянные изменения к работающему состоянию без разрыва соединений:

sudo firewall-cmd --reload

Выполнить полный перезапуск (разрывает все соединения — используйте только в экстренных случаях):

sudo systemctl restart firewalld

Создание пользовательских зон и определений служб

Пользовательская зона

sudo firewall-cmd --new-zone=management --permanent
sudo firewall-cmd --zone=management --add-source=10.10.0.0/16 --permanent
sudo firewall-cmd --zone=management --add-service=ssh --permanent
sudo firewall-cmd --zone=management --add-service=cockpit --permanent
sudo firewall-cmd --reload

Пользовательское определение службы

Создайте файл службы для пользовательского приложения, прослушивающего TCP 9200 (например, Elasticsearch):

sudo nano /etc/firewalld/services/elasticsearch.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Elasticsearch</short>
  <description>Elasticsearch HTTP API and transport port</description>
  <port protocol="tcp" port="9200"/>
  <port protocol="tcp" port="9300"/>
</service>
sudo firewall-cmd --reload
sudo firewall-cmd --zone=internal --add-service=elasticsearch --permanent
sudo firewall-cmd --reload

Firewalld и альтернативы: выбор подходящего инструмента

ФункцияFirewalldUFWiptables (прямой)nftables (прямой)
Динамические обновления правилДаНет (требует перезагрузки)НетНет
Модель на основе зонДаНетНетНет
Интеграция D-Bus / APIДаНетНетНет
Расширенные правила / условная логикаДаОграниченноДаДа
По умолчанию в семействе RHELДаНетУстаревшийДа (бэкенд)
По умолчанию на UbuntuНетДаУстаревшийДа (бэкенд)
Порог вхожденияСреднийНизкийВысокийВысокий
Подходит для скриптингаДаДаДаДа
Инструмент управления с GUIДа (firewall-config)НетНетНет

Для команд, управляющих Выделенными серверами в масштабе, D-Bus API Firewalld обеспечивает программное управление правилами из инструментов управления конфигурацией, таких как Ansible (модуль ansible.posix.firewalld) или Puppet, что является значительным операционным преимуществом по сравнению с поддержкой необработанных скриптов iptables.

Практические паттерны усиления безопасности

Защита веб-сервера

Типичная конфигурация для сервера, работающего с HTTPS, с SSH, ограниченным управляющим IP:

# Set the default zone
sudo firewall-cmd --set-default-zone=public --permanent

# Allow HTTPS globally
sudo firewall-cmd --zone=public --add-service=https --permanent

# Allow HTTP only to redirect to HTTPS (optional)
sudo firewall-cmd --zone=public --add-service=http --permanent

# Restrict SSH to a specific management IP only
sudo firewall-cmd --zone=public --remove-service=ssh --permanent
sudo firewall-cmd --zone=public --add-rich-rule='
  rule family="ipv4"
  service name="ssh"
  source address="198.51.100.10/32"
  accept' --permanent

sudo firewall-cmd --reload

Если вы запускаете веб-сервер вместе с развёртыванием SSL-сертификатов, обеспечение открытости порта 443 в правильной зоне перед выпуском сертификата (особенно для проверок ACME HTTP-01 или TLS-ALPN-01) является обязательным шагом, который часто упускают из виду.

Защита почтового сервера

Для серверов, работающих со стеками Email-хостинга (Postfix, Dovecot), необходимый набор служб:

sudo firewall-cmd --zone=public --add-service=smtp --permanent
sudo firewall-cmd --zone=public --add-service=smtps --permanent
sudo firewall-cmd --zone=public --add-service=imap --permanent
sudo firewall-cmd --zone=public --add-service=imaps --permanent
sudo firewall-cmd --zone=public --add-service=pop3s --permanent
sudo firewall-cmd --reload

Регистрация отброшенных пакетов для криминалистики

sudo firewall-cmd --zone=public --add-rich-rule='
  rule family="ipv4"
  log prefix="DROPPED_PUBLIC " level="warning" limit value="10/m"
  drop' --permanent
sudo firewall-cmd --reload

Журналы появляются в /var/log/messages или в журнале systemd (journalctl -k -g DROPPED_PUBLIC). Ограничьте частоту журналирования (как показано выше), чтобы предотвратить переполнение журнала в сценарии DDoS-атаки.

Firewalld на VPS под управлением cPanel

Если вы используете VPS с cPanel, имейте в виду, что cPanel устанавливает и управляет собственным уровнем межсетевого экрана (по умолчанию CSF/LFD). Запуск Firewalld вместе с CSF без явной координации приведёт к конфликтующим правилам netfilter. Рекомендуемый подход — выбрать один уровень управления межсетевым экраном на сервер и отключить другой, или использовать интерфейс прямой передачи правил Firewalld для интеграции с требованиями cPanel.

Устранение распространённых проблем Firewalld

Проблема: Правило, добавленное с --permanent, не вступает в силу.

Причина: Постоянные правила требуют перезагрузки для перехода в состояние времени выполнения.

Решение:

sudo firewall-cmd --reload

Проблема: SSH-соединение разорвано после изменения межсетевого экрана.

Причина: Служба SSH была удалена из активной зоны, или расширенное правило drop было добавлено перед правилом accept.

Решение: Получите доступ к серверу через внеполосную консоль (консоль VNC/KVM вашего хостинг-провайдера), затем восстановите службу SSH:

sudo firewall-cmd --zone=public --add-service=ssh --permanent
sudo firewall-cmd --reload

Проблема: firewall-cmd возвращает FirewallD is not running.

Причина: Демон аварийно завершил работу или никогда не был запущен.

Решение:

sudo systemctl start firewalld
sudo journalctl -u firewalld -n 50

Проблема: Правила выглядят корректными, но трафик всё равно блокируется.

Причина: Конфликтующее правило iptables или nft существует за пределами управляемых Firewalld таблиц, или SELinux/AppArmor блокирует соединение на уровне приложения.

Решение: Проверьте наличие ручных правил и отказов SELinux:

sudo iptables -L -n -v
sudo ausearch -m avc -ts recent

Проблема: Интерфейс не назначен ожидаемой зоне после перезагрузки.

Причина: Профиль подключения NetworkManager переопределяет назначение интерфейса Firewalld.

Решение: Задайте зону в профиле NetworkManager, как описано в разделе назначения интерфейсов выше.

Матрица принятия решений и технический чеклист

Используйте этот чеклист перед развёртыванием Firewalld на производственном сервере:

  • Подтвердите, что активный бэкенд межсетевого экрана (FirewallBackend в /etc/firewalld/firewalld.conf) соответствует поддержке nftables/iptables вашего ядра.
  • Убедитесь, что на тех же интерфейсах не активны конфликтующие инструменты межсетевого экрана (UFW, CSF, прямые скрипты iptables).
  • Явно назначьте каждый сетевой интерфейс зоне — никогда не полагайтесь исключительно на зону по умолчанию для многосетевых серверов.
  • Сначала применяйте все изменения во время выполнения, проверяйте подключение, затем фиксируйте с помощью --permanent и --reload.
  • Ограничьте доступ по SSH конкретными исходными IP через расширенные правила перед удалением службы SSH из публичной зоны.
  • Добавьте расширенные правила ограничения частоты для всех публично доступных служб аутентификации (SSH, SMTP, конечные точки входа HTTPS).
  • Включите журналирование для зоны drop с ограничением частоты для сбора данных об угрозах без переполнения хранилища.
  • Для серверов, управляемых через Панели управления VPS, убедитесь, что необходимые порты панели управления внесены в белый список перед применением ограничительной политики по умолчанию.
  • Проверьте постоянную конфигурацию, выполнив firewall-cmd --reload и немедленно убедившись, что все критически важные службы остаются доступными.
  • Документируйте каждую пользовательскую зону, расширенное правило и определение службы в системе контроля версий вместе с вашим кодом инфраструктуры.

FAQ

В чём разница между --reload и sudo systemctl restart firewalld?

--reload применяет постоянные изменения конфигурации к работающему демону без разрыва установленных соединений. systemctl restart полностью перезапускает процесс демона, что сбрасывает все правила netfilter и кратковременно прерывает активные соединения. Всегда предпочитайте --reload на производственных системах.

Могут ли Firewalld и iptables сосуществовать на одном сервере?

Не безопасно на одном интерфейсе. Firewalld управляет собственными цепочками netfilter; прямые команды iptables, изменяющие те же цепочки, будут перезаписаны при следующей перезагрузке Firewalld. Если вам нужно внедрить пользовательские правила, используйте вместо этого интерфейс --direct Firewalld или расширенные правила.

Как сделать правило времени выполнения постоянным без его повторного ввода?

Нет встроенной команды для перевода всех правил времени выполнения в постоянные за один шаг. Правильный рабочий процесс — применять каждое правило дважды: один раз без --permanent для тестирования, затем с --permanent для сохранения — с последующим --reload. Альтернативно используйте firewall-cmd --runtime-to-permanent (доступно в Firewalld 0.9+) для создания снимка текущего состояния времени выполнения на диск.

Почему назначение зоны сбрасывается после повторного подключения NetworkManager?

NetworkManager хранит назначения зон в собственных профилях подключения. Назначение firewall-cmd --change-interface является переопределением времени выполнения, которое NetworkManager может перезаписать. Сохраните назначение с помощью nmcli connection modify <profile-name> connection.zone <zone>.

Поддерживает ли Firewalld IPv6?

Да. Firewalld управляет правилами netfilter как для IPv4, так и для IPv6 одновременно. Расширенные правила требуют атрибута family="ipv6" для конкретного таргетирования IPv6-трафика. Правила зон и служб применяются к обоим семействам адресов по умолчанию, если только определение службы или расширенное правило не ограничивает область применения.

15%

Сэкономьте 15% на всех хостинговых услугах

Проверьте свои навыки и получите скидку на любой тарифный план

Используйте код:

Skills
Начать