Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Создание мультизональных конфигураций межсетевого экрана с помощью Firewalld

Оригинал: Understanding Firewalld in Multi-Zone Configurations
Авторы: Nathan Vance, William F. Polik
Дата публикации: 2 февраля 2017 г.
Перевод: А.Панин
Дата перевода: 1 марта 2017 г.

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

Так как защита системы от любых видов атак на уровне приложений является практически невыполнимой задачей, в большинстве случаев для защиты различных систем применяются межсетевые экраны, позволяющие ограничивать доступ к ним извне. Межсетевые экраны фильтруют входящие сетевые пакеты на основе их исходных и целевых IP-адресов и номеров портов, а также протоколов. Таким образом, система может работать лишь с несколькими комбинациями IP-адресов/номеров портов/протоколов и игнорировать все остальные.

В Linux межсетевые экраны основываются на netfilter, специализированном фреймворке уровня ядра. В течение более чем десяти лет утилита iptables выступала в качестве уровня абстракции для netfilter из пространства пользователя. iptables позволяет обрабатывать сетевые пакеты с помощью наборов правил, причем при совпадении комбинации IP-адрес/номер порта/протокол правила с аналогичной комбинацией свойств сетевого пакета осуществляется применение правила, приводящее в конечном итоге к приему, отклонению или отбрасыванию пакета.

Firewalld является более новым уровнем абстракции для netfilter из пространства пользователя. К сожалению, вся его мощь и гибкость не была оценена по достоинству ввиду отсутствия документации с описанием мультизональных конфигураций. Данная статья призвана исправить данную ситуацию с помощью примеров.

Цели проектирования Firewalld

Разработчики Firewalld понимали, что большинство вариантов использования утилиты iptables подразумевало задействование нескольких уникальных исходных IP-адресов с соответствующими списками разрешенных к использованию сетевых служб и запретом использования всех остальных служб. Для реализации подобного подхода firewalld разделяет входящий трафик на зоны, описываемые с помощью исходного IP-адреса или имени сетевого интерфейса. Каждая зона имеет свои данные конфигурации, позволяющие осуществлять прием или отклонение сетевых пакетов на основе заданных критериев.

Другим усовершенствованием концепции, представленной в iptables, является упрощение процесса конфигурации. Firewalld упрощает процесс описания сетевых служб благодаря возможности использования имени сетевой службы вместо указания ее номера порта и протокола - например, вы можете использовать имя сетевой службы samba вместо указания номеров UDP-портов 137 и 138 и TCP-портов 139 и 445. Кроме того, синтаксис правил дополнительно упрощается благодаря устранению зависимости от порядка следования правил, присутствующей в iptables.

Наконец, firewalld позволяет осуществлять изменение состояния фреймворка netfilter в динамическом режиме, то есть, изменять настройки межсетевого экрана вне зависимости от правил, хранящихся на постоянной основе в файле конфигурации формата XML. Таким образом, с помощью следующей команды может осуществляться временная модификация правил межсетевого экрана, которая утратит свою силу после перезагрузки системы.

# firewall-cmd <модификация правила>

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

# firewall-cmd --permanent <модификация правила>
# firewall-cmd --reload

Зоны

Верхним уровнем организации правил межсетевого экрана в firewalld являются зоны. Пакет является частью зоны в том случае, если он принадлежит к ассоциированному с этой зоной сетевому интерфейсу или имеет ассоциированный с ней исходный IP-адрес/маску сети. По умолчанию пользователю доступно несколько зон:

# firewall-cmd --get-zones
block dmz drop external home internal public trusted work

Активной зоной является любая зона, которой поставлен в соответствие сетевой интерфейс и/или исходный IP-адрес. Для вывода списка активных зон может использоваться следующая команда:

# firewall-cmd --get-active-zones
public
  interfaces: eno1 eno2

Интерфейсами (Interfaces) называются имена, выдаваемые системой аппаратным и виртуальным сетевым адаптерам, что несложно увидеть в примере выше. Все активные интерфейсы связываются с зонами, причем в соответствие интерфейсу может быть поставлена как стандартная зона, так и любая зона, выбранная пользователем. Однако, сетевому интерфейсу не может быть поставлено в соответствие более одной зоны.

При использовании стандартной конфигурации firewalld ставит в соответствие всем сетевым интерфейсам публичную зону (public) и не устанавливает для зон каких-либо исходных IP-адресов. В результате публичная зона является единственной активной зоной.

