CARP позволяет группе хостов в одном сегменте сети совместно использовать один и тот же IP-адрес. Эта группа хостов называется «группой резервирования». Ей назначается IP-адрес, который является общим для всех хостов в группе. Внутри группы один из хостов обозначен как «главный», а остальные как его «резервные копии». Главный хост - тот, который в настоящее время «держит» общий IP; он отвечает на любой трафик или запросы ARP, направленные на этот IP-адрес. Каждый хост может принадлежать более чем одной группе резервирования одновременно.
Одним из распространенных применений CARP является создание группы хостов резервирования для firewall'ов. Виртуальный IP-адрес, назначенный группе резервирования, настраивается на клиентских компьютерах в качестве шлюза по умолчанию. В случае сбоя главного хоста firewall'а или перехода его в автономный режим, IP-адрес будет использоваться одним из резервных хостов. При этом это никак не отразится на работе самого firewall'а как сервиса.
CARP поддерживает IPv4 и IPv6.
advbase
и advskew
).
Возможно наличие нескольких CARP-групп в одном сегменте сети. CARP-сообщения содержат идентификатор виртуального хоста, который позволяет членам группы определить, к какой группе резервирования принадлежит эти сообщения.
Чтобы злоумышленник в сегменте сети не мог подделать эти CARP-сообщения, каждая группа может быть настроена с паролем. Каждый CARP-пакет, отправленный группе, защищен при помощи SHA1 HMAC.
Поскольку CARP является отдельным независимым протоколом, для него должно быть указано pf pass-правило:
pass out on $carp_dev proto carp
$carp_dev
это имя физического интерфейса, который будет
использоваться CARP'ом для связи с остальными хостами из резервной группы.
# ifconfig carpN create # ifconfig carpN vhid vhid [pass password] [carpdev carpdev] \ [advbase advbase] [advskew advskew] [state state] [group|-group group] \ ipaddress netmask mask
carpN
vhid
password
carpdev
advbase
advskew
advbase
при отправке CARP-сообщений.
Управляя advskew
, можно выбрать главный хост CARP.
Чем выше число, тем менее предпочтительным будет хост при выборе мастера.
По умолчанию 0. Допустимые значения от 0 до 254.
state
init
, backup
,
и master
.
group, -group
carp
.
Каждая группа имеет счетчик carpdemote
, влияющий
на все carp(4) интерфейсы, принадлежащие этой группе.
Если один CARP-интерфейс выйдет из строя, CARP увеличит счетчик
понижения уровня на 1 в группах интерфейсов, членом которых
является интерфейс carp(4), в результате чего все члены группы
будут переключаться при сбое одновременно.
ipaddress
mask
Поведение и состояние CARP можно контролировать при помощи sysctl(8).
net.inet.carp.allow
net.inet.carp.preempt
advbase
и advskew
, заменить мастера.
Значение net.inet.carp.preempt
равно 0 (отключено) по умолчанию.
net.inet.carp.log
# sysctl net.inet.carp.allow=1 # echo 'net.inet.carp.allow=1' >> /etc/sysctl.conf # ifconfig carp1 create # ifconfig carp1 vhid 1 pass mekmitasdigoat carpdev em0 advskew 100 10.0.0.1 netmask 255.255.255.0Эти команды создают конфигурацию, а именно:
carp1
carp1
для виртуального хоста #1, включают пароль,
устанавливают em0
в качестве интерфейса, принадлежащего группе,
и делают этот хост резервным, т.к. advskew
имеет значение
100
(при условии, конечно, что мастер настроен со значением
advskew
менее 100)
Вывод команды ifconfig
для carp1
интерфейса покажет
следующее состояние.
# ifconfig carp1 carp1: flags=8802<UP,BROADCAST,SIMPLEX,MULTICAST> mtu 1500 carp: BACKUP carpdev em0 vhid 1 advbase 1 advskew 100 groups: carp inet 10.0.0.1 netmask 0xffffff00 broadcast 10.0.0.255
Когда pfsync настроен на отправку и получение обновлений из сети, по умолчанию используется многоадресная рассылка обновлений для локальной сети. Все обновления отправляются без аутентификации. Вот пример лучшей практики:
syncdev
(см. ниже)
syncpeer
(см. ниже), чтобы обновления выполнялись
unicast-передачей напрямую одноранговому узлу, затем настройте
ipsec(4) между хостами для
защиты pfsync трафика
pass on $sync_if proto pfsync
$sync_if
это имя физического интерфейса, который будет использовать
pfsync.
# ifconfig pfsyncN syncdev syncdev [syncpeer syncpeer] [defer|-defer]
pfsyncN
syncdev
syncpeer
syncpeer
.
defer
defer
,
первый initial-пакет нового соединения, проходящего через firewall, не будет
передаваться, пока либо другая система pfsync не подтвердит добавление
таблицы состояний, либо не истечет время ожидания.
Это добавляет небольшие задержки, но позволяет трафику проходить, когда
несколько firewall'ов могут активно обрабатывать пакеты («активный/активный»),
например, с некоторыми конфигурациями
ospfd(8),
bgpd(8), или
carp(4).
# ifconfig pfsync0 syncdev em1 upЭта команда активирует(enables) pfsync на интерфейсе
em1
.
Исходящие обновления будут многоадресными (multicast) в сети, что
позволит любому другому узлу, на котором запущен pfsync, получать их.
Пример сценария: два firewall'а, fw1
и fw2
.
Firewall'ы подключены друг к другу при помощи перекрестного (crossover) кабеля с+----| WAN/internet |----+ | | em2| |em2 +-----+ +-----+ | fw1 |-em1----------em1-| fw2 | +-----+ +-----+ em0| |em0 | | ---+-------Shared LAN-------+---
em1
.
Оба подключены к локальной сети с em0
и к WAN/интернет с
em2
. IP-адреса следующие:
fw1
будет предпочтительным мастером.
Чтобы настроить fw1, начните с включения приоритетного прерывания (preemption) и переключения группового интерфейса при отказе (group interface failover):
# sysctl net.inet.carp.preempt=1 # echo 'net.inet.carp.preempt=1' >> /etc/sysctl.confНастройка pfsync:
! configure pfsync # ifconfig em1 10.10.10.1 netmask 255.255.255.0 # ifconfig pfsync0 syncdev em1 # ifconfig pfsync0 upНастройка CARP на стороне LAN:
# ifconfig carp1 create # ifconfig carp1 vhid 1 carpdev em0 pass lanpasswd \ 172.16.0.100 netmask 255.255.255.0Настройка CARP на стороне WAN/интернет:
# ifconfig carp2 create # ifconfig carp2 vhid 2 carpdev em2 pass netpasswd \ 192.0.2.100 netmask 255.255.255.0Затем настраиваем соответственно fw2:
# sysctl net.inet.carp.preempt=1 # echo 'net.inet.carp.preempt=1' >> /etc/sysctl.conf # ifconfig em1 10.10.10.2 netmask 255.255.255.0 # ifconfig pfsync0 syncdev em1 # ifconfig pfsync0 up # ifconfig carp1 create # ifconfig carp1 vhid 1 carpdev em0 pass lanpasswd \ advskew 128 172.16.0.100 netmask 255.255.255.0 # ifconfig carp2 create # ifconfig carp2 vhid 2 carpdev em2 pass netpasswd \ advskew 128 192.0.2.100 netmask 255.255.255.0
Пример содержания этих файлов:
/etc/hostname.carp1
/etc/hostname.pfsync0
Для восстановления определенной CARP-группы выключите carp интерфейс на
главном master-узле.
Это приведет к тому, что сообщения мастера станут с «бесконечной»
advbase
and advskew
.
Резервные хосты увидят это, и роль мастера возьмет на себе кто-то другой.
# ifconfig carp1 downАльтернативой является увеличение
advskew
до значения,
превышающего advskew
на резервных хостах.
Это приведет к аварийному переключению, но все же позволит мастеру
участвовать в CRAP-группе.
Другой метод восстановления после сбоя - настроить счетчик понижения CARP. Счетчик понижения - это мера того, насколько «готов» хост стать master'ом CARP-группы. Например, в то время как хост находится в процессе загрузки, плохой идеей будет стать мастером, пока не будут настроены все интерфейсы, запущены все сетевые демоны и т.д. Хосты, сообщающие о себе высокое значение понижения, будут менее предпочтительными в качестве мастера.
Счетчик понижения хранится в каждой группе интерфейсов, которой принадлежит
CARP-интерфейс. По умолчанию все CARP-интерфейсы являются членами группы
интерфейсов «carp».
Текущее значение счетчика понижения можно просмотреть при помощи
ifconfig
:
# ifconfig -g carp carp: carp demote count 0В этом примере показан счетчик, связанный с группой интерфейсов «carp». Когда CARP-хост объявляет себя в сети, он принимает сумму счетчиков понижения для каждой группы интерфейсов, к которой принадлежит и интерфейс carp, и объявляет это значение в качестве значения понижения (demotion value).
Теперь рассмотрим следующий пример. Два firewall'а, которые объеденены в CARP-кластер со следующими CARP-интерфейсами:
Во-первых, присвойте каждому интерфейсу новую группу, в данном случае с именем «internal»:
# ifconfig carp1 group internal # ifconfig carp2 group internal # ifconfig internal carp1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 carp: MASTER carpdev em0 vhid 1 advbase 1 advskew 100 groups: carp internal inet 10.0.0.1 netmask 0xffffff00 broadcast 10.0.0.255 carp2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 carp: MASTER carpdev em1 vhid 2 advbase 1 advskew 100 groups: carp internal inet 10.0.1.1 netmask 0xffffff00 broadcast 10.0.1.255Теперь увеличьте счетчик понижений для «internal» группы при помощи ifconfig(8):
# ifconfig -g internal internal: carp demote count 0 # ifconfig -g internal carpdemote 50 # ifconfig -g internal internal: carp demote count 50Firewall теперь будет корректно переключаться при сбое на группы carp1 и carp2 на другом firewall'е в кластере, оставаясь при этом основным на carp3 и carp4. Если другой firewall начал отправлять сообщения о себе со значением понижения, превышающим 50, или если другой firewall вообще прекратил отправку этих сообщений, то этот firewall снова перенял бы роль мастера на carp1 и carp2.
Чтобы вернуться к основному firewall'у, отмените изменения:
# ifconfig -g internal -carpdemote 50 # ifconfig -g internal internal: carp demote count 0Сетевые демоны, такие как OpenBGPD и sasyncd(8), используют счетчик понижений, чтобы гарантировать, что firewall не станет главным, пока не будут установлены BGP-сеансы и не синхронизированы SA IPsec.
carp0
).
Таким образом, учитывайте это при написании правил.
Не забывайте, что имя интерфейса в правиле PF может быть именем
физического интерфейса или адресом, связанным с этим интерфейсом.
Например, это правило может быть правильным:
pass in on fxp0 inet proto tcp from any to carp0 port 22Но замена
fxp0
на carp0
не будет работать.
Не забудьте разрешить proto carp
и proto pfsync
!