Создание отказоустойчивого брандмауэра на OpenBSD с использованием CARP и pfsync

Опубликовано – 30.11.2009

Оригинал: Redundant firewalls with OpenBSD, CARP and pfsync
Перевод: Сгибнев Михаил

 1. Введение

 Брандмауэр является одними из самых критичных компонентов сети, так как при выходе его из строя, мы потеряем доступ к внешнему миру. Помимо того, что станут недоступны наши внешние сервисы (http, mail и т.д.), так мы еще и потеряем возможность бродить по разным Интернетам!

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

 С другой стороны, мы увеличиваем затраты на оборудование и не можем решить такие проблемы как прозрачная передача некоторых протоколов (SSH или IRC) между членами кластера или данными синхронизации (в нашем примере мы будем пользоваться двумя разными протоколами для отказоустойчивости и синхронизации).

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

  • OpenBSD — ну, в принципе понятно, что это безопастно, надежно и практично
  • Packet Filter (PF) — система пакетной фильтрации и NAT
  • CARP (Common Address Redundancy Protocol) — протокол, обеспечивающий отказоустойчивость путем соединения нескольких машин виртуальным интерфейсом и отображающий их для стороннего наблюдателя как одна машина
  • pfsync — протокол синхронизации таблиц состояний PF между несколькими брандмауэрами

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

 2. Схема сети

 Сперва посмотрим на окружающую нас действительность. В данном случае мы будем работать с очень простой и «классической» моделью:

  • DMZ (172.16.240.0/24), содержащей внешние сервисы и сенсор системы обнаружения вторжений
  • LAN (172.16.0.0/24), содержащей рабочие станции пользователей и серверы, не доступные извне
  • Маршрутизатор, расположенной в маленькой сеточке (172.16.250.0/24), соединяющий нас с Интернет

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

  • В случае компрометации брандмауэра, LAN будет защищена дополнительным уровнем фильтрации (хотя было бы предпочтительно использовать различные платформы для брандмауэра, чтобы препятствовать тому, что нападавшие поставили под угрозу внутренние брандмауэры используя ту же уязвимость [MISC17])
  • Один, хоть и кластеризованный брандмауэр для LAN и DMZ является одной точкой отказа
  • На каждом брандмауэре правила применяются только к ЛВС или DMZ, таким образом делая набор правил PF более понятным и более легким в поддержке

 3. Базовая конфигурация

 Давайте бросим беглый взгляд на основную конфигурацию системы, которая относится ко всем нашим брандмауэрам.

 Мы не будем рассматривать вопрос установки системы, который очень подробно изложен на сайте OpenBSD. Единственное (очевидное) замечание заключается в том, что вы должны установить только голый минимум, чтобы препятствовать тому, что безопасность и надежность брандмауэра ставились под угрозу ненужным программным обеспечением. Поэтому, во время установки вы только должны выбрать только те наборы, которые отмеченны как «Required» в документации: bsd, baseXX.tgz, etcXX.tgz.




 Нет никакой необходимости в установке компилятора (compXX.tgz) или пользовательских утилит, которые могут сильно помочь злоумышленникам (смотрите PUIS).

 После первой перезагрузки мы можем начать настраивать некоторые файлы конфигурации; по умолчанию, OpenBSD идет с некоторыми сервисами, включенными в inetd(8):

$ grep -v ^# /etc/inetd.conf
ident stream tcp nowait _identd /usr/libexec/identd identd -el
ident stream tcp6 nowait _identd /usr/libexec/identd identd -el
127.0.0.1:comsat dgram udp wait root /usr/libexec/comsat comsat
[::1]:comsat dgram udp6 wait root /usr/libexec/comsat comsat
daytime stream tcp nowait root internal
daytime stream tcp6 nowait root internal
time stream tcp nowait root internal
time stream tcp6 nowait root internal
$

 Систему считают безопасной также с этими включенными сервисами (см. ABSO); так или иначе, выведение из строя их всех не нанесет нам никакого вреда.

 Хорошей практикой будет редактирование файла /etc/motd, в котором можно указать некоторую информацию о системе и предупредить пользователей, что все попытки доступа регистрируется и что любой несанкционированный доступ будет преследоваться по суду (см. [PUIS]).

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

  • /etc/hostname.if(5) — содержит информацию о сетевых интерфейсах
  • /etc/mygate(5) — содержит адрес шлюза по умолчанию
  • /etc/myname(5) — содержит имя (FQDN) машины
  • /etc/resolv.conf(5) — содержит информацию о DNS, доменах и т.д.

 Учитывая большое количество атак, основанных на уязвимостях в системе DNS, предпочтительно не использовать эту систему, а внести
