Anycast DNS Using Static Routing

/ DNS, BIND, Anycast, DDI

Anycast DNS

This second article in our series "Anycast DNS" is a recipe for deploying Anycast DNS using static routes.

In this article we'll show our recipe for configuring Anycast using static routes, and provide an explanation as to why this is the least optimal way of building an Anycast DNS environment.

Recipe - Single Anycast IP Address 192.168.0.1/32

The goal of this recipe is to configure Anycast DNS on two (2) Linux caching only DNS servers. While this solution can accommodate additional servers, we'll only deal with two servers in our scenario. Our fictitious company, ABC Corporation, uses RIPv2 as its IGP routing routing protocol. NOTE: for this solution there is no requirement for any host-based routing software.

Anycast DNS using Static Routing

The figure above shows two name servers, Server A & B, deployed on two different subnets 10.0.1.0/24 and 10.0.2.0/24 respectively. Both servers are shown configured with a virtual loopback interface of 192.168.0.1. Each of these systems has an upstream router that will be responsible forĀ originatingĀ a static route to the Anycast DNS address of 192.168.0.1/32. The upstream router's job is not only to originate the route, but to redistribute it into the IGP cloud.

Step 1 - Create virtual interfaces with Anycast Address

Create a loopback interface for our Anycast virtual interface. In the following example, a virtual interface, lo:0 is added to the existing loopback interface, lo. It is configured with the Anycast DNS address 192.168.0.1 with a mask of 255.255.255.255.

Server A:

[root@A~]# ifconfig lo:0 192.168.0.1 netmask 255.255.255.255 up

[root@A ~]# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:30:48:80:AF:9B
          inet addr:10.0.1.10  Bcast:10.0.1.255  Mask:255.255.255.0
inet6 addr: fe80::230:48ff:fe80:af9b/64 Scope:Link
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:33 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:248 (248.0 b)  TX bytes:7307 (7.1 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
          RX bytes:716 (716.0 b)  TX bytes:716 (716.0 b)

lo:0      Link encap:Local Loopback
          inet addr:192.168.0.1  Mask:255.255.255.255
UP LOOPBACK RUNNING  MTU:16436  Metric:1

Repeat this step for server B.

Step 2 - Configure upstream router with static route and redistribute route into the network

Configure the upstream router from Server A, R1 with the static route and redistribute that route into the network. NOTE: in this case our IGP is RIP. This is shown below:

R1# configure terminal
Enter configuration commands, one per line. End with CNTL/Z.
R1(config)# ip route 192.168.0.1 255.255.255.255 10.0.1.10
R1(config)# router rip
R1(config-router)# redistribute static
R1(config-router)# end

Repeat this same configuration for Server B's upstream router R2. The command to add the static route will differ only in the gateway address that is used, 10.0.2.10 instead. Everything else is the same.

Step 3 - Configure the name server

Configure the name service as a caching only server that binds port 53 to the Anycast IP of 192.168.0.1 and no other address. Additionally, it's recommended that the server-id and hostname directives be configured and used for management purposes. We'll dive into this later. These changes are made by editing the named.conf. The following is an example of the configuration used:

//
// named.conf for Server A
//
options {
    version "none of your business";
    server-id "A";
    listen-on port 53 { 192.168.0.1;};
    directory       "/var/named";
    allow-query     { any; };
    recursion yes;
    hostname "A";
};
logging {
   channel my_syslog {
      syslog daemon;
      severity info;
   };
   channel named_log {
      file "logs/named.log" versions 5 size 1m;
      severity info;
      print-category yes;
      print-severity yes;
      print-time yes;
   };
   channel query_log {
      file "logs/query.log" versions 5 size 1m;
      severity info;
      print-category yes;
      print-severity yes;
      print-time yes;
   };
   category default { named_log; };
   category xfer-out { my_syslog; named_log; };
   category queries { query_log; };
};

zone "." IN {
        type hint;
        file "named.ca";
};

Repeat this step for Server B. The configuration is the same with the exception of the server-id and hostname directives. Once this step is complete, restart both name servers. Everything should be complete. Depending on the size of the network, it may take a bit for the routes to show up, but once they have propagated, you have Anycast DNS set up!

So, How do I test this?

The first step would be to ensure that the Anycast DNS Virtual IP or VIP is being routed. By checking on some downstream routers or core routers on the network, you should see specific host routes for 192.168.0.1/32. One route will refer to 10.0.1.10 as the gateway address, and the other will refer to 10.0.2.10 as the gateway.

Assuming our routes are present, the next step is to perform DNS queries against the Anycast VIP. Using the dig command, try the following:

dig @192.168.0.1 abc.com. ns

If you get a response back, that's a good sign that Anycast is working! Hey, but how do I know it's really working? How do I know which server I received a response from? There are two possible servers that could provide the answer. Recall earlier we recommended the use of the hostname and server-id directives in the named.conf of the two DNS servers. This is why. To identify which server is currently providing you answers, you can perform the following dig command:

dig @192.168.0.1 id.server txt chaos
; <<>> DiG 9.6.0-P1 <<>> @192.168.0.1 id.server txt chaos
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 71
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;id.server.                     CH      TXT

;; ANSWER SECTION:
id.server.              0       CH      TXT     "A"

;; AUTHORITY SECTION:
id.server.              0       CH      NS      id.server.

;; Query time: 22 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Sat May 02 13:20:19 2009
;; MSG SIZE  rcvd: 55

The output of the above command shows that we are indeed receiving responses from Server A. Alternatively, you can also query the name server for its hostname TXT record in the CHAOS class.

dig @192.168.0.1 hostname.bind txt chaos
; <<>> DiG 9.6.0-P1 <<>> @192.168.0.1 hostname.bind txt chaos
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1191
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;hostname.bind.                 CH      TXT

;; ANSWER SECTION:
hostname.bind.          0       CH      TXT     "A"

;; AUTHORITY SECTION:
hostname.bind.          0       CH      NS      hostname.bind.

;; Query time: 15 msec
;; SERVER: 192.168.0.1#53(192.168.0.1)
;; WHEN: Sat May 02 13:04:46 2009
;; MSG SIZE  rcvd: 61

The output of this command shows that Server A responded again.

Testing Anycast Failover Using Static Routes

To test the fault tolerance of Anycast DNS, shutdown the name service on Server A and repeat the command. You will notice that there is a noticeable delay. With Anycast, isn't the failover from a server failure supposed to be near instantaneous and not noticeable to the user? Yes it should, but remember, we are using static routes. This is one of the key requirements of Anycast DNS. When the server and/or service fails, the routes to the Anycast VIP MUST be removed so that query traffic is deflected elsewhere to other operable servers. This is the single biggest drawback of using static routing to create our Anycast DNS environment. If you manually remove the route from the router that is upstream from server A, R1, you will see that your queries start responding again, and if you query the server-id you will see that the queries responses are from Server B.

Conclusion

In final, while Anycast functions using static routes, it is far from optimal. The drawbacks of using static routes for Anycast DNS are:

  • Maintaining static routing in larger environments is difficult to manage - the more servers and networks the more unwieldy static routing maintenance becomes.
  • Static Routing requires a manual or scripted configuration change - there is no automatic trigger to remove the routes from the network when a server or service failure occurs.

For these reasons, static routing is not a recommended method of building an Anycast DNS environment. In the next article, we use RIP version 2 as our IGP for originating our Anycast routes.

Series

DNS Anycast using static routes
DNS Anycast using RIP
DNS Anycast using RIP (cont)
DNS Anycast using OSPF (basic)
DNS Anycast using OSPF (advanced)
DNS Anycast using BGP

Next Post Previous Post