Anycast DNS Using RIP
This third article in our series on Anycast DNS, focuses on deploying Anycast DNS using RIP v2 routing protocol.
In this article we'll be using Quagga, Open Source host-based routing software, to originate our Anycast IP address. Our upstream routers are Cisco routers, so we'll also be providing all routing configurations that are needed for the recipes. The goal of the recipe is to be efficient, secure, and simple.
In this recipe we configure a single Anycast VIP on two name servers, using host-based routing software to originate the routes Anycast VIPs to their upstream routers via the RIP v2 routing protocol. The following figure shows our configuration for this exercise:
Two Linux-based DNS servers running Quagga's ripd routing protocol, are configured with an Anycast VIP of 192.168.0.1/32. But first, a quick refresher on RIP v2 is in order.
RIP v2 Refresher
RIP is a distance-vector protocol, based on the Bellman-Ford algorithms, and is still widely deployed as an interior gateway protocol. As a distance-vector protocol, RIP router send updates to its neighbors periodically, thus allowing the convergence to a known topology. In each update, the distance to any given network will be broadcasted to its neighboring router.
RIP has several customizable timers which are summarized in the following table:
|Route update timer||The interval between periodic routing updates in which the router sends a complete copy of its routing table out to all neighbors.||30 seconds|
|Route invalid timer||The length of time that must elapse before a router determines that a route has become invalid. This is determined when there are no further announcements from a neighbor for a particular route. When this occurs, the router will send out an announcement to all its neighbors of the now invalid route.||180 seconds|
|Holddown timer||This sets the amount of time during which routing information is suppressed. Routes will enter into the holddown state when an update packet is received that indicated the route is unreachable. This continues either until an update packet is received with a better metric or until the holddown timer expires.||180 seconds|
|Route flush timer||Sets the time between a route becoming invalid and its removal from the routing table. Before it’s removed from the table, the router notifies its neighbors of that route’s impending demise. The value of the route invalid timer must be less than that of the route flush timer. This gives the router enough time to tell its neighbors about the invalid route before the local routing table is updated.||240 seconds|
Because of these timers and the manner in which RIP v2 manages routing updates, RIP v2 is less than an optimal choice for our Anycast DNS design. As we'll see in the testing section, RIP v2, while a dynamic routing protocol, is much slower at performing topology convergence than OSPF and BGP.
Recipe - Single Anycast VIP
Step 1 - Configure Anycast VIP on Server A
Configure the Anycast VIP as a virtual loopback device on lo (or lo0 depending on the platform)
ifconfig lo:0 192.168.0.1 netmask 255.255.255.255
Make sure the settings for the new loopback device are defined in the appropriate configuration file so that it will come up properly when the system is rebooted. On an RHEL Linux system, this can be done by creating the /etc/sysconfig/network-scripts/ifcfg-lo0 configuration file.
Step 2 - Configure zebra (part of Quagga)
When configuring Quagga, you must configure two parts, zebra and the desired routing protocol daemon (in our case its ripd). The typical location of the Quagga configuration files is in /etc/quagga, unless you have built Quagga with non-default file locations. Create the /etc/quagga/zebra.conf as follows:
hostname server_a ! password Passw0rd! enable password Passw0rd! ! interface lo ! interface lo:0 ip address 192.168.0.1/32 ipv6 nd suppress-ra ! interface eth0 ip address 10.0.1.10/24 ipv6 nd suppress-ra ! line vty
Start the zebra process and configure it to start automatically at boot time. Now that zebra is running, we can access the running configuration interactively by using the vty. This is performed with the following command: telnet localhost 2601
Step 3 - Configure ripd (part of Quagga)
To enable the RIP routing protocol daemon of Quagga, create and edit the file /etc/quagga/ripd.conf as follows:
hostname server_a password zebra1 log stdout ! router rip version 2 network 192.168.0.0/24 network 192.168.1.0/24 network lo:0 network eth0 !
Start the ripd routing daemon and configure it to start automatically at boot time. Now that ripd is running, we can access the running configuration interactively by using the vty. This is performed with the following command: telnet localhost 2602
Step 4 - Configure Server A Upstream Router R1
Since almost everyone uses Cisco routers, it only makes sense to show how one might configure the upstream Cisco router. Perform the following in enable mode:
R1# configure terminal R1(config)# router rip R1(config-router)# version 2 R1(config-router)# network 10.0.0.0 R1(config-router)# network 192.168.0.0 R1(config-router)# network 192.168.1.0 R1(config-router)# no auto-summary R1(config-router)# end
Provided the following, we should be routing our Anycast VIP at this point. Perform a show ip route command on the Cisco router R1 to see the current routing table. This is the very minimum set of commands that are needed to get the Anycast VIP to route. In a continuation of this article, we'll show how to extend this configuration to increase the level of security and be more efficient.
Step 5 - Create Failover Mechanism
In the event that our DNS process on Server A fails, it is desirable to remove the Anycast VIPs from the global routing table. To do this, we need to stop the origination or advertisement of those VIPs at the source on Server A. A small script is needed to perform cursory health checks of the DNS process to ensure it is operating properly. If it fails the test, then the routing software should be disabled or told to stop advertising our Anycast VIPs to the upstream neighbors. An example of this might look like the following:
#!/bin/bash DNSUP=`/usr/sbin/dig @192.168.0.1 localhost. A +short` if [ "$DNSUP" != "127.0.0.1" ]; then echo "Stopping Anycast...." /etc/init.d/quagga stop /etc/init.d/named stop else echo "Everything's good... Do nothing..." fi
Schedule this script as a job in cron to run at some interval, such as every 60 seconds. This is just a sample script, there are opportunities for additional significant logical tests and checks that could be added to a script like this. The main point here is that we want to make sure we stop advertising the Anycast VIPs when our DNS service is non-functional.
Step 6 - Repeat steps 1-5 on Server B and router R2
To test functionality and failover of Anycast DNS, a simple looping script was used. The script performed a DNS query to the Anycast VIP for the hostname.bind TXT record in the CHAOS class. In our previous article, Anycast DNS - Part 2, Using Static Routes, we mentioned the importance of configuring the nameserver with the hostname directive in its named.conf file. The script issues a hostname.bind query every 3 seconds, and the response it receives tells us exactly which nameserver of the two is responding.
The following test cases were performed:
- Kill/stop named DNS process - simulates a failure or maintenance in the named process (Quagga is still running and routing)
- Kill/stop Quagga host-based routing software - simulates an application failure or maintenance to our host-based routing software
- Disable upstream router interface - this simulates either a downed router, or router that is administratively taken down for maintenance.
Default RIP v2 timers were used in the testing. Additional and/or different test results could be obtained by altering these timers to achieve better performance.
|Test Case #||Test Description||Failover in Secs. (avg)||Timeout in Secs. (avg)|
|Test 1||Kill/stop named process on Server A||> 240 - 300 seconds||> 240 seconds|
|Test 2||Disable Quagga routing daemons on Server A||> 240 - 300 seconds||N/A|
|Test 3||Administratively down the upstream router interface on R1-A||> 240 - 300 seconds||N/A|
In nearly all our tests the failover was delayed by at least 240 seconds or more. In our first test, we experience timeout in the failover process. In test 1, the DNS process was not running, but Quagga was still up and routing. This means our Anycast routes were still being injected into the routing infrastructure. We had timeout issues because DNS query packets were still being routed to Server A that it was unable to serve. To avoid this issue during normal maintenance, it is strongly advised that both Quagga and named DNS process be started and stopped using the same startup/shutdown script. The shutdown of named should be delayed 300 seconds to permit RIP to flush the Anycast DNS routes from its tables. This will prevent the DNS client resolver timeout issue when shutting down normally for maintenance cycles. These tests results are for a small network. The numbers will be even larger on a large LAN/WAN.
RIP v2 quite simply is not the best routing protocol to implement Anycast DNS because of its timers, slow convergence, and distance vector routing updates. Yes it works, but it's far from optimal. Most environments that want to deploy Anycast are not even using RIP in their environment. We still wanted to show recipes for how to accomplish Anycast DNS using RIP v2. In Anycast DNS using RIP part 2, we'll show a few improvements made to our RIP v2 recipe that improve the overall security, behavior, and performance of our Anycast DNS design.