Firewall redundancy with carp on FreeBSD 9.1

firewall_bsd

First lets recompile freebsd kernel with pf and carp support

cd /usr/src/sys/i386/conf
mkdir /root/kernels
cp GENERIC /root/kernels/bentoslack
ln -s /root/kernels/bentoslack

vi bentoslack
device pf
device pfsync
device pflog
device carp
options ALTQ
options ALTQ_CBQ
options ALTQ_RED
options ALTQ_RIO
options ALTQ_HFSC
options ALTQ_PRIQ
options ALTQ_NOPCC

cd /usr/src
make buildkernel KERNCONF=bentoslack
make installkernel KERNCONF=bentoslack

bentoslack@X200s:~/Desktop$ ssh 192.168.247.27 -l bentoslack
Password:
FreeBSD 9.1-RELEASE (bentoslack)

We need three network interfaces for each firewall(wan,lan,carp sync)

FW1:

em0=192.168.247.27/24 #wan interface
em1=172.16.0.27/24 #lan interface
em2=10.10.10.27/24 #carp interface
carp0=192.168.247.100/24 #shared wan interface
carp1=172.16.0.1/24 #shared lan interface

FW2:

em0=192.168.247.28/24 #wan interface
em1=172.16.0.28/24 #lan interface
em2=10.10.10.28/24 #carp interface
carp0=192.168.247.100/24 #shared wan interface
carp1=172.16.0.1/24 #shared lan interface

FW1:

cat /etc/rc.conf

hostname="FW1"
keymap="hy.armscii-8.kbd"
sshd_enable="YES"
powerd_enable="YES"
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="NO"
ifconfig_em0="inet 192.168.247.27/24"
cloned_interfaces="carp0 carp1"
ifconfig_em1="inet 172.16.0.27/24"
ifconfig_em2="inet 10.10.10.27/24"
ifconfig_carp0="inet 192.168.247.100/24 vhid 1 pass test advskew 0"
ifconfig_carp1="inet 172.16.0.1/24 vhid 2 pass test advskew 0"
ifconfig_pfsync0="syncdev em2"
pf_enable="YES"
pf_rules="/etc/pf.conf"
pf_flags=""
pflog_enable="YES"
pflog_logfile="/var/log/pflog"
pflog_flags=""
gateway_enable="YES"
defaultrouter="192.168.247.1"

cat /etc/pf.conf

ext_if="em0"
int_if="em1"
carp="em2"
set skip on lo0
scrub in all
nat on $ext_if from $int_if:network to any -> ($ext_if)
pass on $carp inet proto pfsync keep state
pass on { $ext_if, $int_if } inet proto carp keep state

cat /etc/sysctl.conf

net.inet.carp.arpbalance=1
net.inet.carp.allow=1
net.inet.carp.preempt=1
net.inet.ip.forwarding=1
net.inet.tcp.blackhole=2
net.inet.udp.blackhole=1
net.inet.tcp.sendspace=65536
net.inet.tcp.recvspace=65536

FW2:

cat /etc/rc.conf

hostname="FW2"
keymap="hy.armscii-8.kbd"
sshd_enable="YES"
powerd_enable="YES"
# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
dumpdev="NO"
ifconfig_em0="inet 192.168.247.28/24"
cloned_interfaces="carp0 carp1"
ifconfig_em1="inet 172.16.0.28/24"
ifconfig_em2="inet 10.10.10.28/24"
ifconfig_carp0="inet 192.168.247.100/24 vhid 1 pass test advskew 100"
ifconfig_carp1="inet 172.16.0.1/24 vhid 2 pass test advskew 100"
ifconfig_pfsync0="syncdev em2"
pf_enable="YES"
pf_rules="/etc/pf.conf"
pf_flags=""
pflog_enable="YES"
pflog_logfile="/var/log/pflog"
pflog_flags=""
gateway_enabled="YES"
defaultrouter="192.168.247.1"

cat /etc/pf.conf

ext_if="em0"
int_if="em1"
carp="em2"

set skip on lo0
scrub in all
nat on $ext_if from $int_if:network to any -> ($ext_if)
pass on $carp inet proto pfsync keep state
pass on { $ext_if, $int_if } inet proto carp keep state

cat /etc/sysctl.conf

net.inet.carp.arpbalance=1
net.inet.carp.allow=1 # Allow the firewall to accept CARP packets
net.inet.carp.preempt=1 # Allow firewalls to failover when one goes down
net.inet.ip.forwarding=1 # Allow packet forwarding through the firewalls
net.inet.tcp.blackhole=2
net.inet.udp.blackhole=1
net.inet.tcp.sendspace=65536
net.inet.tcp.recvspace=65536

Let`s simulate hardware failure( for example FW1, which is Master) I will reboot the server

On FW2

root@FW2:/usr/home/bentoslack # tcpdump -i em1
listening on em1, link-type EN10MB (Ethernet), capture size 65535 bytes
20:31:15.743077 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:31:16.760463 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:31:17.769896 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:31:18.779350 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:31:19.789115 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:31:20.798691 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:31:21.811340 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:31:22.818259 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:32:18.387518 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:32:19.401798 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:32:20.434015 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:32:21.444717 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:32:22.455101 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:32:25.864213 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:32:25.864317 ARP, Request who-has 172.16.0.1 tell 172.16.0.1, length 28
20:32:27.275029 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:32:28.686703 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:32:30.096736 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:32:31.506761 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:32:32.916785 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:32:34.326901 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36

Now,FW2 is master

carp0: flags=49<UP,LOOPBACK,RUNNING> metric 0 mtu 1500
inet 192.168.247.100 netmask 0xffffff00
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
carp: MASTER vhid 1 advbase 1 advskew 100
carp1: flags=49<UP,LOOPBACK,RUNNING> metric 0 mtu 1500
inet 172.16.0.1 netmask 0xffffff00
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
carp: MASTER vhid 2 advbase 1 advskew 100

And when FW1 is online

20:33:05.352422 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:33:06.764943 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:33:08.174812 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:33:09.588241 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:33:11.002042 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:33:12.410123 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:33:13.107028 ARP, Request who-has 172.16.0.27 tell 172.16.0.27, length 46
20:33:13.819929 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:33:14.771250 IP 172.16.0.27 > igmp.mcast.net: igmp v3 report, 1 group
record(s)
20:33:15.229934 IP 172.16.0.28 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 100, authtype none, intvl 1s, length 36
20:33:15.243249 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:33:15.243286 ARP, Request who-has 172.16.0.1 tell 172.16.0.1, length 46
20:33:16.251905 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:33:16.397591 IP 172.16.0.27 > igmp.mcast.net: igmp v3 report, 1 group
record(s)
20:33:17.274780 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:33:18.322249 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36
20:33:19.356768 IP 172.16.0.27 > vrrp.mcast.net: VRRPv2, Advertisement, vrid
2, prio 0, authtype none, intvl 1s, length 36

FW2 is now BACKUP

carp0: flags=49<UP,LOOPBACK,RUNNING> metric 0 mtu 1500
inet 192.168.247.100 netmask 0xffffff00
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
carp: BACKUP vhid 1 advbase 1 advskew 100
carp1: flags=49<UP,LOOPBACK,RUNNING> metric 0 mtu 1500
inet 172.16.0.1 netmask 0xffffff00
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
carp: BACKUP vhid 2 advbase 1 advskew 100

Leave a Reply

Your email address will not be published. Required fields are marked *