chrooted bind9 with geodns under debian wheezy

at work we’ll soon make use of dns-based geo load balancing to have users in americas / asia ‘talk’ with north am site and rest of the world – with the european site. we preferred to avoid modifying the client application so the dns based solution seemed reasonable. below – quick overview of the setup under debian.

install bind:

apt-get install bind9

as described in :

  • stop bind
    /etc/init.d/bind9 stop
  • in /etc/default/bind9 add:
    OPTIONS="-u bind -t /var/bind9/chroot"
  • create needed directories / inodes, move configs and create links, adjust permissions:
    mkdir -p /var/bind9/chroot/{etc,dev,var/cache/bind,var/run/named}
    mknod /var/bind9/chroot/dev/null c 1 3
    mknod /var/bind9/chroot/dev/random c 1 8
    chmod 660 /var/bind9/chroot/dev/{null,random}
    mv /etc/bind /var/bind9/chroot/etc
    ln -s /var/bind9/chroot/etc/bind /etc/bind 
    chown -R bind:bind /etc/bind/*
    chmod 775 /var/bind9/chroot/var/{cache/bind,run/named}
    chgrp bind /var/bind9/chroot/var/{cache/bind,run/named}
  • configure syslog:
    echo "\$AddUnixListenSocket /var/bind9/chroot/dev/log" > /etc/rsyslog.d/bind-chroot.conf
  • restart rsyslogd, bind:
    /etc/init.d/rsyslog restart; /etc/init.d/bind9 start

debian’s bind9 supports geoip out of the box – it’s already patched. normally the geoip database is kept in debian under /usr/share/GeoIP/GeoIP.dat ; since bind is chrooted we need to copy that file:

apt-get install geoip-database
mkdir -p /var/bind9/chroot/usr/share/GeoIP/
cp /usr/share/GeoIP/* /var/bind9/chroot/usr/share/GeoIP/

this database should be updated periodically, in both locations.

to make use of the ‘split view’ configuration where we define different responses depending on the country from which dns request has arrive i:

  • edit /var/bind9/chroot/etc/bind/named.conf and comment out the line ‘include “/etc/bind/named.conf.default-zones”;’
  • add new content in named.conf.local:
    view "sweden" {
            match-clients { country_SE; };
            allow-recursion { recurseallow_acl; };
            zone "" {
                    type master;
                    file "/etc/bind/zones/";
                    notify no;
            include "/etc/bind/otherZones.conf";
            include "/etc/bind/named.conf.default-zones";
    view "other" {
            match-clients { any; };
            allow-recursion { recurseallow_acl; };
            zone "" {
                    type master;
                    file "/etc/bind/zones/";
                    notify no;
            include "/etc/bind/otherZones.conf";
            include "/etc/bind/named.conf.default-zones";

    this might look convoluted but makes sense. to avoid duplication zones that do not require geo-dns are defined in otherZones.conf and only the part that needs to be geo-dependent goes to /var/bind9/chroot/etc/bind/ and /var/bind9/chroot/etc/bind/

    for me it even made sense to have main records and use CNAME to point to and and have only the zone configured with 2 different views depending on the geo-location of the dns resolver sending us the query.

secondary dns server[s] will not be able to use ordinary zone transfer mechanism for the zones that provide different responses based on geoip lookup. configure it as if it was a master and copy the zone files/configs manually whenever they get changed.

2013-12-08 i’ve been using this setup in the production for the last few weeks and all seems fine. i’m getting some percent of ‘incorrect’ assignments – especially users from the UK end up on the north american servers instead of european ones [ google dns users? ] – but it’s not grave. having a dns server that understands edns-client-subnet would be nice, but it seems quite cumbersome – i’d have to notify operators like google, easydns and others that i can ‘understand’ this record correctly – this does not seem scalable. related question on the serverfault.

helpful materials:

One thought on “chrooted bind9 with geodns under debian wheezy

Leave a Reply

Your email address will not be published. Required fields are marked *


(Spamcheck Enabled)