June 10, 2009

Configure a Vyatta Cluster for Redundant Virtual Firewalls

If you missed the Protect the Service Console Network With a Virtual Firewall project, we looked at how to use a Vyatta firewall to protect the ESX Service Console network and restrict SSH and VI or vSphere Client access to only a few specific workstations. Vyatta offers an impressive network operating system that can be run from a live CD, permanently installed on physical or virtual hardware, or downloaded as a virtual appliance. It comes with some high end features like stateful packet inspection, site-to-site VPN, OSPF, and BGP. There's a completely free edition with unrestricted access to all the features, but it can also be purchased with support offerings.

If you followed along with the original post, you may have noticed a potential pitfall: what if the ESX server hosting the Vyatta virtual machine goes down? You may have HA enabled, but what if it takes several minutes for the VM to boot all the way up on another host? Even a couple of minutes with no SSH or VM console access during a crisis would feel like an eternity.

Amazingly, the Vyatta operating system also includes clustering, and it's very simple to configure. To set up a cluster, we'll need the following:

  • Two Vyatta VC5 virtual machines, preferably with very similar configurations, see Protect the Service Console Network With a Virtual Firewall for a quick setup tutorial

  • Both Vyatta VMs will need two virtual NICs, each with its own real IP address: one in the Service Console network, and one in a LAN network

  • The clustered Vyatta VMs will host two virtual IPs: one will be the default gateway address configured on every ESX host (172.20.1.254 in our case), and the second will be a LAN address you specify as the route to the Service Console network on the Layer 3 device routing between your LAN subnets. In our case, we have a very simplified setup and the Vyatta's LAN facing interface is the default gateway for the LAN (10.1.1.254)

There's some good documentation on setting up a cluster in the High Availability Reference Guide for VC5 available for download at the Vyatta website.

Once you've got the two Vyatta VMs up and running on different ESX hosts, this is how the cluster configuration will look on the primary Vyatta firewall. We're using a conservative dead-interval of ten seconds, meaning a failover will only occur if keepalives are missed for that long, and keepalives are being sent out every two seconds over the eth0 (Console Network) interface.

The service commands define the virtual IPs the cluster will bring up on the secondary if the primary stops responding:

cluster {
    dead-interval 10000
    group sc-cluster {
        auto-failback true
        primary sc-firewall-pri
        secondary sc-firewall-sec
        service 10.1.1.254/24/eth1
        service 172.20.1.254/24/eth0
    }
    interface eth0
    keepalive-interval 2000
    pre-shared-secret ****************
}

interfaces {
    ethernet eth0 {
        address 172.20.1.252/24
        hw-id 00:50:56:9c:3b:0b
    }
    ethernet eth1 {
        address 10.1.1.252/24
        hw-id 00:50:56:9c:04:a5
    }
    loopback lo {
    }
}


And here's the cluster configuration on the secondary firewall. The actual cluster commands are identical, only the real IPs assigned to the interfaces are different:

cluster {
    dead-interval 10000
    group sc-cluster {
        auto-failback true
        primary sc-firewall-pri
        secondary sc-firewall-sec
        service 10.1.1.254/24/eth1
        service 172.20.1.254/24/eth0
    }
    interface eth0
    keepalive-interval 2000
    pre-shared-secret ****************
}

interfaces {
    ethernet eth0 {
        address 172.20.1.253/24
        hw-id 00:50:56:9c:3c:e0
    }
    ethernet eth1 {
        address 10.1.1.253/24
        hw-id 00:50:56:9c:38:04
    }
    loopback lo {
    }
}

As you can see, it's pretty simple to set up, but one annoyance with the cluster feature is that you have to create the same firewall rules on each device, there's no functionality for syncing up the configurations.

It wasn't too hard to write a quick and dirty little shell script to copy just the firewall configuration from the primary to the secondary, however, so you only need to maintain the rules on the primary, and then remember to run the script after saving the changes. If you like, you can set up public key authentication for SSH access from the primary to the secondary like we did in DIY ESX Server Health Monitoring - Part 2, but it's not necessary, the script will prompt you for the password during the SSH connection attempt.


#!/bin/bash

# Vyatta cluster firewall sync script
# by Robert Patton - 2009
#
# Copies firewall rules from primary to secondary
# and applies them to the appropriate interfaces.
#
# Deletes existing firewall rules on secondary and
# removes any firewall sets on interfaces, so make
# sure this is only run from the primary.
#
# Replace the SECONDARY value with the hostname or IP
# of the secondary device in the cluster.

SECONDARY="sc-firewall-sec"

TEMPFWRULES=$(mktemp TEMPFWRULES.XXXXXXXX)
TEMPINTCMDS=$(mktemp TEMPINTCMDS.XXXXXXXX)
TEMPSETCMDS=$(mktemp TEMPSETCMDS.XXXXXXXX)

# Match just the firewall section from the boot config file
awk '/^firewall {/, /^}/' /opt/vyatta/etc/config/config.boot > $TEMPFWRULES

# Match the interface section, we filter for firewall set statements later
awk '/^interfaces {/, /^}/' /opt/vyatta/etc/config/config.boot > $TEMPINTCMDS

# Create a script to run on the secondary with the firewall set commands
# The vyatta-config-gen-sets.pl script creates set commands from the config
cat > $TEMPSETCMDS <<'EOF1'
configure
# First remove any firewalls from interfaces
for int in $(show interfaces ethernet | \
awk '/eth[0-9]/ {print $1}'); \
do delete interfaces ethernet $int firewall; \
done
# Now delete all firewalls
for fwall in $(show firewall name | \
awk '/^ \w* {$/ {print $1}')
do delete firewall name $fwall; \
done
EOF1

cat >> $TEMPSETCMDS <<EOF2
# Create firewalls found on primary
$(/opt/vyatta/sbin/vyatta-config-gen-sets.pl $TEMPFWRULES)
# Apply firewalls to interfaces as defined on primary
$(/opt/vyatta/sbin/vyatta-config-gen-sets.pl $TEMPINTCMDS | grep firewall)
commit
save
exit
exit
EOF2

# Force a tty for the ssh connection - Vyatta environment variables
# and special shell are only set up during an interactive login
cat $TEMPSETCMDS | ssh -tt $SECONDARY

rm -f $TEMPFWRULES $TEMPSETCMDS $TEMPINTCMDS



3 comments:

  1. This is a bit dated since VC6 is out, but I thought I'd comment on the lack of a config-syncing feature. While Vyatta doesn't support it officially yet, I've found the following worked well in my own situation:

    http://blog.fohnet.co.uk/2010/05/11/vyatta-config-sync/

    ReplyDelete
  2. you may also check this out:
    http://www.vyatta4people.org/vyatta-config-sync/

    ReplyDelete