Setting up a Forwarding DNS Server (or DNS Proxy) with ISC BIND

When you are connected to VPN, all DNS queries in your system often goes to the DNS server that your company runs. This is inefficient because most DNS queries can be resolved by faster public DNS servers such as Google Public DNS. If only the domain names related with your company are resolved by the private name servers, you won’t have a problem browsing public web sites due to an unstable VPN connection.
To address this issue, you can install a forwarding DNS server (a.k.a. proxy DNS server) in your machine or local area network. There are dedicated DNS proxy servers such as pdnsd and dnsmasq, but I recommend to use BIND because it was more reliable than others from my experience. Unlike the first impression, BIND is very easy to configure into a forwarding DNS server. Moreover, BIND works fine on both Windows and Linux.
First, let’s say we want to forward all DNS queries to Google Public DNS (8.8.8.8 and 8.8.4.4):

# /etc/named.conf
options {
    directory "/var/named";

    # Hide version string for security
    version "not currently available";

    # Listen to the loopback device only
    listen-on { 127.0.0.1; };
    listen-on-v6 { none; }; # No IPv6

    # Do not query from the specified source port range
    # (Adjust depending your firewall configuration)
    use-v4-udp-ports { range 32768 65535; };
    use-v6-udp-ports { range 32768 65535; };

    # Forward all DNS queries to the Google Public DNS.
    forwarders { 8.8.8.8; 8.8.4.4; };
    forward only;

    # Expire negative answer ASAP.
    # i.e. Do not cache DNS query failure.
    max-ncache-ttl 3; # 3 seconds

    # Disable non-relevant operations
    allow-transfer { none; };
    allow-update-forwarding { none; };
    allow-notify { none; };
};
# Disable the control channel.
controls { };

If you are connected to your company VPN and you want to forward some DNS queries for certain domains to different name servers, you can override the default settings by adding the zones for your company domains:

... (continuing from the named.conf above) ...

zone "abc.com" in {
    # matches:
    #     abc.com
    #     intranet.abc.com
    type forward;
    forwarders { 192.168.1.1; 192.168.2.2; };
};

zone "private.def.com" in {
    # matches:
    #     private.def.com
    #     mail.private.def.com
    type forward;
    forwarders { 172.10.1.1; 172.10.2.2; };
};

If you don’t want to forward some subdomain of the overridden zones to the private DNS servers, you can insert another zone before the zone definitions above to override the override:

zone "www.abc.com" in {
    type forward;
    forwarders { 8.8.8.8; 8.8.4.4; };
}

zone "abc.com" in { ... }

Here’s my complete configuration. Please note that I replaced the domain names and the private DNS server addresses with bogus values.

options {
    # I am running BIND on Windows without a problem. :)
    directory "C:Program Files (x86)BINDetc";
    version "not currently available";

    listen-on { 127.0.0.1; };
    listen-on-v6 { none; };

    use-v4-udp-ports { range 32768 65535; };
    use-v6-udp-ports { range 32768 65535; };
    forwarders { 8.8.8.8; 8.8.4.4; };
    forward only;

    max-ncache-ttl 3;

    allow-transfer { none; };
    allow-update-forwarding { none; };
    allow-notify { none; };
};
controls { };

# We can't resolve the VPN server names with the private
# DNS servers before we join the VPN, so we should use
# the public DNS to initiate VPN connection successfully.
zone "vpn.abc.com" in {
    type forward;
    forwarders { 8.8.8.8; 8.8.4.4; };
};

# Our company has two top level domains: abc.com and def.com
zone "abc.com" in {
    type forward;
    forwarders { 172.10.1.1; 10.10.2.2; };
};

zone "def.com" in {
    type forward;
    forwarders { 172.10.1.1; 10.10.2.2; };
};

At last but not least, make sure to set the DNS settings in your operating system to point to the DNS server you’ve just configured (i.e. 127.0.0.1). In Linux, you should update /etc/resolv.conf or your NetworkManager settings. In Windows, you know what to do – mess with the Control Panel. 🙂

9 Comments Setting up a Forwarding DNS Server (or DNS Proxy) with ISC BIND

  1. Kesava Srinivas Vunnava

    First of all Nice article which demonstrates the simpler ways to configure the named.conf.

    I have a requirement where we need to configure the forwarder based on the Client who is sending me the request.

    Ex: LAN1 Clients will send me the DNS Request && Me; assuming the role of Forwarder ., need to forward the request to DNS1 & Similarly for LAN2 Clients ; need to forward to DNS2.

    Was this configurations can be achieved via bind DNS Package ???

    Reply
  2. you know who

    Pinky: What are we going to do tomorrow night Brain (aka Google)?
    Brain (aka Google): Try to take over the world.

    Using their DNS they’ll be able to mine data about sites that don’t even have their instrumentation (adwords, adsense, analytics). Just a bit unnerving.

    Reply
  3. Ned Dyakov

    Hey! Thanks.
    I have a question.
    Can I log every request to my dns proxy server at my local network. I want to have client – request and maybe having a timestamp will be nice.
    Best wishes,
    Ned

    Reply

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.