AlmaLinux и Rocky Linux часто выбирают для продакшен-серверов: это стабильные RHEL-совместимые системы с понятным циклом поддержки, SELinux из коробки и привычным набором административных инструментов. Один из таких инструментов — firewalld, штатный менеджер сетевого экрана, который управляет правилами netfilter через зоны, сервисы, порты и более гибкие rich rules.
Если вы только подняли VDS под сайт, API, панель управления или почтовый шлюз, firewall лучше настроить сразу, до установки лишних сервисов. Минимальный сценарий прост: оставить доступ по SSH, открыть 80 и 443 для веб-сервера, закрыть всё ненужное и добавить точечные исключения для админских IP.
На практике быстро появляются нюансы: IPv6, Docker, несколько интерфейсов, временные правила, ограничение доступа к админке, блокировка отдельных адресов, логирование подозрительных подключений. В этой инструкции разберём firewalld именно как рабочий инструмент администратора VDS на AlmaLinux и Rocky Linux.
Главная идея firewalld: вы не пишете длинный набор низкоуровневых правил вручную, а описываете политику доступа через зоны и команды. Это удобно, но требует дисциплины: понимать, что применено временно, что сохранено постоянно и какая зона реально привязана к интерфейсу.
Что такое firewalld и почему он уместен на VDS
firewalld — это сервис для динамического управления firewall без ручной перезагрузки всего набора правил. На современных AlmaLinux и Rocky Linux он обычно использует backend nftables, но администратор взаимодействует с ним через стабильный интерфейс firewall-cmd. Поэтому для большинства задач не нужно помнить синтаксис nftables или iptables: можно работать на уровне «открыть сервис», «закрыть порт», «разрешить только этому IP».
Для VDS firewalld полезен по нескольким причинам. Во-первых, он уже интегрирован в экосистему RHEL-like систем. Во-вторых, его зонам удобно сопоставлять сетевые интерфейсы: публичный интерфейс сервера можно держать в зоне public, а внутренний — в более доверенной зоне, если у вас есть приватная сеть между серверами. В-третьих, rich rules позволяют описывать более точные условия, чем обычное «порт открыт для всех».
Важно понимать границы инструмента. Firewalld — это не WAF, не защита от всех видов DDoS и не замена правильной настройки приложений. Он не исправит небезопасную админку, слабые пароли или открытый Redis без авторизации. Но он отлично выполняет базовую сетевую гигиену: уменьшает поверхность атаки, закрывает случайно поднятые службы и помогает быстро внедрять понятные правила доступа.
Перед началом: как не потерять доступ по SSH
Любая настройка firewall на удалённом сервере начинается с простого правила: сначала обеспечиваем запасной путь, потом меняем политику. Если вы подключены к VDS по SSH и ошиблись в правилах, можно заблокировать собственный доступ. Обычно это решается через консоль провайдера, но лучше не доводить до аварийного восстановления.
Перед изменениями проверьте текущий SSH-порт. В большинстве установок это 22, но на некоторых серверах его меняют на нестандартный. Посмотреть активные слушающие порты можно так:
ss -tulpenПроверьте, что firewalld установлен и запущен:
sudo systemctl status firewalldЕсли сервис отсутствует, установите его через пакетный менеджер. Для AlmaLinux и Rocky Linux используется dnf:
sudo dnf install firewalldЗапустите и включите автозапуск:
sudo systemctl enable --now firewalldПеред применением строгих правил удобно открыть вторую SSH-сессию и не закрывать первую. Ещё лучше — временно запланировать откат через systemd-run, если вы работаете с критичным сервером. Например, можно через несколько минут остановить firewalld, а после успешной проверки отменить задачу:
sudo systemd-run --on-active=5m systemctl stop firewalldПосле проверки правил посмотрите временный unit и отмените его, если всё хорошо:
systemctl list-timers --allЕсли вы только экспериментируете, можно сначала применять правила без --permanent. Тогда они действуют в runtime-конфигурации и пропадут после перезагрузки firewalld. Когда убедились, что доступ есть и сайт открывается, сохраняйте правила постоянно.
Runtime и permanent: две конфигурации, о которых часто забывают
У firewalld есть две «плоскости» настроек. Runtime — это текущие активные правила. Permanent — правила, которые будут загружены после перезапуска firewalld или сервера. Команда без --permanent меняет runtime. Команда с --permanent меняет постоянную конфигурацию, но не всегда мгновенно влияет на текущий firewall.
Типовой безопасный подход такой: сначала добавить правило во временную конфигурацию, проверить доступ, затем повторить с --permanent. Альтернативный подход: менять permanent и выполнить --reload, но на удалённом сервере это лучше делать только после понимания текущих правил.
Посмотреть состояние firewalld:
sudo firewall-cmd --stateПоказать активную зону и интерфейсы:
sudo firewall-cmd --get-active-zonesПоказать полную конфигурацию зоны по умолчанию:
sudo firewall-cmd --list-allПоказать permanent-конфигурацию зоны:
sudo firewall-cmd --permanent --list-allСинхронизировать runtime из permanent-конфигурации можно командой:
sudo firewall-cmd --reloadЗдесь есть важная ловушка: --reload может убрать временные правила, если они не были сохранены. Поэтому после серии runtime-изменений не делайте reload «на автомате», пока не перенесли нужные правила в permanent.

