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.
+----| WAN/internet |----+
| |
em2| |em2
+-----+ +-----+
| fw1 |-em1----------em1-| fw2 |
+-----+ +-----+
em0| |em0
| |
---+-------Shared LAN-------+---
Firewall'ы подключены друг к другу при помощи перекрестного (crossover)
кабеля с 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!