адреса наиболее критических систем в файл /etc/hosts(5).
Чтобы убедиться, что файл /etc/hosts(5) имеет больший приоритет, по
сравнению с DNS, посмотрите файл /etc/resolv.conf(5):

lookup file bind

 Пакетная фильтрация по умолчанию выключена, поэтому нам необходимо отредактировать (или создать) файл /etc/rc.conf.local(8, в котром установить переменной pf значение, отличное от NO. Так же вы можете изменить наименование файла конфигурации (по умолчанию /etc/pf.conf):

pf=""
pf_rules=/new/path/to/pf.conf

 Так же вы можете установить флаг pflogd(8) в переменной pflogd_flags. И не забудьте включить IP форвардинг!

# sysctl net.inet.ip.forwarding=1
net.inet.ip.forwarding: 0 -> 1
#

 Чтобы изменеия действовали после загрузки, раскомментируйте строку в /etc/sysctl.conf(5):

net.inet.ip.forwarding=1

 4. Протокол CARP

 CARP (Common Address Redundancy Protocol) обеспечивает резервирование системы, состоящей из нескольких хостов, находящихся в одном сетевом сегменте (redundancy group) и имеющей общий IP адрес, при этом, в случае отказа одного из хостов, доступность общего адреса обеспечивают другие члены группы. CARP также позволяет разделить нагрузку между хостами.

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

 Первоначально, группа разработчиков OpenBSD хотела сделать открытую реализацию протоколов стандарта IETF, VRRP (Virtual Router Redundancy Protocol), определенный в RFC3768, и HSRP (Hot Standby Router Protocol), определенный в RFC2281. Но Cisco, опираясь на патентное право, «категорически заявила сообществу OpenBSD, что будет защищать свои патенты на VRRP» (см. CARP для получения дополнительной информации), вынуждая, таким образом, разработчиков OpenBSD создать новый протокол, существенно отличающийся от VRRP.

 CARP принадлежит семейству multicast протоколов, объединяя несколько физических компьютеров одним или несколькими виртупльными адресами. Одна из этих машин является хозяином группы (master) и отвечает на все пакеты, адресованные группе. Остальные машины (backups) находятся в режиме ожидания, готовые в любой момент занять место павшего товарища.

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

 Как вы могли заметить, CARP только создает и управляет виртуальными интерфейсами. Для синхронизации же данных между хостами системный администратор должен использовать pfsync(4), rsync или какой другой протокол.

4.1 Параметры конфигурации

 Конфигурирование CARP происходит с помощью команд sysctl(8) и ifconfig(8). Для sysctl(8) есть три доступных переменных:

  • net.inet.carp.allow — определяет, будет ли хост обрабатывать пакеты CARP. По умолчанию — обрабатывать будет.
  • net.inet.carp.log — регистрация ошибок CARP. Может иметь значения от 0 до 7, соответствуюя стандартынм уровням syslog(3). По умолчанию имеет значение 2
  • net.inet.carp.preempt — если установлено в 0 (по умолчанию), то получив объявление от master, хост не будет учавствовать в выборах нового master. В противном случае, если период рассылки объявлений у хоста меньше, чем у текущего master, хост становится новым master. Эта опция таже позволяет объявить об отказе всех сетевых интерфейсов, при отказе одного из них. Фактически, если отказывает один из CARP-enabled интерфейсов, то CARP изменит значение advskew на 240 на остальных CARP-enabled интерфейсах, инициируя таким образом выборы нового master во всех подсетях, к которым был подключен хост.

 Синтаксис команды ifconfig(8), при конфигурации CARP, выглядит следующим образом:

ifconfig carpN create

ifconfig carpN [advbase n] [advskew n] [balancing mode] \
[carpnodes vhid:advskew,vhid:advskew,...] [carpdev iface] \
[[-]carppeer peer_address] [pass passphrase] [state state] [vhid host-id]

  • carpN — имя виртуального carp(4) интерфейса
  • advbase, advskew — эти параметры задают временной интервал между посылками объявлений. Этот интервал (в секундах) вычисляется по формуле (advbase + (advskew / 255)). Увеличение advbase уменьшит сетевой трафик, но увеличит время выбора нового master-a. Маленькие значения advskew позволяют хосту чаще давать объявления, увеличивая вероятность стать master. advbase должен иметь значения от 1 до 255, advskew между 0 (значение по умолчанию) до 254.
  • balancing — устанавливает режим балансировки. Доступными режимами являются arp, ip, ip-stealth и ip-unicast.
  • carpnodes— Разделенный запятыми список пар vhid:advskew, определяющий как будет распределяться загрузка между хостами
  • carpdev — определяет физический интерфейс, который принадлежит данной группе. По умолчанию, CARP использует физический интерфейс, который принадлежит той же самой подсети, что и виртуальный интерфейс.
  • carppeer — позволяет указать IP адрес пиров, вместо использования multicast.
  • pass — пароль, используемый для общения хостов внутри группы.
  • state — перевод интерфейса в указанное состояние (init, backup или master)
  • vhid — Virtual Host ID. Это уникальный номер от 1 до 255, идентифицирующий отказоустойчивую группу

4.1.1 Счетчик понижения

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

 Все интерфейсы CARP разделены на группы (по умолчанию, интерфейсы carp(4) принадлежат группе «carp») и каждой группе назначен demotion counter, значение которого можно посмотреть командой:

$ ifconfig -g carp
carp: carp demote count 0

 Данный счетчик необходим с следующих случаях:

  • Вы хотите воспрепятствовать выборам хоста в качестве мастера, например, на время его загрузки. Скрипт rc(8) может увеличить demotion counter на 128 до поднятия сетевых интерфейсов и снизить его после настройки сетевых интерфейсов и запуска необходимых сервисов (demotion counter не может быть установлен в абсолютную величину, только увеличен или уменьшен на определенное значение).

    ifconfig -g carp carpdemote 128
    [ ... ]
    ifconfig -g carp -carpdemote 128
  • Вы хотите ограничить число отказоустойчивых интерфейсов carp(4) (а не всех, что происходит, когда установлен preempt). В следующем примере мы сделаем отказоустойчивыми интерфейсы carp1 и carp2, оставив остальные интерфейсы без изменеий:

    # ifconfig carp1 group morituri
    # ifconfig carp2 group morituri
    # ifconfig morituri
    carp1: flags=8843 mtu 1500
    carp: MASTER carpdev sis0 vhid 1 advbase 1 advskew 100
    groups: carp morituri
    inet 1.2.3.4 netmask 0xffffff00 broadcast 1.2.3.255
    carp2: flags=8843 mtu 1500
    carp: MASTER carpdev sis1 vhid 2 advbase 1 advskew 100
    groups: carp morituri
    inet 2.3.4.5 netmask 0xffffff00 broadcast 2.3.4.255
    # ifconfig -g morituri
    morituri: carp demote count 0
    # ifconfig -g morituri carpdemote 50
    # ifconfig -g morituri
    morituri: carp demote count 50

 Для получения дополнительной информации обратитесь к PFFAQ.

 4.1.2 Балансировка нагрузки

 CARP предоставляет два различных способа балансировки нагрузки входящего трафика: ARP balancing и IP balancing.

 Оба метода требуют предварительного создания группы балансировки на каждом хосте, с несколькими carp(4) интерфейсами, имеющих один IP адрес, но различные VHID. Все ноды carp(4) в группе формируются одинаково, за исключением различного advskew, чтобы сделать каждый хост мастером на разных VHID (пример см. ниже).

 ARP balancing работает путем наложения hash-функции на MAC адрес источника для определения VHID, который должен ответить на запрос. На запрос ARP ответит только тот хост, который является master-ом для данного VHID. ARP load balancing может быть включена через ifconfig(8), установив значение «arp» функции балансировки:

# ifconfig carp0 balancing arp carpnodes 1:0,2:100

 IP load balancing работает очень похоже на ARP balancing, но использует hash-функцию адресов источника и назначения для определения, какой VHID (и какой хост, соответственно) ответит на запрос.

 Требованием IP balancing является необходимость получения пакета всеми хостами группы. Включается данный тип балансировки с помощью команды ifconfig(8), установкой опции «ip». Таким образом, мы заставляем CARP использовать multicast MAC адрес для отправки трафика на все хосты группы:

# ifconfig carp0 balancing ip carpnodes 1:0,2:100

 В качестве альтернативы, вы можете установить значение функции балансировки в «ip-stealth», чтобы запретить master-у посылать пакеты со своим действительным адресом MAC в качестве источника. Таким образом мы предотвратим обучение коммутатора и продолжим рассылать широковещательные пакеты. Наконец, если у вас слишком умный коммутатор, то можете установить значение опции балансировки в «ip-unicast».

 Выбор между двумя механизмами балансировки нагрузки главным образом зависит от сетевого окружения, в которое будут помещены системы: ARP balancing работает только для клиентов локальной сети и не может балансировать трафик, выходящий за маршрутизатор, поскольку маршрутизируемый трафик всегда содержит MAC address маршрутизатора в качестве источника. Поэтому, если клиенты находятся в разных сетях, остается только IP balancing, единственный недостаток этого метода заключается в том, что трафик должен попасть на все хосты CARP, что увеличивает нагрузку на сеть.

 4.2 Входные данные

 Пришло время настраивать CARP на наших брандмауэрах. В данной статье мы используем две сильно различающиеся конфигурации CARP, где внутренний брандмауэр (Mickey и Minnie, между LAN и DMZ) работает в режиме active/stand-by (трафик идет только через один хост, а второй находится в горячем резерве), а внешний брандмауэр (Donald и Daisy, отделяет DMZ от internet) работает в режиме балансировки нагрузки.

Mickey

  • LAN 172.16.0.200
  • DMZ 172.16.240.200
  • pfsync 192.168.2.200

Minnie

  • LAN 172.16.0.201
  • DMZ 172.16.240.201
  • pfsync 192.168.2.201

Virtual address

  • LAN 172.16.0.202
  • DMZ 172.16.240.202

Donald

  • LAN 172.16.240.100
  • DMZ 172.16.250.100
  • pfsync 192.168.1.100

Daisy

  • LAN 172.16.240.101
  • DMZ 172.16.250.101
  • pfsync 192.168.1.101

Virtual address

  • LAN 172.16.240.102
  • DMZ 172.16.250.102

 4.2.1 Active/standby конфигурация

 Начнем с Mickey и Minnie: сперва, с помощью ifconfig(8) создадим устройства carp*

mickey# ifconfig carp0 172.16.0.202/24 vhid 1 pass password1 advbase 1 advskew 0
mickey# ifconfig carp1 172.16.240.202/24 vhid 2 pass password2 advbase 1 advskew 0

minnie# ifconfig carp0 172.16.0.202/24 vhid 1 pass password1 advbase 1 advskew 100
minnie# ifconfig carp1 172.16.240.202/24 vhid 2 pass password2 advbase 1 advskew 100

 Мы только что создали интерфейсы, назначили им IP адрес, присвоили VHID (1 для LAN, 2 для DMZ) и пароль (не самый безопасный). Так же мы решили, что Mickey будет master (присвоив Minnie более высокое значение advskew, таким образом делая интервал между объявлениями (1 + 100 / 255) выше чем интервал между объявлениями Mickey’s (1 + 0 / 255)).

 Кроме того, установив переменную net.inet.carp.preempt в «1» на Mickey, мы заставим его всегда пытаться стать master.

mickey# sysctl net.inet.carp.preempt=1
net.inet.carp.preempt: 0 -> 1

 Для того, чтобы наши изменения не пропали после загрузки, необходимо внести в файлы /etc/hostname.carp* и /etc/sysctl.conf следущее:

 Mickey:

/etc/hostname.carp0
inet 172.16.0.202 255.255.255.0 172.16.0.255 vhid 1 pass password1 advbase 1 advskew 0

/etc/hostname.carp1
inet 172.16.240.202 255.255.255.0 172.16.240.255 vhid 2 pass password2 advbase 1 advskew 0

/etc/sysctl.conf
[...]
net.inet.carp.preempt=1

 Minnie:

/etc/hostname.carp0
inet 172.16.0.202 255.255.255.0 172.16.0.255 vhid 1 pass password1 advbase 1 advskew 100

/etc/hostname.carp1
inet 172.16.240.202 255.255.255.0 172.16.240.255 vhid 2 pass password2 advbase 1 advskew 100

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

 4.2.2 Active/active конфигурация

 Настал черед Donald и Daisy, на которых мы сконфигурируем интерфейсы, смотрящие в DMZ. Как и предыдущем примере, создаем устройства carp0 на каждом хосте зададим опцию carpnodes для назначения различных Virtual Host IDs на интерфейсы (vhids 3 и 4).

 На vhid 3 мы установим значения advskew для Donald и Daisy в 0 и 100 соответственно, что позволит выступать хосту Donald в роли мастера. Для vhid 4 значения меняются на обратные, назначая, таким образом, Daisy мастером для vhid 4:

donald# ifconfig carp0 172.16.240.102/24 balancing ip carpnodes 3:0,4:100 \
> pass password3
donald# sysctl net.inet.carp.preempt=1
net.inet.carp.preempt: 0 -> 1

daisy# ifconfig carp0 172.16.240.102/24 balancing ip carpnodes 3:100,4:0 \
> pass password3
daisy# sysctl net.inet.carp.preempt=1
net.inet.carp.preempt: 0 -> 1

 Теперь мы имеем две отказоустойчивые группы с разными мастерами и одним IP адресом.

donald# ifconfig carp0
carp0: flags=8843 mtu 1500
lladdr 01:00:5e:00:01:01
carp: carpdev rl1 advbase 1 balancing ip
state MASTER vhid 3 advskew 0
state BACKUP vhid 4 advskew 100
groups: carp
inet 172.16.240.102 netmask 0xffffff00 broadcast 172.16.240.255
inet6 fe80::2c0:a8ff:fe8e:b112%carp0 prefixlen 64 scopeid 0x5

daisy# ifconfig carp0
carp0: flags=8843 mtu 1500
lladdr 01:00:5e:00:01:01
carp: carpdev rl1 advbase 1 balancing ip
state BACKUP vhid 3 advskew 100
state MASTER vhid 4 advskew 0
groups: carp
inet 172.16.240.102 netmask 0xffffff00 broadcast 172.16.240.255
inet6 fe80::219:d2ff:fe02:6469%carp0 prefixlen 64 scopeid 0x5

 Дабы не потерять сделанное при перезагрузке, редактируем файлы:

Donald:

/etc/hostname.carp0
inet 172.16.240.102 255.255.255.0 172.16.240.255 balancing ip carpnodes 3:0,4:100 pass password3

/etc/sysctl.conf
[...]
net.inet.carp.preempt=1

/etc/hostname.carp1
inet 172.16.250.102 255.255.255.0 172.16.250.255 balancing ip carpnodes 5:0,6:100 pass password5

Daisy:

/etc/hostname.carp0
inet 172.16.240.102 255.255.255.0 172.16.240.255 balancing ip carpnodes 3:100,4:0 pass password3

/etc/sysctl.conf
[...]
net.inet.carp.preempt=1

/etc/hostname.carp1
inet 172.16.250.102 255.255.255.0 172.16.250.255 balancing ip carpnodes 5:100,6:0 pass password5

 Хотя в вышеприведенном примере всего две машины, данная конфигурация может быть легко расширена до 32 хостов. Распределение нагрузки, как бы вам не хотелось, вряд ли достигнет соотношения 50/50 — это связано с тем, что мы используем хэш адресов источника и назначения, а не объем трафика.

 5. Протокол pfsync

 Pfsync — это протокол, используемый пакетным фильтром для управления и обновления таблиц состояния для stateful inspection и NAT. По умолчанию, сообщения о смене состояния рассылаются через синхронизационный интерфейс с помощью IP multicast пакетов. При этом используется IP protocol 240 и multicast-группа 224.0.0.240. Мы реализуем данную схему синхронизации таблиц состояний для получения отказоустойчивого решения, когда переход на новый master происходит без разрыва сессий клиентов.

 pfsync(4) является также названием псевдоустройства, через которое происходит синхронизация таблиц (кроме состояний, созданных правилами, помеченных флагом no-sync или пакетов pfsync(4)) pfsync(4) может быть сконфигурирован на физическом интерфейсе, чтобы синхронизировать таблицы нескольких брандмауэров.

 Физический синхронизационный интерфейс может быть настроен с помощью команды ifconfig(8), используя параметр syncdev. Для примера, на вашем брандмауэре вы можете выполнить команду:

# ifconfig pfsync0 syncdev rl2

 Предполагаем, что интерфейс rl2 на обоих хостах находится в сети 192.168.1.0/24 (для Mickey и Minnie) или 192.168.2.0/24 (для Donald и Daisy) и брандмауэры соединены между собой «кривым(обратным)» патчкордом.

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

 В качестве альтернативы, вы можете использовать ключевое слово syncpeer для указания адреса брандмауэра, с которым осуществляется синхронизация. Система будет использовать этот адрес вместо рассылки широковещательных пакетов и вы можете использовать IPsec для защиты трафика. В случае использования syncdev вы должны иметь поддержку псевдоустройства enc(4) для инкапсуляции/деинкапсуляции трафика ipsec(4).

# ifconfig pfsync0 syncpeer 192.168.1.101 syncdev enc0

 Для того, чтобы изменения не пропали после перезагрузки, внесите данные в файл /etc/hostname.pfsync0:

up syncdev rl2

 6. Правила PF

 Воздействие CARP и pfsync на правила пакетного фильтра минимально. Для начала, нужно разрешить трафик этих протоколов:

pass quick on rl2 proto pfsync keep state (no-sync)
pass on { rl0, rl1 } proto carp keep state (no-sync)

 При написании правил, имейте в виду, что с точки зрения pf(4) трафик движется через физический интерфейс. Поэтому в случае:

pass in on $ext_if [...]

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



 С другой стороны, виртуальный адрес связан с интерфейсом CARP, таким образом вы можете обратиться к нему, если на брандмауэре запущены какие либо сервисы на виртуальном адресе.

# SSH on the virtual interface
pass in on $int_if inet proto tcp from $int_if:network to carp0 port ssh

 Или делать NAT через перенаправление:

# Mail server accessible from the internet
rdr on $ext_if inet proto tcp from any to carp2 port $mail_ports -> $mail_srv

 В любом случае, CARP прозрачен для pf(4), что касается и услуг, предлагаемых брандмауэром на его физических адресах:

# SSH on the physical address
pass in on $int_if inet proto tcp from $int_if:network to $int_if port ssh

 Или для нормальной фильтрации:

# External DNS
pass in on $int_if inet proto { tcp, udp } from $int_if:network to $dns_srv \
port domain
pass out on $ext_if inet proto { tcp, udp } from $ext_if to $dns_srv \
port domain

 В качестве примера, приведем правила фильтрации для наших внешних брандмауэров, Donald и Daisy:

/etc/pf.conf

################################################################################
# Macros and lists #
################################################################################

ext_if = rl0 # External interface
int_if = rl1 # DMZ interface
pfs_if = rl2 # Pfsync interface
carp_if = carp1 # External CARP interface

mail_srv = "mail.kernel-panic.it" # Mail server
web_srv = "{ www1.kernel-panic.it, www2.kernel-panic.it }" # Web servers
dns_srv = "{ dns1.isp.com, dns2.isp.com }" # DNS servers
int_fw = "{ mickey.kernel-panic.it, minnie.kernel-panic.it }" # Internal fw

mail_ports = "{ smtp, imap, imaps }" # Mail server ports
web_ports = "{ www, https }" # Web server ports

# Allowed incoming ICMP types
icmp_types = "{ echoreq, timex, paramprob, unreach code needfrag }"

# Private networks (RFC 1918)
priv_nets = "{ 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 }"

################################################################################
# Options, scrub and NAT #
################################################################################

set block-policy drop
set loginterface $ext_if
set skip on lo

scrub in

# NAT outgoing connections
nat on $ext_if from !$ext_if to any -> $ext_if

# Redirect web services (with load balancing)
rdr on $ext_if inet proto tcp from any to $carp_if port $web_ports -> $web_srv \
round-robin sticky-address

# Redirect mail services
rdr on $ext_if inet proto tcp from any to $carp_if port $mail_ports -> $mail_srv

################################################################################
# Filtering rules #
################################################################################

block all # Default deny
block in quick from urpf-failed # Spoofed address protection

pass quick on $pfs_if proto pfsync keep state (no-sync) # Enable pfsync
pass on { $int_if, $ext_if } proto carp keep state (no-sync) # Enable CARP

block in quick on $ext_if from $priv_nets to any
block out quick on $ext_if from any to $priv_nets

# Mail server
pass in on $ext_if inet proto tcp from any to $mail_srv port $mail_ports
pass out on $int_if inet proto tcp from any to $mail_srv port $mail_ports
pass in on $int_if inet proto tcp from $mail_srv to any port smtp
pass out on $ext_if inet proto tcp from $ext_if to any port smtp modulate state

# Web servers
pass in on $ext_if inet proto tcp from any to $web_srv port $web_ports \
synproxy state
pass out on $int_if inet proto tcp from any to $web_srv port $web_ports

# ICMP
pass in inet proto icmp all icmp-type $icmp_types
pass out inet proto icmp all

# DNS
pass in on $int_if inet proto { tcp, udp } from $int_if:network to $dns_srv \
port domain
pass out on $ext_if inet proto { tcp, udp } from $ext_if to $dns_srv \
port domain

# Internet web servers
pass in on $int_if inet proto tcp from $int_fw to any port $web_ports
pass out on $ext_if inet proto tcp from $ext_if to any port $web_ports \
modulate state

 7. Приложения

7.1 Ссылки

[MISC17] — Filtrage applicatif : le cas des clients web, mail et p2p (MISC N?17)
[PUIS] — Practical UNIX and Internet Security, Simson Garfinkel and Gene Spafford, O’Reilly, 2003
[ABSO] — Absolute OpenBSD, Michael W. Lucas, No Starch Press, 2003
[CARP] — «CARP License» and «Redundancy must be free»
[PFFAQ] — PF: The OpenBSD Packet Filter
[RFC3768] — RFC 3768, Virtual Router Redundancy Protocol (VRRP)
[RFC2281] — RFC 2281, Cisco Hot Standby Router Protocol (HSRP)

7.2 Библиография

The Common Address redundancy Protocol (CARP)
Firewall Failover with pfsync and CARP
Firewalling with OpenBSD’s PF packet filter, Peter N. M. Hansteen, 2008
The Book of PF, Peter N. M. Hansteen, No Starch Press, 2008
The OpenBSD PF Packet Filter Book, Jeremy C. Reed, Reed Media Services, 2006

Уважайте труд автора и переводчика, не ищите дешевой славы — оставляйте ссылки и копирайты при размещении статьи на своем ресурсе!

Реклама на сайте висит не просто так! Спасибо!


Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


*