Зоны firewalld: public, trusted, drop и другие
Зона в firewalld — это набор правил, применяемый к интерфейсу или источнику трафика. На VDS чаще всего используется одна публичная сетевая карта, привязанная к зоне public. Этого достаточно для большинства сайтов. Но если у сервера есть приватная сеть, VPN-интерфейс или bridge контейнеров, зоны помогают разделить политику доступа.
Список доступных зон:
sudo firewall-cmd --get-zonesЗона по умолчанию:
sudo firewall-cmd --get-default-zoneЕсли интерфейс оказался не в той зоне, его можно назначить явно. Сначала узнайте имя интерфейса:
ip -br addressДопустим, публичный интерфейс называется ens3. Назначить его в зону public можно так:
sudo firewall-cmd --zone=public --change-interface=ens3И сохранить постоянно:
sudo firewall-cmd --permanent --zone=public --change-interface=ens3Для обычного публичного VDS не стоит использовать trusted на внешнем интерфейсе: эта зона фактически доверяет трафику. Зона drop, наоборот, жёстко отбрасывает входящие пакеты без ответа. Её можно применять для отдельных источников или специфичных сценариев, но для типового веб-сервера проще работать с public и явными разрешениями.
Базовый профиль для веб-сервера: SSH плюс 80 и 443
Минимальный набор для VDS с Nginx, Apache, Caddy или другим веб-сервером обычно включает SSH и HTTP/HTTPS. В firewalld можно открывать не только порты, но и сервисы. Сервис — это именованный профиль, где уже описаны порт и протокол. Например, http соответствует TCP 80, а https — TCP 443.
Посмотреть доступные сервисы:
sudo firewall-cmd --get-servicesОткрыть HTTP и HTTPS во временной конфигурации:
sudo firewall-cmd --zone=public --add-service=httpsudo firewall-cmd --zone=public --add-service=httpsСохранить постоянно:
sudo firewall-cmd --permanent --zone=public --add-service=httpsudo firewall-cmd --permanent --zone=public --add-service=httpsЕсли вы предпочитаете работать с портами напрямую, эквивалент будет таким:
sudo firewall-cmd --zone=public --add-port=80/tcpsudo firewall-cmd --zone=public --add-port=443/tcpНо для стандартных сервисов я обычно советую использовать имена http и https: конфигурация читается лучше. Для нестандартных приложений, например панели на 8443 или API на 9000, можно использовать --add-port.
Проверьте, что получилось:
sudo firewall-cmd --zone=public --list-allЕсли SSH-сервис почему-то отсутствует в зоне, добавьте его до любых ограничений:
sudo firewall-cmd --zone=public --add-service=sshsudo firewall-cmd --permanent --zone=public --add-service=sshПосле сохранения permanent-правил перезагрузите firewalld и проверьте доступ:
sudo firewall-cmd --reloadsudo firewall-cmd --zone=public --list-servicesЕсли сервер ещё только планируется, удобнее сразу выбрать тариф под задачу, развернуть чистую ОС и настроить firewall до установки приложений. Для таких сценариев подойдёт облачный VDS с AlmaLinux или Rocky Linux.
Когда обычных портов мало: зачем нужны rich rules
rich rules — это расширенный синтаксис firewalld для правил с условиями. С их помощью можно разрешать или запрещать трафик по IP-адресу, семейству адресов, сервису, порту, протоколу, добавлять логирование, ограничивать частоту логов и задавать действия accept, reject, drop.
Rich rules особенно полезны на VDS, где нельзя полагаться только на «порт открыт» или «порт закрыт». Например, публичный сайт должен принимать 80/443 от всех, но админская панель, метрики, тестовый API, PostgreSQL или Redis не должны быть доступны всему интернету. Здесь rich rules позволяют сделать точечные разрешения: открыть порт только для вашего офисного IP или приватной сети.
Синтаксис rich rule выглядит как строка, которую лучше брать в одинарные кавычки. Например, разрешить доступ к порту 8080 только с адреса 203.0.113.10:
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.10" port port="8080" protocol="tcp" accept'Сохранить это правило постоянно:
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.10" port port="8080" protocol="tcp" accept'Показать rich rules в зоне:
sudo firewall-cmd --zone=public --list-rich-rulesУдалить правило нужно точно той же строкой, которой оно было добавлено:
sudo firewall-cmd --zone=public --remove-rich-rule='rule family="ipv4" source address="203.0.113.10" port port="8080" protocol="tcp" accept'Для IPv6 используйте family="ipv6" и IPv6-адрес или подсеть. Не забывайте: если у сервера есть AAAA-запись и веб-сервер слушает IPv6, firewall должен быть продуман и для IPv4, и для IPv6. Нередкая ошибка — закрыть сервисы по IPv4 и случайно оставить их открытыми по IPv6.
Практические rich rules для VDS
Ниже — набор рабочих примеров, которые часто нужны администраторам. Адреса из диапазонов документации замените на свои реальные IP и подсети. Сначала применяйте правила во временную конфигурацию, проверяйте, затем добавляйте --permanent.
Разрешить SSH только с конкретного IP
Если у вас статический админский IP, можно не держать SSH открытым для всего интернета. Сначала добавьте разрешающее rich rule:
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.10" service name="ssh" accept'Затем удалите общий сервис SSH из зоны:
sudo firewall-cmd --zone=public --remove-service=sshПроверьте новый вход в отдельной SSH-сессии. Только после этого сохраняйте:
sudo firewall-cmd --permanent --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.10" service name="ssh" accept'sudo firewall-cmd --permanent --zone=public --remove-service=sshЕсли у вас динамический домашний IP, такой подход может неожиданно заблокировать доступ после смены адреса. В этом случае лучше использовать VPN, bastion-хост, несколько разрешённых источников или оставить SSH открытым, но усилить его ключами, ограничениями и защитой от перебора.
Открыть админку только для подсети
Допустим, панель приложения слушает порт 8443, а доступ к ней должен быть только из офисной подсети 198.51.100.0/24:
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="198.51.100.0/24" port port="8443" protocol="tcp" accept'Не добавляйте при этом --add-port=8443/tcp для всей зоны, иначе rich rule потеряет смысл: порт окажется открыт всем. Общая логика такая: публичные сервисы открываем сервисами или портами, приватные — только rich rules с источником.
Заблокировать конкретный IP
Если нужно быстро заблокировать отдельный адрес, можно использовать drop или reject. drop молча отбрасывает пакеты, reject отвечает отказом. Для грубой блокировки обычно используют drop:
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="203.0.113.200" drop'Не превращайте ручные блокировки в бесконечный список. Если адресов становится много, лучше использовать sets в nftables, fail2ban с backend firewalld или централизованную защиту на уровне периметра. Подробнее про динамические наборы адресов можно почитать в материале о nftables sets и blocklists.
Логировать подключения к нестандартному порту
Для диагностики иногда полезно увидеть, кто стучится в порт. Например, логировать попытки подключения к TCP 8443 и ограничить частоту логов:
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" port port="8443" protocol="tcp" log prefix="fw-8443 " level="info" limit value="5/m" reject'Смотреть сообщения можно через journal:
sudo journalctl -k -g fw-8443Не включайте слишком подробное логирование для массовых портов 80/443 без лимитов: на шумном публичном VDS это может быстро раздуть журналы и создать лишнюю нагрузку.
Порядок правил и типичные ловушки
Одна из причин, почему администраторы путаются в firewalld, — смешивание нескольких способов описать одно и то же. Например, порт 8443 может быть открыт через --add-port, через пользовательский service XML, через rich rule или через direct-правило. Потом кажется, что правило удалили, а доступ всё ещё есть. Поэтому держите конфигурацию простой: стандартные публичные сервисы — через --add-service, точечные исключения — через rich rules.
Проверять нужно не только firewalld, но и само приложение. Если firewall открыл 443, но Nginx не слушает порт, сайт всё равно не заработает. Если приложение слушает только 127.0.0.1, внешний доступ не появится даже при открытом firewall. Начинайте диагностику с трёх вопросов: слушает ли процесс порт, разрешает ли firewall входящий трафик, доходит ли пакет до сервера.
ss -tulpensudo firewall-cmd --zone=public --list-allsudo nft list rulesetКоманда nft list ruleset полезна для низкоуровневой диагностики, но не стоит редактировать эти правила вручную, если они управляются firewalld. Ручные изменения могут конфликтовать с последующим reload.
Ещё одна ловушка — Docker и другие контейнерные рантаймы. Они могут создавать собственные правила NAT и фильтрации. В результате опубликованный порт контейнера может быть доступен не так, как вы ожидаете. Если на VDS есть Docker, проверяйте не только firewalld, но и правила контейнерной сети, а также то, на какой адрес опубликован порт: на все интерфейсы или только на localhost. Для отдельного разбора пригодится статья про Docker, iptables, nftables и firewall.