Источниками (Sources) называются диапазоны исходных IP-адресов, которые также могут связываться с зонами. Источник (или перекрывающиеся источники) не могут ставиться в соответствие множеству зон. Выполнение подобной операции приведет к неопределенному поведению межсетевого экрана, ведь firewalld не сможет определить, какие правила должны применяться по отношению к заданному источнику.

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

# firewall-cmd --zone=public --list-all
public (default, active)
  interfaces: eno1 eno2
  sources:
  services: dhcpv6-client ssh
  ports:
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:
# firewall-cmd --permanent --zone=public --get-target
default

Рассмотрим приведенный вывод построчно:

  • public (default, active) указывает на то, что публичная зона является стандартной зоной (используемой для появляющихся сетевых интерфейсов), а также активна, ведь она связана как минимум с одним сетевым интерфейсом или источником.
  • interfaces: eno1 eno2 содержит список сетевых интерфейсов, связанных с данной зоной.
  • sources: содержит список источников данной зоны. На данный момент они не заданы, а в случае их наличия после двоеточия должны были бы находиться IP-адреса в формате xxx.xxx.xxx.xxx/xx.
  • services: dhcpv6-client ssh содержит список служб, которые могут осуществлять обмен данными через межсетевой экран. Вы можете получить исчерпывающий список известных firewalld имен сетевых служб, воспользовавшись командой firewall-cmd --get-services.
  • ports: содержит список целевых портов, с которыми могут работать сетевые службы через межсетевой экран. Эта директива может оказаться полезной в том случае, если вам нужно разрешить использование сетевой службы, которая не известна firewalld.
  • masquerade: no указывает на то, что IP-маскарадинг отключен в рамках данной зоны. При активации упомянутого механизма станет возможным использование IP-форвардинга (проброса портов) с превращением вашего компьютера в маршрутизатор.
  • forward-ports: содержит список пробрасываемых портов.
  • icmp-blocks: содержит список адресов для блокировки ICMP-трафика.
  • rich rules: содержит правила для сложных конфигураций, обрабатываемые в первую очередь при загрузке параметров зоны.
  • default является целью зоны, которая описывает действие, выполняемое по отношению к соответствующему зоне сетевому пакету, не подпадающему под действие какого-либо из приведенных выше параметров.

Пример простой монозональной конфигурации

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

# firewall-cmd --permanent --zone=public --remove-service=dhcpv6-client
# firewall-cmd --permanent --zone=public --remove-service=ssh
# firewall-cmd --reload

В результате исполнения данных команд будет сформирована следующая конфигурация межсетевого экрана:

# firewall-cmd --zone=public --list-all
public (default, active)
  interfaces: eno1 eno2
  sources:
  services:
  ports:
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:
# firewall-cmd --permanent --zone=public --get-target
default

Руководствуясь соображениями максимальной защиты системы, при возникновении необходимости в открытии временного доступа к той или иной службе на уровне межсетевого экрана (возможно, к службе защищенной командной оболочки ssh), вы можете активировать сетевую службу лишь в рамках текущей сессии (убрать параметр --permanent), а также сообщить firewalld о том, что стоит отменить внесенное изменение правил по прошествии заданного промежутка времени:

# firewall-cmd --zone=public --add-service=ssh --timeout=5m

Параметр --timeout позволяет использовать значения промежутков времени в секундах (s), минутах (m) или часах (h).

Цели

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

  • ACCEPT: сетевой пакет должен быть принят.
  • %%REJECT%%: сетевой пакет должен быть отклонен с передачей информация об этом событии отправителю.
  • DROP: сетевой пакет должен быть отброшен без передачи какой-либо информации отправителю.
  • default: не должно выполняться никаких действий. Зона должна не участвовать в обработке пакета, а просто пересылать его "наверх".

В версии firewalld 0.3.9 была допущена досадная ошибка (которая была исправлена в версии 0.3.10), заключающаяся в том, что в зонах с заданными источниками и целями, отличными от default, цели применялись вне зависимости от разрешенных сетевых служб. Например, зона с заданным источником и целью DROP отбрасывала все сетевые пакеты даже в том случае, если эти сетевые пакеты генерировались разрешенными сетевыми службами. К сожалению, данная версия firewalld была включена в состав дистрибутива RHEL 7 и производных дистрибутивов, что делает описанную ошибку достаточно часто встречающейся. Примеры, приведенные в данной статье, составлялись таким образом, чтобы избежать описанного поведения.

