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)\BIND\etc";
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. 🙂