Начиная с CentoOS 7 для настройки правил фильтрации трафика появился новый инструмент firewalld. Именно его рекомендуется использовать для управления правилами iptables. В CentOS 8 вместо стандартного пакета фильтрации iptables теперь используется фреймворк nftables, и при настройке правил файервола через firewalld на самом деле вы настраиваете nftables. В этой статье мы рассмотрим установку, основные концепции и настройку межсетевого экрана firewalld на сервере под управлением CentOS 8 (в CentOS 7 все аналогично).
Основные концепции firewalld, зоны и правила
Перед тем как приступить к установке и настройке firewalld, мы познакомимся с понятием зон, которые используются для определения уровня доверия к различным соединениям. Для различных зон firewalld можно применить различные правила фильтрации, указывать активные опции брандмауэра в виде предварительно определенных служб, протоколов и портов, перенаправления портов и rich-rules.
Firewalld фильтрует входящий трафик по зонам в зависимости от примененных к зоне правил. Если IP-адрес отправителя запроса соответствует правилам какой-либо зоны, то пакет будет отправляться через эту зону. Если же адрес не соответствует ни одной из настроенных на сервере зоне, пакет будет обрабатываться зоной используемой по умолчанию. При установке firewalld зона по умолчанию называется public.
В firewalld есть зоны, где уже предварительно настроены разрешения для различных служб. Можно использовать эти настройки или создавать собственные зоны. Список зон по-умолчанию, которые создаются при установке firewalld (хранятся в каталоге /usr/lib/firewalld/zones/):
drop | минимальный уровень доверия. Все входящие соединения блокируются без ответа, допускаются только исходящие соединения; |
block | зона схожа с предыдущей, но при отклонении входящих запросов отправляется сообщение icmp-host-prohibited для Ipv4 или icmp6-adm-prohibited для Ipv6; |
public | представляет общественные, недоверенные сети. Можно разрешать избранные входящие соединения в индивидуальном порядке; |
external | внешние сети при использовании брандмауэра в качестве шлюза. Она настроена для маскирования NAT, поэтому ваша внутренняя сеть остается частной, но доступной; |
internal | антоним зоны external. Хост обладают достаточным уровнем доверия, доступен ряд дополнительных служб; |
dmz | используется для компьютеров, расположенных в DMZ (изолированные компьютеры без доступа к остальной сети). Разрешены только определенные входящие соединения; |
work | зона для рабочих машин (большинство компьютеров в сети доверенные); |
home | зона домашней сети. Можно доверять большинству ПК, но поддерживаются только определенные входящие соединения; |
trusted | доверять всем машинам в сети. Наиболее открытая из всех доступных опций, требует сознательного использования. |
В firewalld используется два набора правил — постоянные и временные. Временные правила работают до перезагрузки сервера. По умолчанию при добавлении правил в firewalld, правила считаются временными (runtime). Чтобы добавить правило на постоянной основе нужно использовать флаг — permanent. Такие правила будут применяться после перезагрузки сервера.
Установка и включение firewalld в CentOS
В CentOS 7/8 firewalld устанавливается по умолчанию при установке ОС. Если вы его удалили и хотите установить firewalld, можете воспользоваться стандартным менеджером yum/dnf:
# yum install firewalld -y
— для Centos 7
# dnf install firewalld -y
— для Centos 8
Чтобы демон firewalld запускался автоматически со стартом сервера, нужно добавить его в автозагрузку:
# systemctl enable firewalld
И запустить:
# systemctl start firewalld
Проверить статус сервиса:
# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2019-10-14 14:54:40 +06; 22s ago Docs: man:firewalld(1) Main PID: 13646 (firewalld) CGroup: /system.slice/firewalld.service └─13646 /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid Oct 14 14:54:40 server.vpn.ru systemd[1]: Starting firewalld - dynamic firewall daemon... Oct 14 14:54:40 server.vpn.ru systemd[1]: Started firewalld - dynamic firewall daemon.
Либо командой:
# firewall-cmd --state
# firewall-cmd --state
running
Работа с правилами firewalld
Правила по умолчанию:
Перед настройкой правил firewalld, нужно проверить, какая зона используется по умолчанию:
# firewall-cmd --get-default-zone
Так как firewalld мы только установили и еще не настраивали, у нас зона по-умолчанию public.
Проверим активную зону. Она также одна — public:
# firewall-cmd --get-active-zones
public interfaces: eth0
Как видим, сетевой интерфейс eth0 управляется зоной public.
# ip link show
Или
# nmcli device status
Чтобы посмотреть правила активной зоны, введите:
# firewall-cmd --list-all
public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
Из листинга видно, что в данную зону добавлены обычные операции, связанные с DHCP-клиентом и ssh.
Доступные зоны
Чтобы просмотреть список всех зон, нужно выполнить команду:
# firewall-cmd --get-zones
У меня получился такой список:
block dmz drop external home internal public trusted work
Чтобы проверить правила конкретной зоны, нужно добавить флаг — zone.
# firewall-cmd --zone=home --list-all
home target: default icmp-block-inversion: no interfaces: sources: services: dhcpv6-client mdns samba-client ssh ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:
Правила всех зон, можно просмотреть командой:
# firewall-cmd --list-all-zones
Листинг будет довольно большой, так как зон может быть много.
Изменение зоны по умолчанию.
По умолчанию все сетевые интерфейсы расположены в зоне public, но их можно перенести в любую из зон, командой:
# firewall-cmd --zone=home —change-interface=eth0
После параметра —zone= указать нужную зону.
Чтобы изменить зону по умолчанию, нужно применить команду:
# firewall-cmd --set-default-zone=home
Добавление правил для приложений
Чтобы открыть порт для приложения, можно добавить в исключения сервис. Вывести список доступных сервисов:
# firewall-cmd --get-services
Вывод будет содержать большое количество сервисов. Подробная информация о службе содержится в ее xml файле. Эти файлы расположены в директории /usr/lib/firewalld/services.
Например:
# cd /usr/lib/firewalld/services
# cat smtp.xml
<?xml version="1.0" encoding="utf-8"?> <service> <short>Mail (SMTP)</short> <description>This option allows incoming SMTP mail delivery. If you need to allow remote hosts to connect directly to your machine to deliver mail, enable this option. You do not need to enable this if you collect your mail from your ISP's server by POP3 or IMAP, or if you use a tool such as fetchmail. Note that an improperly configured SMTP server can allow remote machines to use your server to send spam.</description> <port protocol="tcp" port="25"/> </service>
В XML файле есть описание сервиса, протокол и номер порта, который будет открыт в firewalld.
При добавлении правил, вы можете использовать параметр —add-service, чтобы открыть доступ определенному сервису:
# firewall-cmd --zone=public --add-service=http
success
# firewall-cmd --zone=public --add-service=https
success
После добавления правил, можно проверить, добавлены ли сервисы в указанную зону:
# firewall-cmd --zone=public --list-services
dhcpv6-client http https ssh
Если вы хотите сделать эти правила постоянными, при добавлении нужно добавить параметр —permanent.
Чтобы удалить сервис из зоны:
# firewall-cmd --permanent --zone=public --remove-service=http
# firewall-cmd --zone=public --permanent --list-services
dhcpv6-client https ssh test
Если вы хотите добавить в исключения свой сервис, вы можете создать файл xml самостоятельно и заполнить его. Можно скопировать данные с любого сервиса, изменить название, описание и номер порта.
Скопируем файл smtp.xml в директорию для работы с сервисами пользователей:
# cp /usr/lib/firewalld/services/smtp.xml /etc/firewalld/services
Измените описание сервиса в файле.
Сам файл xml тоже нужно переименовать по имени вашего сервиса. После чего, нужно перезагрузить firewalld и проверить есть ли наш сервис в списке:
# firewall-cmd --get-services
Я назвал сервис test и в списке он появился:
syslog-tls telnet test tftp
Теперь можно добавить созданный сервис в любую зону:
# firewall-cmd --zone=public --add-service=test --permanent
success
# firewall-cmd --zone=public --permanent --list-services
dhcpv6-client http https ssh test
Если вы на нашли нужный вам сервис в списке, вы можете открыть нужный порт на firewalld командой:
# firewall-cmd --zone=public --add-port=77/tcp
— открыть 77 порт tcp
# firewall-cmd --zone=public --add-port=77/udp
— открыть 77 порт udp
# firewall-cmd --zone=public --add-port=77-88/udp
— открыть диапазон портов 77-88 udp
# firewall-cmd --zone=public --list-ports
— проверить список разрешенных портов
Заблокировать/разрешить ICMP ответы:
# firewall-cmd --zone=public --add-icmp-block=echo-reply
# firewall-cmd --zone= public --remove-icmp-block=echo-reply
Удалить добавленный порт:
# firewall-cmd --zone=public --remove-port=77/udp
— удалить временное правило 77 udp
# firewall-cmd --permanent --zone=public --remove-port=77/udp
— удалить постоянное правило
Добавление собственных зон
Вы можете создать собственную зону (назову ее our):
# firewall-cmd --permanent --new-zone=our
После создания новой зоны, как и после создания сервиса, нужна перезагрузка firewalld:
# firewall-cmd --reload
success
# firewall-cmd --get-zones
block dmz drop external home internal our public trusted work
Зона our доступна. Вы можете добавлять в нее сервисы или открывать определенные порты.
Firewalld: блокировка IP-адресов, создание исключений
Вы можете добавлять в исключения firewalld доверенные адреса IP адреса или блокировать нежелательные.
Чтобы добавить в исключения конкретный IP- адрес (например 8.8.8.8) на вашем сервере через firewalld, используйте команду:
# firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="8.8.8.8" accept'
Проверьте зону, и убедитесь что IP добавлен в исключения в правиле rich rules:
# firewall-cmd --zone=public --list-all
public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client http https ssh test ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv4" source address="8.8.8.8" accept
Чтобы заблокировать IP, нужно заменить accept на reject:
# firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="8.8.4.4" reject'
# firewall-cmd --zone=public --list-all
public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: dhcpv6-client http https ssh test ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: rule family="ipv4" source address="8.8.8.8" accept rule family="ipv4" source address="8.8.4.4" reject
Можно разрешить определенную службу только для запросов с конкретного IP адреса:
#firewall-cmd --permanent --add-rich-rule 'rule family="ipv4" source address="10.10.1.0/24" service name="https" accept'
Если вам нужно срочно заблокировать вообще все запросы к серверу, используйте команду паники:
# firewall-cmd --panic-on
Отключить режим паники можно либо командой:
# firewall-cmd --panic-off
Либо перезагрузив сервер.
Вы можете заблокировать конфигурацию firewalld, чтобы локальные сервисы с правами root не могли изменить созданные вами правила файервола:
# firewall-cmd --lockdown-on
Отключить режим блокировки:
# firewall-cmd --lockdown-off
Перенаправление портов в firewalld
Вы можете создать правило перенаправления портов (port forwarding) в firewalld. Чтобы перенаправить 443 порт на 9090:
# firewall-cmd --zone=public --add-forward-port=port=443:proto=tcp:toport=9090 --permanent
Чтобы удалить правило перенаправления порта:
# firewall-cmd --zone=public --remove-forward-port=port=443:proto=tcp:toport=9090