Приоритеты

Активные зоны могут выступать в двух различных ролях. Зоны с ассоциированными сетевыми интерфейсам выступают в роли интерфейсных зон, а зоны с ассоциированными исходными IP-адресами - адресных зон (при этом каждая из зон может выступать сразу в двух описанных ролях). Firewalld осуществляет обработку сетевых пакетов в описанной ниже последовательности:

  1. Сначала применяется правило соответствующей адресной зоны. При этом такая зона может либо существовать в единичном экземпляре, либо не существовать вообще. Если адресная зона обрабатывает сетевой пакет из-за того, что он удовлетворяет ее расширенному правилу, сетевая служба является разрешенной или ее цель отличается от default, то процесс обработки рассматриваемого сетевого пакета может считаться оконченным. В противном случае сетевой пакет подвергается дополнительной обработке.
  2. Далее приходит очередь соответствующей интерфейсной зоны. Ровно одна такая зона должна существовать в любом случае. Если пакет обрабатывается на уровне этой зоны, процесс его обработки может считаться оконченным. В противном случае пакет подвергается дополнительной обработке.
  3. Теперь используется стандартное правило Firewalld. Оно заключается в том, что принимаются все сетевые пакеты, связанные с протоколом icmp, а все остальные сетевые пакеты просто отбрасываются.

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

Простой пример мультизональной конфигурации

Для демонстрации приоритета в использовании зон предлагаю заменить службу ssh на службу http в публичной зоне (public) и установить наш любимый IP-адрес 1.1.1.1 в соответствие внутренней зоне (internal). Для этой цели могут использоваться следующие команды:

# firewall-cmd --permanent --zone=public --remove-service=ssh
# firewall-cmd --permanent --zone=public --add-service=http
# firewall-cmd --permanent --zone=internal --add-source=1.1.1.1
# firewall-cmd --reload

после исполнения которых будет сгененрирована следующая конфигурация межсетевого экрана:

# firewall-cmd --zone=public --list-all
public (default, active)
  interfaces: eno1 eno2
  sources:
  services: dhcpv6-client http
  ports:
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:
# firewall-cmd --permanent --zone=public --get-target
default
# firewall-cmd --zone=internal --list-all
internal (active)
  interfaces:
  sources: 1.1.1.1
  services: dhcpv6-client mdns samba-client ssh
  ports:
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:
# firewall-cmd --permanent --zone=internal --get-target
default

В случае использования данной конфигурации попытки кого-либо с IP-адресом 1.1.1.1 воспользоваться сетевой службой ssh будут завершаться успешно, так как адресная зона (внутренняя) применяется в первую очередь и позволяет осуществлять доступ к службе ssh.

Если же получить доступ к сетевой службе ssh попытается кто-либо с другим IP-адресом, к примеру, 2.2.2.2, адресная зона не будет использоваться, так как для этого IP-адреса попросту не существует такой зоны. Исходя из этого, запрос будет передан напрямую интерфейсной зоне (публичной), которая не обрабатывает обращения именно к службе ssh. Так как целью публичной зоны является default, по отношению к запросу применяется стандартное правило firewalld, в результате чего он отклоняется.

Но что, если клиент с IP-адресом 1.1.1.1 попытается получить доступ к службе http? Адресная зона (внутренняя) не позволит этого сделать, но при этом она имеет цель default, следовательно, запрос будет передан интерфейсной зоне (публичной), на уровне которой и будет предоставлен доступ в веб-серверу.

Теперь давайте предположим, что кто-либо с IP-адресом 3.3.3.3 пытается вывести из строя ваш веб-сайт. Для ограничения доступа к веб-серверу клиента с данным IP-адресом достаточно просто использовать это адрес в качестве исходного IP-адреса специальной зоны drop, названной так из-за того, что она предназначена для сброса всех соединений:

# firewall-cmd --permanent --zone=drop --add-source=3.3.3.3
# firewall-cmd --reload

При следующей попытке клиента с IP-адресом 3.3.3.3 осуществить доступ к веб-сайту firewalld в первую очередь отправит запрос в адресную зону (drop). Так как целью данной зоны является DROP, запрос будет отклонен и не достигнет интерфейсной зоны (публичной), в которой он мог бы быть принят.

