对于openbsd或freebsd来说,任何疑问,都应该先阅读官方文档,里面可以几乎可以找到你想知道的一切。

准备工作

实验室有两台openbsd防火墙,每台3张网卡,网络拓扑如下:

         +----| WAN/Internet |----+
         |                        |
      em0|                        |em0
      +-----+                  +-----+
      | ob1 |-em2----------em2-| ob2 |
      +-----+                  +-----+
      em1|                        |em1
         |                        |
      ---+-------Shared LAN--+----+---
                             |
                             |eth0
                          +--+--+
                          |debn6|
                          +-----+

网卡和IP地址关系列表:

host

nic

ip

openbsd1

em0($wan_if)

10.199.18.97

em1($dmz_if)

192.168.5.251

em2($sync_if)

172.16.1.1

carp1

10.199.18.90

openbsd2

em0($wan_if)

10.199.18.98

em1($dmz_if)

192.168.5.252

em2($sync_if)

172.16.1.2

carp2

192.168.5.254

debn6

eth0

192.168.5.3

两台ob的carp虚拟网卡拥有相同的virtual mac。

carp中的virtual mac

Virtual MAC Address: The Carp virtual MAC is in the format 00-00-5e-00-01-xx where the last octet is filled in by the CARP vhid. For example if you look at the MASTER firewall you will see carp1 has the MAC address of 00-00-5e-00-01-01 and carp2 is 00-00-5e-00-01-02

在ob中,可以将多个carp虚拟网卡加入一个组里面,通过控制carpdemote count来实现整机的master和backup角色的互换,譬如说,ob1的carpdemote count为0,ob2的carpdemote count为100,则ob1为master,ob2为backup(ob1的carp1、carp2全部为master,ob2的carp1和carp2为backup)

  • openbsd1

    $ ifconfig -g carp
    carp: carp demote count 0
  • openbsd2

    $ ifconfig -g carp
    carp: carp demote count 50

这个时候,master角色位于openbsd1上。

测试一:master角色从ob1迁移至ob2

在ob1中执行ifconfig -g carp carpdemote 50,则ob1的carp角色由master变成backup,ob2则从backup变成master。

在ob1中执行ifconfig em1 down,相当于停用carp2,ob2 ping不通ob1的192.168.5.251(em1),debn6还是可以ping通10.199.18.97(carp1)。

在ob1中执行ifconfig em1 up,相当于启用carp2,ob2可以ping通ob1的192.168.5.251(em1)。

测试二:master角色从ob2迁移回ob1

  • ob1中的pf.conf已配置,ob1的carp角色是backup

  • ob2中的pf.conf未配置,ob2的carp角色是master

此时,外网无法访问debn6,接着在ob1中执行:

ifconfig -g carp -carpdemote 50

此时:

  • ob1变成master

  • ob2变成backup

外网可以访问debn6的ssh服务。   == 测试三:拔插网线

拔掉ob1中em1(dmz_if)网卡的网线:

  • ob1的carp1变成backup,carp2变成INIT

  • ob2变成master   插上ob1中em1(dmz_if)网卡的网线:

  • ob1变回master,ob2变成backup   拔掉ob1中em2(sync_if)网卡的网线:

  • ob1和ob2的状态不变。原因是两台openbsd防火墙的同步数据包的通道不仅仅是$sync_if,也包括$wan_if、$dmz_if。

两台防火墙均配置了相同pf.conf,对debn6做了wan:9322→dmz:22端口映射:

wan_vip = "221.182.254.188"
...
pass in quick log on $wan_if inet proto tcp to $wan_vip port 9322 \
    rdr-to $debn6 port 22
pass quick log on $lan_if inet proto tcp to $debn6 port 22

从外网使用paping工具探测9322端口

paping 221.182.254.188 -p 9322

通过tcpdump工具在ob1和ob2上观察的结果如下:

  • 探测数据包到达ob1;

  • 探测数据包无法到达ob2;

在ob1上

ifconfig -g carp carpdemote 50

ob1变为backup,ob2变为master

此时,ob1和ob2的tcpdump结果正好跟上面结果倒转过来。

排错

假设将该虚拟IP附着在fxp0上,需要先配置好hostname.fxp0,然后启动该接口sh /etc/netstart fxp0 否则会出现以下错误:

root@openbsd-1/etc: # ifconfig carp0 221.182.254.187 vhid 1
ifconfig: SIOCAIFADDR: Can't assign requested address