Improve reliability with CARP and redundant DNS on two boxes. Almost everyone already has (at least) two nameservers, so why not add CARP into the mix to make it appear as if they're always available?

This setup assumes two nameservers. Both nameservers will have a total of 3 IPs assigned to them, two of which are the floating CARP IPs and one of which is a unique management IP for each box. Each nameserver will be the CARP backup for the other nameservers primary nameserver IP. If one goes down, the other will assume responsibility for the IP.

You'll need to assign your nameservers two new IPs (to be used for management) and take the original pair of IPs and we'll use those for the carp interfaces.

Rebuild/install your kernel with (or load the carp module via /boot/loader.conf):

device      carp

Edit /etc/rc.conf to add:

cloned_interfaces="carp0 carp1"
ifconfig_carp0="create"
ifconfig_carp1="create"

Setup the CARP interfaces:

I set the vhid's to be the last octet of the floaty IP, however, you can set them to be whatever you want as long as they match on both boxes.

On ns1: Create /etc/start_if.carp0 with the following:

#!/bin/sh
ifconfig carp0 vhid XX advbase 1 advskew 10 pass supersecretpasswordhere <ns1.ip> netmask <ns1.netmask>

Create /etc/start_if.carp1 with the following:

#!/bin/sh
ifconfig carp1 vhid YY advbase 2 advskew 10 pass othersupersecretpasswordhere <ns2.ip> netmask <ns2.netmask>

Then run:

chmod go-rwx /etc/start_if.carp*;chmod +x /etc/start_if.carp*

On ns2: Create /etc/start_if.carp0 with the following:

#!/bin/sh
ifconfig carp0 vhid YY advbase 1 advskew 10 pass supersecretpasswordhere <ns2.ip> netmask <ns2.netmask>

Create /etc/start_if.carp1 with the following:

#!/bin/sh
ifconfig carp1 vhid XX advbase 2 advskew 10 pass othersupersecretpasswordhere <ns1.ip> netmask <ns1.netmask>

Then run:

chmod go-rwx /etc/start_if.carp*;chmod +x /etc/start_if.carp*

carp0 on both boxes will be its PRIMARY IP whereas carp1 will be the SECONDARY IP on both. In a non-failover scenario, this means that carp0 on both boxes should show up as MASTER and carp1 should show up as BACKUP.

Ensure named is configured to bind to the management IP (for zone transfers, etc.), ns1.ip and ns2.ip (on both boxes!) or ensure that it listens on *.

Add this to /etc/sysctl.conf for some extra logging info.

net.inet.carp.log=2

Reboot. Your primary box should come up with ns1.ip as MASTER and ns2.ip as BACKUP. Your secondary box should come up with ns2.ip as MASTER and ns1.ip as BACKUP. Check ifconfig and dmesg to confirm.

CARP traffic is multicast and you may need to alter firewalls as appropriate to allow it. The destination is VRRP.MCAST.NET/224.0.0.18. For defining masters/slaves, etc. in bind you will want to reference the management IPs of the boxes, not the floating CARP addresses.

You can actually skip using the start_if.* files if you elect to put the ifconfig statements into rc.conf. In order to limit access to your CARP authentication key, you would need to change the permissions on rc.conf which could be bad in certain situations.

ESX Note: If you're trying to do this with a box in VMware, you'll need to disable the vSwitch security features (accept: promisc, forged transmits, mac changes). This is not advisable in production as any VM on that switch can sniff traffic from any other VM. For my setup at home, I simply allocated a second NIC and a second vSwitch and made the security changes on the dedicated vSwitch. No other VMs should share this other vSwitch where the security features have been disabled.