Практический пример мультизональной конфигурации

Предположим, что вы настраиваете межсетевой экран на сервере вашей организации. Вам нужно, чтобы доступ к службам http и https был предоставлен любым пользователям, к службе ssh - клиентам из вашей организации (1.1.0.0/16) и рабочей группы (1.1.1.0/8), а к службе samba - только клиентам из вашей рабочей группы. Благодаря концепции зон firewalld вы можете реализовать данную конфигурацию без каких-либо проблем, пользуясь лишь своей интуицией.

Логичным решением с точки зрения именования зон является задействование публичной зоны для обработки соединений извне, а внутренней зоны - для обработки локальных соединений. Начнем с замены сетевых служб dhcpv6-client и ssh в публичной зоне на службы http и https:

# firewall-cmd --permanent --zone=public --remove-service=dhcpv6-client
# firewall-cmd --permanent --zone=public --remove-service=ssh
# firewall-cmd --permanent --zone=public --add-service=http
# firewall-cmd --permanent --zone=public --add-service=https

После этого уберем сетевые службы mdns, samba-client и dhcpv6-client из внутренней зоны (оставив в ней лишь службу ssh) и установим диапазон IP-адресов вашей организации в качестве источника соединений для данной зоны:

# firewall-cmd --permanent --zone=internal --remove-service=mdns
# firewall-cmd --permanent --zone=internal --remove-service=samba-client
# firewall-cmd --permanent --zone=internal --remove-service=dhcpv6-client
# firewall-cmd --permanent --zone=internal --add-source=1.1.0.0/16

Для организации работы компьютеров из вашей рабочей группы с сервером samba придется добавить расширенное правило:

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

# firewall-cmd --reload

Осталось обратить внимание на две небольшие детали. Если вы попытаетесь соединиться с сервером с помощью клиента ssh, запущенного на компьютере за пределами внутренней зоны, вы получите сообщение об отклонении соединения, которое отправляется firewalld в подобных ситуациях по умолчанию. Более безопасным вариантом является эмуляция неактивного IP-адреса со сбросом соединения. Для реализации описанного поведения достаточно изменить цель публичной зоны с default на DROP:

# firewall-cmd --permanent --zone=public --set-target=DROP
# firewall-cmd --reload

Но подождите, ведь в этом случае вы больше не сможете использовать утилиту ping даже во внутренней зоне! Кроме того, в списке разрешенных служб firewalld нет упоминания о протоколе icmp (который используется утилитой ping). Это объясняется тем, что протокол icmp является протоколом 3 уровня сетевой модели OSI и не поддерживает концепции порта в отличие от протоколов, привязанных к определенным портам. Перед установкой цели DROP для публичной зоны ping-пакеты проходят через межсетевой экран, так как цели default обеих зон позволяют задействовать стандартное правило firewalld, которое позволяет пропустить их. Теперь же они отбрасываются.

Для восстановления работоспособности утилиты ping в рамках внутренней сети может использоваться расширенное правило:

В общем, это конфигурация двух активных зон:

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

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

Отладка

Firewalld реализует интуитивно понятные парадигмы настройки межсетевого экрана, которые обуславливают повышенную неоднозначность правил по сравнению с ранее использовавшейся для аналогичных целей утилитой iptables. Для упрощения разбора возникающих вариантов неопределенного поведения или для лучшего понимания принципа работы firewalld следует рассмотреть настройки фреймворка netfilter, которые генерируются в процессе работы с утилитой iptables. Настройки данного фреймворка для предыдущего примера с убранными для простоты цепочками forward, output и logging приведены ниже:

В приведенном выше выводе утилиты iptables новые цепочки (в строках, начинающихся с -N) объявляются в первую очередь. Остальные правила добавляются (в строках, начинающихся с -A) в iptables. Установленные соединения и локальный трафик принимаются, при этом входящие пакеты отправляются в цепочку INPUT_ZONES_SOURCE с последующей оправкой в зоны, связанные с их IP-адресами, если эти зоны существуют. После этого трафик передается в цепочку INPUT_ZONES, перенаправляясь в интерфейсную зону. Если он не обрабатывается в данной зоне, пакеты icmp принимаются, некорректные пакеты отбрасываются, а все остальные пакеты - отклоняются.

Заключение

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