Firewalld — это современный динамический демон firewall для Linux, который заменяет iptables в качестве инструмента управления firewall по умолчанию. Он предлагает более простой зональный подход к настройке firewall с управлением правилами в runtime- и permanent-режимах. В этом руководстве рассматривается настройка firewall для production-серверов с точки зрения senior-разработчика.
Почему Firewalld
Firewalld предоставляет существенные преимущества по сравнению с «сырым» iptables:
- Динамические правила: применяйте изменения без перезапуска firewall
- Зональный подход: группируйте интерфейсы и источники по зонам безопасности
- Интерфейс D-Bus: программный доступ для приложений
- Rich rules: человекочитаемый синтаксис для сложных правил
- Определения сервисов: предопределённые правила для распространённых сервисов
Установка
CentOS/RHEL/Fedora
# Обычно уже предустановлен, но при необходимости:
sudo dnf install firewalld
# Запустить и включить
sudo systemctl start firewalld
sudo systemctl enable firewalld
# Проверить статус
sudo firewall-cmd --state
Ubuntu/Debian
sudo apt install firewalld
sudo systemctl start firewalld
sudo systemctl enable firewalld
Понимание зон
Firewalld использует зоны для определения уровней доверия к сетевым подключениям:
| Zone | Описание | Сервисы по умолчанию |
|---|
| drop | Отбрасывать все входящие, без ответа | Нет |
| block | Отклонять все входящие с сообщением | Нет |
| public | Недоверенные сети (по умолчанию) | ssh, dhcpv6-client |
| external | Для маршрутизаторов с NAT masquerading | ssh |
| dmz | Публично доступные серверы | ssh |
| work | Рабочая среда | ssh, dhcpv6-client |
| home | Домашняя среда | ssh, mdns, dhcpv6-client |
| internal | Внутренние сети | То же, что и home |
| trusted | Все подключения разрешены | Все |
Просмотр информации о зоне
# Список всех зон
sudo firewall-cmd --get-zones
# Получить зону по умолчанию
sudo firewall-cmd --get-default-zone
# Получить активные зоны
sudo firewall-cmd --get-active-zones
# Показать всё в зоне
sudo firewall-cmd --zone=public --list-all
# Список всех зон с подробностями
sudo firewall-cmd --list-all-zones
Установка зоны по умолчанию
# Изменить зону по умолчанию
sudo firewall-cmd --set-default-zone=home
# Назначить интерфейс зоне
sudo firewall-cmd --zone=internal --change-interface=eth1 --permanent
sudo firewall-cmd --reload
Управление сервисами
Список и включение сервисов
# Список доступных сервисов
sudo firewall-cmd --get-services
# Список сервисов в зоне
sudo firewall-cmd --zone=public --list-services
# Добавить сервис (только runtime)
sudo firewall-cmd --zone=public --add-service=http
# Добавить сервис permanent
sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent
sudo firewall-cmd --reload
# Удалить сервис
sudo firewall-cmd --zone=public --remove-service=http --permanent
sudo firewall-cmd --reload
Распространённые сервисы
# Веб-сервер
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
# База данных
sudo firewall-cmd --permanent --add-service=mysql
sudo firewall-cmd --permanent --add-service=postgresql
# Почта
sudo firewall-cmd --permanent --add-service=smtp
sudo firewall-cmd --permanent --add-service=imap
sudo firewall-cmd --permanent --add-service=imaps
# Применить всё
sudo firewall-cmd --reload
Управление портами
Открытие конкретных портов
# Открыть порт (runtime)
sudo firewall-cmd --zone=public --add-port=8080/tcp
# Открыть порт permanent
sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
sudo firewall-cmd --reload
# Открыть диапазон портов
sudo firewall-cmd --zone=public --add-port=5000-5100/tcp --permanent
# Список открытых портов
sudo firewall-cmd --zone=public --list-ports
# Удалить порт
sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanent
sudo firewall-cmd --reload
UDP-порты
# DNS
sudo firewall-cmd --permanent --add-port=53/udp
# VPN
sudo firewall-cmd --permanent --add-port=1194/udp
# Применить
sudo firewall-cmd --reload
Rich rules
Rich rules обеспечивают тонкую настройку:
Разрешить с конкретного IP
# Разрешить всё с IP
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" accept' --permanent
# Разрешить конкретный порт с IP
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="3306" accept' --permanent
# Разрешить из подсети
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="22" accept' --permanent
Заблокировать конкретный IP
# Отбрасывать всё с IP
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.50" drop' --permanent
# Reject (отправляет ответ)
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.50" reject' --permanent
Ограничение скорости
# Ограничить подключения SSH (защита от brute force)
sudo firewall-cmd --zone=public --add-rich-rule='rule service name="ssh" limit value="3/m" accept' --permanent
Логирование
# Логировать отброшенные пакеты
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" log prefix="Dropped: " level="info" drop' --permanent
Список rich rules
sudo firewall-cmd --zone=public --list-rich-rules
Защита SSH
Лучшая практика: ограничьте SSH только доверенными IP.
# Создать trusted-зону для SSH
sudo firewall-cmd --zone=trusted --add-service=ssh --permanent
# Добавить доверенные IP
sudo firewall-cmd --zone=trusted --add-source=192.168.1.0/24 --permanent
sudo firewall-cmd --zone=trusted --add-source=10.20.30.40 --permanent
# Удалить SSH из public-зоны
sudo firewall-cmd --zone=public --remove-service=ssh --permanent
# Применить
sudo firewall-cmd --reload
Проброс портов
Проброс на другой порт
# Пробросить порт 80 на 8080
sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080 --permanent
# Пробросить на другой IP
sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.10:toport=8080 --permanent
# Включить masquerading (требуется для проброса на другие хосты)
sudo firewall-cmd --zone=public --add-masquerade --permanent
sudo firewall-cmd --reload
Пользовательские определения сервисов
Создание пользовательского сервиса
# Создать service-файл
sudo cat > /etc/firewalld/services/myapp.xml << 'EOF'
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>MyApp</short>
<description>My Custom Application</description>
<port protocol="tcp" port="3000"/>
<port protocol="tcp" port="3001"/>
</service>
EOF
# Перезагрузить, чтобы распознать новый сервис
sudo firewall-cmd --reload
# Использовать сервис
sudo firewall-cmd --zone=public --add-service=myapp --permanent
sudo firewall-cmd --reload
Пример для production-сервера
Полная настройка для типичного web-сервера:
#!/bin/bash
# Безопасная конфигурация firewall для веб-сервера
# Установить зону по умолчанию
firewall-cmd --set-default-zone=public
# Удалить ненужные сервисы
firewall-cmd --zone=public --remove-service=dhcpv6-client --permanent
# Веб-сервисы
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --zone=public --add-service=https --permanent
# SSH только с доверенных IP
firewall-cmd --zone=trusted --add-service=ssh --permanent
firewall-cmd --zone=trusted --add-source=10.0.0.0/8 --permanent
firewall-cmd --zone=public --remove-service=ssh --permanent
# Порты приложения (только внутренние)
firewall-cmd --zone=internal --add-port=3000/tcp --permanent # Node.js
firewall-cmd --zone=internal --add-port=6379/tcp --permanent # Redis
firewall-cmd --zone=internal --add-source=10.0.1.0/24 --permanent
# Ограничить скорость публичного web-трафика
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" service name="http" limit value="25/s" accept' --permanent
# Логировать отброшенные пакеты (для отладки)
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" log prefix="DROPPED: " level="warning" limit value="5/m"' --permanent
# Применить все изменения
firewall-cmd --reload
# Проверить
firewall-cmd --list-all-zones
Runtime vs Permanent
# Только runtime (теряется после перезапуска)
sudo firewall-cmd --add-service=http
# Permanent (сохраняется после перезапуска)
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --reload
# Сделать runtime-правила permanent
sudo firewall-cmd --runtime-to-permanent
# Перезагрузить permanent-правила (сбросить runtime-изменения)
sudo firewall-cmd --reload
# Полный перезапуск
sudo firewall-cmd --complete-reload
Сброс к настройкам по умолчанию
# Удалить файлы пользовательских зон
sudo rm /etc/firewalld/zones/*
# Перезагрузить значения по умолчанию
sudo firewall-cmd --complete-reload
Устранение неполадок
Проверка логов
# Просмотреть логи firewalld
sudo journalctl -u firewalld
# Просмотреть отброшенные пакеты (если включено логирование)
sudo journalctl -k | grep DROPPED
Проверка доступности
# С другой машины
nc -zv server-ip 80
nmap -p 22,80,443 server-ip
Ключевые выводы
- Используйте зоны: сопоставляйте уровни доверия сети с зонами
- Permanent + reload: всегда используйте
--permanent и --reload - Ограничивайте SSH: перенесите SSH в trusted-зону с конкретными источниками
- Rich rules для точности: фильтрация по IP и ограничение скорости
- Определения сервисов: создавайте переиспользуемые service-файлы для приложений
- Логируйте аккуратно: включайте логирование для отброшенных пакетов во время отладки
Firewalld предоставляет надёжный и управляемый firewall, который балансирует безопасность и удобство использования — это необходимо для любого production Linux-сервера.