Location aware Bind
I have a client who needs to host graphic content closer to their audience, partly to speed things up for their audience but also to allow them to save some money on bandwidth bills by spreading it out to cheaper hosts.
The obvious answer is to just use Akamai, but unless you have a huge amount of bandwidth it does not really make financial sense. So I proposed we get a few UML / Virtual Machines at ISPs and host the images there. Typically we'd just round-robin the A record but this doesn't give us any geo-awareness.
I googled a bit and came across a guy who made a patch to bind 9.2.4. He bascially hooks the Maxmind GeoIP C Library into ISC Bind. As it turns out thats exactly the version RedHat uses in their Enterprise distribution so it seemed like a winner.
The basic idea is to setup a view that matches countries rather than just IP Blocks as is the default supported scenario. A sample view:
view "us" {
match-clients { country_US; };
zone "geotest.devco.net" {
type master;
file "data/us-geotest.devco.net";
};
};
view "other" {
match-clients { any; };
zone "geotest.devco.net" {
type master;
file "data/other-geotest.devco.net";
};
};
The above will serve us-geotest.devco.net to visitors from the United States and everyone else will get other-geotest.devco.net. These 2 zone files are stock standard bind zone files, my sample just set a different A record in each.
To see this in action, first a query from my UK hosted machine:
% host geotest.devco.net geotest.devco.net has address 193.201.200.135
and now a query from the states:
% host geotest.devco.net geotest.devco.net has address 72.21.58.28
So to make a long story short, I've patched the stock RedHat Enterprise 4 bind RPM with the GeoDNS patch and am making the files available here, first I have the source files up if you want to look through them to ensure I didn't put any funny stuff in them:
The actual patch from GeoDNS - I had to modify the file names in the patch since the one from the source site is made to patch from outside the bind source dir while RPM will change directory into the source directory before running the patch.
Changes made to the RPM Spec file
Sample config - this gets placed in the standard documentation directory
I've build a full RPMs of this on a CentOS 4.3 machine, the files are:
bind-9.2.4-2geodns.i386.rpm
bind-libs-9.2.4-2geodns.i386.rpm
bind-utils-9.2.4-2geodns.i386.rpm
bind-devel-9.2.4-2geodns.i386.rpm
bind-chroot-9.2.4-2geodns.i386.rpm
and finally a Source RPM that you can use to build this all on your own machine:
bind-9.2.4-2geodns.src.rpm
Before you can install these you'll need to get GeoIP on your machine, CentOS has an extras Yum repository that you can enable in /etc/yum.repos.d/CentOS-Base.repo. Once enabled you can install it with yum:
# yum install GeoIP GeoIP-data <snip> Running Transaction Installing: GeoIP ######################### [1/2] Installing: GeoIP-data ######################### [2/2] Installed: GeoIP.i386 0:1.3.14-2.c4 GeoIP-data.i386 0:20060501-2.c4
RedHat Enterprise has an extras CD, you can find GeoIP on there and install it using RPM.
The bind RPMs above should simply install on your standard CentOS/RedHat Enterprise box, be sure to remove all the old bind stuff especially bind-libs before installing these.


September 12th, 2007 - 01:25
looking for a way to make this work with BIND 9.4.1-P1 i have the patches but I am running into problems how hard would it be to get RPMS for that version of BIND for Redhat 4ES
September 19th, 2007 - 04:50
Chroot bind+GeoIP will not work correctly unless copy the GeoIP.dat into /var/named/chroot/var/lib/GeoIP
June 2nd, 2009 - 09:20
Not intending to ‘blow my own trumpet’ here, but I figured out a way of making BIND geo-aware without having to patch the source code.
See: http://phix.me/geodns/
I like this method better as it allows for upgrades to BIND as and when ISC release new versions, without having to try and re-fit source code patches in!
Hope you find this useful!
July 24th, 2009 - 06:43
I appreciate Mark’s method presented at http://phix.me/geodns/, it is very simple by much more efficient.
No need to install GeoIP and GeoIP-data modules, neither patched bind.
But I don’t know how much amount of memory does the include file take at the first loading of bind ?
August 8th, 2009 - 00:23
I investigated the memory usage with my include file method and it seems that the footprint of the BIND process only increases by a few megabytes at most (16Mb on my setup). You must remember that BIND will use its own efficient data-structures in memory when reading and loading ACL definitions from config files, and I presume these data-structures have been designed with speed and efficiency being a top priority, with a trade off against optimum memory usage. Certainly, I have the complete GeoIP.acl include file loaded on 3 production name servers and there is absolutely no noticeable slow down in the speed at which DNS queries are answered. Given the amount of RAM modern servers have these days, 16Mb is really nothing to worry about.
December 28th, 2009 - 14:57
I have installed the rpms and followed all steps. The bind server is working fine but it does not seem to read any of the country_country it serves the default match-clients { any; }; . Please let me know if there is anything more to check on. GeoIp is installed and it gives correct details when using the tool geoiplookup.
December 28th, 2009 - 16:31
That should be all there is to it. I use ruby-pdns.googlecode.com now instead of the Bind solution.
December 29th, 2009 - 09:04
i get a error domain.com not found: 5(REFUSED)