Настройка брандмауэра на CentOS 7 с использованием FirewallD

Введение

FirewallD — динамически управляемый брандмауэр с поддержкой зон, который определяет уровень доверия сетевых подключений или интерфейсов. Доступен для многих дистрибутивов Linux и выступает в качестве фронтенда для системы фильтрации сетевых пакетов Iptables ядра Linux. В данной статье мы рассмотрим, как установить брандмауэр на сервер и продемонстрируем основы управления брандмауэром с помощью утилиты firewall-cmd.

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

Данная статья является переводом и адаптацией англоязычной статьи.

Базовые понятия в FirewallD

Прежде, чем перейти к использованию firewall-cmd для управления настройками брандмауэра, следует познакомиться с несколькими базовыми понятиями, которые предоставляются утилитой.

Зоны

Демон FirewallD управляет группами правил, используя объекты под названием «зоны». Зоны представляют собой набор правил, которые диктуют, какой трафик должен быть разрешен в зависимости от уровня доверия в сетях, к которым подключен компьютер. Сетевым интерфейсам назначается зона, определяющая поведение, которое должен разрешать брандмауэр.

Для компьютеров, которые могут часто перемещаться между сетями (например, ноутбуки), такой уровень гибкости дает возможность изменять правила в зависимости от среды. Можно применять более строгие правила, запрещающие большую часть трафика при работе в общедоступной сети Wi-Fi, и более мягкие ограничения при подключении к домашней сети. Для сервера эти зоны не так важны, поскольку сетевое окружение редко, если вообще меняется.

Независимо от того, насколько динамичной может быть сетевая среда, полезно иметь представление о каждой из предопределенных зон для FirewallD. Перечислим их в соответствии с уровнем доверия, от самого низкого (ненадежного) до высокого (доверенного):

  • drop: Самый низкий уровень доверия сети. Весь входящий трафик сбрасывается без уведомления, поддерживаются только исходящие соединения.
  • block: Эта зона похожа на предыдущую, но при этом все входящие запросы сбрасываются с сообщением icmp-host-prohibited для IPv4 или icmp6-adm-prohibited для IPv6.
  • public: Эта зона представляет недоверенную публичную сеть, однако поддерживает предопределенные входящие соединения.
  • external: Зона для использования на граничных серверах со связью с внешними сетями. Поддерживается маскировка NAT, благодаря чему внутренняя сеть остается закрытой, но возможны выбранные входящие соединения.
  • internal: Противоположна зоне external, используется во внутренних сетях. Компьютерам в этой зоне можно доверять. Доступны дополнительные сервисы.
  • dmz: Используется для компьютеров, расположенных в демилитаризованной зоне (для изолированных компьютеров с ограниченным доступом к остальной части сети). Поддерживаются только некоторые входящие соединения.
  • work: Зона рабочей сети. Большинству машин в сети можно доверять. Доступны дополнительные сервисы.
  • home: Зона домашней сети. Окружению можно доверять, но поддерживаются только определенные пользователем входящие соединения.
  • trusted: Всем машинам в сети можно доверять. Самая открытая из доступных опций, поэтому требует разумного использования.

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

Сохранение правил

FirewallD использует два набора правил — постоянные и временные. Временные правила представляет собой фактическую рабочую конфигурацию и при перезагрузке не сохраняются. Если правило добавляется или изменяется, поведение запущенного брандмауэра сразу изменяется. Но при перезагрузке все изменения утрачиваются, если они не были сохранены.

По умолчанию при внесении изменений в конфигурацию FirewallD с использованием утилиты firewall-cmd изменения применяются к временному набору правил. Большинство команд firewall-cmd может использовать флаг --permanent, он позволяет cоздать постоянный набор правил, которые будут применяться сразу после выполнения команды перезагрузки.

Установка и подключение брандмауэра для запуска при загрузке

На некоторых дистрибутивах Linux, включая многие образы CentOS 7, FirewallD установлен по умолчанию. Однако, если необходимо установить FirewallD, выполните следующую команду:

sudo yum install -y firewalld

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

sudo systemctl enable firewalld 
sudo reboot

При перезапуске сервера брандмауэр будет запущен и поместит сетевые интерфейсы в сконфигурированные зонаы (или переключится на зону по умолчанию), любые правила, связанные с зоной/зонами, будут применены к соответствующим интерфейсам.

Проверить, что сервис запущен и доступен можно с помощью:

sudo firewall-cmd --state

