Введение в 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' --permanentfirewall-cmd --zone=public --add-rich-rule='
rule family="ipv4"
service name="ssh"
drop' --permanentГраничный случай: Порядок расширенных правил имеет значение. Firewalld оценивает расширенные правила в порядке их добавления в зоне. Если вы добавите широкое правило drop перед конкретным правилом accept, правило accept никогда не будет достигнуто. Всегда добавляйте более конкретные правила первыми.
Конфигурация времени выполнения и постоянная конфигурация
Это наиболее важное с операционной точки зрения различие в Firewalld и источник наиболее распространённых производственных ошибок.
| Параметр | Время выполнения | Постоянная |
|---|---|---|
| — | — | — |
| Место хранения | В памяти (состояние демона) | XML-файлы `/etc/firewalld/` |
| Когда применяется | Немедленно | После `–reload` или перезагрузки |
| Сохраняется после перезагрузки | Нет | Да |
| Безопасно для тестирования | Да | Требует перезагрузки для проверки |
| Риск | Теряется при перезапуске | Сохраняется после перезагрузок |
Рекомендуемый рабочий процесс для производственных изменений:
- Примените правило только во время выполнения (без флага
--permanent) и убедитесь, что оно работает как ожидается. - Если всё верно, примените то же правило с
--permanent, чтобы записать его на диск. - Выполните
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 firewalldDebian / 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 --reloadIP-маскировка (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 --reloadFirewalld и альтернативы: выбор подходящего инструмента
| Функция | Firewalld | UFW | iptables (прямой) | 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-трафика. Правила зон и служб применяются к обоим семействам адресов по умолчанию, если только определение службы или расширенное правило не ограничивает область применения.