ICMP, ping и IPv6: не закрывайте всё без разбора
Иногда администраторы пытаются «усилить безопасность» полным запретом ICMP. На практике это часто мешает диагностике и может ломать сетевые механизмы, особенно в IPv6. Для IPv4 запрет ping обычно не даёт серьёзной защиты: если на сервере открыт 443, его всё равно можно обнаружить. Зато вы теряете простой инструмент проверки доступности.
Для IPv6 ICMPv6 критичен: он участвует в обнаружении соседей, Path MTU Discovery и других базовых процессах. Без него можно получить странные симптомы: сайт открывается у одних пользователей и зависает у других, большие ответы не доходят, TLS-соединение обрывается на середине. Поэтому не применяйте «запретить весь ICMP» как универсальный совет.
Если нужно ограничить диагностический шум, делайте это аккуратно и проверяйте результат снаружи. Для публичного веб-сервера нормальная цель — минимальный набор открытых TCP-портов, а не тотальная блокировка всего, что не похоже на HTTP.
Как проверить правила снаружи и изнутри
Проверка только с самого сервера неполна. Если вы выполняете curl localhost, вы обходите внешний путь и firewall для публичного интерфейса может вообще не участвовать. Проверяйте с внешней машины: домашнего компьютера, другого VDS, мониторинга или CI-раннера.
На самом сервере проверьте слушающие порты:
ss -tulpenПроверьте список сервисов и rich rules:
sudo firewall-cmd --zone=public --list-servicessudo firewall-cmd --zone=public --list-portssudo firewall-cmd --zone=public --list-rich-rulesС внешнего узла можно проверить TCP-подключение к 80 и 443:
nc -vz example.com 80nc -vz example.com 443Для HTTPS полезен обычный curl:
curl -I https://example.comЕсли порт снаружи недоступен, а приложение слушает, проверьте цепочку целиком: DNS указывает на правильный IP, сервис слушает нужный адрес, firewalld разрешает порт, нет дополнительного cloud firewall в панели провайдера, нет локального reverse proxy, который принимает только localhost.
Безопасный шаблон настройки для нового VDS
Ниже — пример последовательности для нового веб-сервера на AlmaLinux или Rocky Linux. Он предполагает, что SSH остаётся открытым через сервис ssh, а публично нужны только 80 и 443. Команды сначала применяются в runtime, затем сохраняются в permanent.
sudo systemctl enable --now firewalldsudo firewall-cmd --set-default-zone=publicsudo firewall-cmd --zone=public --add-service=sshsudo firewall-cmd --zone=public --add-service=httpsudo firewall-cmd --zone=public --add-service=httpssudo firewall-cmd --zone=public --list-allsudo firewall-cmd --permanent --set-default-zone=publicsudo firewall-cmd --permanent --zone=public --add-service=sshsudo firewall-cmd --permanent --zone=public --add-service=httpsudo firewall-cmd --permanent --zone=public --add-service=httpssudo firewall-cmd --reloadsudo firewall-cmd --zone=public --list-allЕсли SSH должен быть доступен только с конкретного адреса, не удаляйте общий ssh до проверки rich rule. Сначала добавьте разрешение для своего IP, откройте вторую сессию, убедитесь, что вход работает, и только затем убирайте общий сервис SSH.
Как документировать firewall, чтобы через месяц всё было понятно
Firewall часто настраивается в спешке: срочно открыть порт для теста, временно разрешить подрядчику доступ, заблокировать подозрительный IP. Через месяц никто не помнит, почему правило появилось и можно ли его удалить. Поэтому хорошая практика — вести краткий журнал изменений в репозитории инфраструктуры или хотя бы в административной заметке.
Я обычно рекомендую хранить рядом с проектом файл с описанием сетевой политики: какие порты публичные, какие доступны только из VPN, какие временные исключения добавлены и когда их пересмотреть. Для воспроизводимости можно вынести команды firewall-cmd в Ansible playbook, shell-скрипт bootstrap или cloud-init.
Главное — не превращать сервер в уникальный «снежный ком», где правила существуют только в текущем runtime и нигде больше не описаны. Это особенно важно для командной поддержки, миграций и восстановления из резервных копий.
Мини-чек-лист для продакшена
- Проверьте активную зону командой
firewall-cmd --get-active-zones. - Убедитесь, что SSH разрешён до изменения политики.
- Откройте публично только нужные сервисы: обычно
httpиhttpsдля 80/443. - Для админских портов используйте rich rules с
source address. - Не забывайте про IPv6, если у домена есть AAAA-записи.
- Не смешивайте без необходимости
--add-port, rich rules, direct rules и ручной nftables. - Сначала проверяйте runtime, затем сохраняйте permanent.
- После
--reloadснова проверяйте--list-allи доступ снаружи. - Не включайте шумное логирование без
limit. - Документируйте нестандартные правила и временные исключения.
Итоги
Firewalld на AlmaLinux и Rocky Linux — удобный и достаточно мощный инструмент для базовой защиты VDS. Для типового веб-сервера достаточно понятной схемы: зона public, открытые сервисы ssh, http, https, а всё нестандартное — через аккуратные rich rules с ограничением по источнику.
Самое важное — не относиться к firewall как к магической кнопке «сделать безопасно». Он работает в связке с SSH-настройками, обновлениями, SELinux, конфигурацией веб-сервера, мониторингом и резервным доступом. Но если держать правила простыми, проверять runtime и permanent, не забывать про IPv6 и документировать исключения, firewalld становится надёжным помощником, а не источником внезапных простоев.
Начните с малого: проверьте активные зоны, откройте только 80/443 и SSH, уберите лишние порты, а затем добавьте rich rules для админских интерфейсов. Такой подход быстро снижает риски на публичном VDS и остаётся понятным для любого администратора, который придёт поддерживать сервер после вас.