Ответ:

running

Теперь брандмауэр запущен и работает согласно конфигурации по умолчанию.

Активные правила брандмауэра

Прежде чем вносить изменения, разберемся с тем, какие правила и какую среду предоставляет служба по-умолчанию.

Правила брандмауэра по умолчанию

Чтобы узнать, какая зона выбрана по умолчанию, используйте:

firewall-cmd --get-default-zone

Ответ:

public

Так как на данный момент FirewallD не получал никаких инструкций относительно других зон, кроме того, к другим зонам не привязан ни один интерфейс, то сейчас зона public является зоной по умолчанию, а также единственной «активной» зоной (той зоной, которая контролирует трафик интерфейсов). Проверим это:

firewall-cmd --get-active-zones

Ответ:

public
  interfaces: eth0 eth1

Мы видим, что наш сервер имеет два сетевых интерфейса: eth0 и eth1. Они оба управляются в соответствии с правилами, заданными для зоны public.

Чтобы узнать правила этой зоны, введите:

sudo firewall-cmd --list-all

Ответ:

public (default, active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources: 
  services: ssh dhcpv6-client
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

Теперь нам известно, что зона public является зоной по умолчанию и к ней привязаны интерфейсы eth0 и eth1. Можно видеть, что в этой зоне предусмотрены обычные операции, связанные с DHCP-клиентом (для назначения IP-адресов) и SSH (для удаленного администрирования).

Другие зоны

Мы получили представление о настройках текущей активной зоны и зоны по умолчанию. Также, можно получить информацию и о других зонах:

Чтобы получить список доступных зон, введите:

firewall-cmd --get-zones

Ответ:

block dmz drop external home internal public trusted work

Включив параметр --zone= в команду --list-all получим конфигурацию конкретной зоны:

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

Ответ:

home
  interfaces: 
  sources: 
  services: dhcpv6-client ipp-client mdns samba-client ssh
  ports: 
  masquerade: no
  forward-ports: 
  icmp-blocks: 
  rich rules:

Чтобы вывести определения всех зон, используйте опцию --list-all-zone. Для более удобного просмотра вывод можно передать в пейджер:

firewall-cmd --list-all-zones | less

Задание зон для сетевых интерфейсов

Изначально все интерфейсы расположены в зоне по умолчанию.

Изменение зоны интерфейса

Можно перевести интерфейс в другую зону с помощью комбинации параметров --zone= и --change-interface=. Как и во всех командах для изменения настроек брандмауэра, используйте sudo.

Например, чтобы переместить интерфейс eth0 в зону home, введите:

sudo firewall-cmd --zone=home --change-interface=eth0

Ответ:

success

При переводе интерфейса в новую зону учитывайте, что изменения могут коснуться работающих сервисов. Например, в зоне home доступен SSH. В некоторых зонах SSH по умолчанию не включен, и после переноса интерфейса в данную зону вы не сможете войти в систему.

Чтобы проверить, что интерфейс переведен успешно, используйте команду для получения активных зон:

firewall-cmd --get-active-zones

Ответ:

home
  interfaces: eth0
public
  interfaces: eth1

Изменение зоны по умолчанию

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

Для этого используется параметр --set-default-zone=. Тогда все интерфейсы зоны по умолчанию будут привязаны к новой зоне:

sudo firewall-cmd --set-default-zone=home

Ответ:

success

Создание правил для приложений

Основной способ определения исключений брандмауэра для сервисов, которые вы хотите сделать доступными, прост. Здесь мы разберем основную идею.

Добавление сервиса к зоне

Самый простой способ — добавить необходимые сервисы и порты в используемые зоны. Получим список доступных сервисов с помощью флага --get-services:

firewall-cmd --get-services

Ответ:

RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry dropbox-lansync elasticsearch freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master high-availability http https imap imaps ipp ipp-client ipsec iscsi-target kadmin kerberos kibana klogin kpasswd kshell ldap ldaps libvirt libvirt-tls managesieve mdns mosh mountd ms-wbt mssql mysql nfs nrpe ntp openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius rpc-bind rsh rsyncd samba samba-client sane sip sips smtp smtp-submission smtps snmp snmptrap spideroak-lansync squid ssh synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local xmpp-server

Можно получить больше информации о каждом сервисе, заглянув в связанный с ним файл .xml в каталоге /usr/lib/firewalld/services. Например, служба SSH определяется в нем следующим образом:

<?xml version="1.0" encoding="utf-8"?> 
<service>   
    <short>SSH</short>   
    <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>   
    <port protocol="tcp" port="22"/> 
</service>
  
 

Используйте параметр —add-service=, чтобы подключить сервис. Указать целевую зону можно с помощью опции —zone=. По умолчанию эти изменения будут работать в течение одной сессии. Чтобы сохранить изменения и использовать их на постоянной основе, добавьте флаг —permanent.

Например, если мы используем веб-сервер, обслуживающий HTTP-трафик, мы можем разрешить этот трафик для интерфейсов в зоне public для этой сессии, используя:

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

Можно не указывать --zone=, если нужно изменить зону по умолчанию. Чтобы проверить, что операция завершилась успешно, используйте --list-all или --list-services:

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

Ответ:

dhcpv6-client http ssh

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

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

Ответ:

success

Убедитесь, что изменения применились, добавив флаг --permanent к команде --list-services. Используйте sudo:

sudo firewall-cmd --zone=public --permanent --list-services

Output:

dhcpv6-client http ssh

Теперь зона public будет разрешать HTTP-трафик. Если веб-сервер настроен на использование SSL/TLS, можно также добавить службу https. Можем добавить ее к текущей сессии и постоянному набору правил, используя:

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

Если нужный сервис не доступен

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

Открытие порта для зоны. Самый простой способ добавить поддержку для конкретного приложения — открыть порты, которые оно использует в соответствующей зоне/зонах. Для этого достаточно указать порт или диапазон портов и соответствующий протокол для них.

Например, если наше приложение использует порт 5000 и протокол TCP, можно добавить их в зону public для этой сессии, используя параметр --add-port=. Протоколы могут быть tcp или udp:

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

Ответ:

success

С помощью --list-ports проверим, что операция прошла успешно:

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

Ответ:

5000/tcp

Также можно указать диапазон портов, разделив начальный и конечный порт в диапазоне с помощью тире. Например, если наше приложение использует UDP-порты с 4990 по 4999, мы можем открыть их в зоне public, набрав:

sudo firewall-cmd --zone=public --add-port=4990-4999/udp

После тестирования можно добавить их к постоянным правилам брандмауэра:

sudo firewall-cmd --zone=public --permanent --add-port=5000/tcp
sudo firewall-cmd --zone=public --permanent --add-port=4990-4999/udp
sudo firewall-cmd --zone=public --permanent --list-ports

Ответ:

success
success
5000/tcp 4990-4999/udp

Определение нового сервиса. Открыть порты для зон легко, но может быть трудно отследить, для чего предназначен каждый из них. Если вы когда-либо выводили службу из эксплуатации на своем сервере, то могли столкнуться с проблемой вспомнить, какие из открытых портов еще необходимы. Чтобы избежать этой ситуации, можно определить сервис.

Сервисы представляют собой наборы портов со связанным именем и описанием. Использование сервисов проще в администрировании, чем использование портов, но это требует некоторой предварительной подготовки. Для начала необходимо скопировать существующий скрипт из каталога /usr/lib/firewalld/services в каталог /etc/firewalld/services, который является местоположением для созданных пользователем сервисов, и заменить в нем параметры.

Например, можно скопировать определение сервиса SSH, чтобы использовать его для определения сервиса example следующим образом. Имя файла должно совпадать с именем сервиса и иметь суффикс .xml:

sudo cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/example.xml

Теперь можно настроить определение для сервиса example:

sudo vi /etc/firewalld/services/example.xml

Файл /etc/firewalld/services/example.xml содержит определение SSH:

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>SSH</short>
  <description>Secure Shell (SSH) is a protocol for logging into and executing commands on remote machines. It provides secure encrypted communications. If you plan on accessing your machine remotely via SSH over a firewalled interface, enable this option. You need the openssh-server package installed for this option to be useful.</description>
  <port protocol="tcp" port="22"/>
</service>

Большую часть определения составляют метаданные. Короткое имя сервиса в тегах можно изменить на более читаемое имя. Также нужно добавить описание, чтобы понимать, что это за сервис. Единственная конфигурация, которую нужно задать и которая повлияет на работу сервиса, — это определение порта, где следует указать порты и протоколы, которые необходимо открыть.

Например, в нашем случае нужно открыть порт 7777 для TCP и 8888 для UDP. Внесем изменения в определение:

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Example Service</short>
  <description>This is just an example service.  It probably shouldn't be used on a real system.</description>
  <port protocol="tcp" port="7777"/>
  <port protocol="udp" port="8888"/>
</service>

Сохраним изменения и закроем файл.

Перезагрузим брандмауэр, чтобы получить доступ к новому сервису:

sudo firewall-cmd --reload

Теперь сервис в списке доступных сервисов:

firewall-cmd --get-services

Ответ:

RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry dropbox-lansync elasticsearch example freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master high-availability http https imap imaps ipp ipp-client ipsec iscsi-target kadmin kerberos kibana klogin kpasswd kshell ldap ldaps libvirt libvirt-tls managesieve mdns mosh mountd ms-wbt mssql mysql nfs nrpe ntp openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius rpc-bind rsh rsyncd samba samba-client sane sip sips smtp smtp-submission smtps snmp snmptrap spideroak-lansync squid ssh synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local xmpp-server

Сервис можно использовать в зонах.

Создание пользовательских зон

Часто предопределенных зон вполне достаточно для работы, но иногда возникает необходимость определить пользовательские зоны.

Например, создадим зону publicweb для веб-сервера. Для нее потребуется настроить дополнительную зону для DNS-сервиса, которая предоставляется в частной сети, назовем ее privateDNS.

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

sudo firewall-cmd --permanent --new-zone=publicweb
sudo firewall-cmd --permanent --new-zone=privateDNS

Проверим, что они присутствуют в постоянных правилах:

firewall-cmd --get-zones

Ответ:

block dmz drop external home internal public trusted work

Перезагрузим брандмауэр, чтобы получить доступ к новым зонам:

sudo firewall-cmd --reload
firewall-cmd --get-zones

Ответ:

block dmz drop external home internal privateDNS public publicweb trusted work

Теперь можно присвоить новым зонам нужные сервисы и порты. Рекомендуется внести изменения в активный экземпляр и протестировать, а затем перенести их в постоянные правила. Например, в зону publicweb можно добавить SSH, HTTP и HTTPS.

sudo firewall-cmd --zone=publicweb --add-service=ssh
sudo firewall-cmd --zone=publicweb --add-service=http
sudo firewall-cmd --zone=publicweb --add-service=https
sudo firewall-cmd --zone=publicweb --list-all

Ответ:

publicweb
  target: default
  icmp-block-inversion: no
  interfaces: 
  sources: 
  services: ssh http https
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules:

Аналогично добавим DNS-сервис к зоне privateDNS:

sudo firewall-cmd --zone=privateDNS --add-service=dns
sudo firewall-cmd --zone=privateDNS --list-all

Ответ:

privateDNS
  interfaces: 
  sources: 
  services: dns
  ports: 
  masquerade: no
  forward-ports: 
  icmp-blocks: 
  rich rules:

Затем мы можем перенести интерфейсы в новые зоны, чтобы проверить их:

sudo firewall-cmd --zone=publicweb --change-interface=eth0
sudo firewall-cmd --zone=privateDNS --change-interface=eth1

На этом этапе можно протестировать полученную конфигурацию. Если заданные значения работают, можно добавить правила к постоянным настройкам. Для этого повторно применим правила, добавив флаг --permanent:

sudo firewall-cmd --zone=publicweb --permanent --add-service=ssh
sudo firewall-cmd --zone=publicweb --permanent --add-service=http
sudo firewall-cmd --zone=publicweb --permanent --add-service=https
sudo firewall-cmd --zone=privateDNS --permanent --add-service=dns

После применения этих правил к постоянным настройкам можно перезапустить сеть и перезагрузить сервис брандмауэра:

sudo systemctl restart network
sudo systemctl reload firewalld

Убедитесь, что зоны были присвоены правильно:

firewall-cmd --get-active-zones

Ответ:

privateDNS
  interfaces: eth1
publicweb
  interfaces: eth0

И проверьте, что в обеих зонах работают нужные сервисы:

sudo firewall-cmd --zone=publicweb --list-services

Ответ:

http https ssh
sudo firewall-cmd --zone=privateDNS --list-services

Ответ:

dns

Пользовательские зоны созданы! Если вы хотите сделать одну из этих зон зоной по умолчанию для других интерфейсов, используйте параметр --set-default-zone=:

sudo firewall-cmd --set-default-zone=publicweb

Заключение

Мы рассмотрели возможности управления службой FirewallD в системе CentOS, необходимые для повседневного использования.

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