Since I enabled comments in this blog, I finally needed to configure a split DNS for my network.
There are various reasons why one needs a split DNS and as it's
usually pointed out, the reasons are usually non-technical. In my
case the reasons are technical: I have a NAT in my local network
that allows me to host this website locally. What causes problems
is that the domain name ressukka.net points to the
external IP address and that doesn't work from the inside. So split
DNS it is.
There are various ways of building a split DNS, one can use the views feature in bind9 or you can set up 2 separate DNS servers that provide different information (and redirect your local resolver to use the internal server). The latter is more secure if the internal zone is sensitive.
I decided to use a hybrid solution. I already knew that PowerDNS Recursor was capable of serving authoritative zones (think pre-cached) so I decided to leverage on that. Setting this up turned out to be simpler than I expected.
First I made a copy of the existing zone and edited it to fit my
needs. I changed the IP address of ressukka.net to
point to the IP address on the local network. I also adjusted some
other entries that pointed to the local network.
Next I modified bind to listen on the external IP address. This
can be accomplished by adding a listen-on { 1.2.3.4;
}; to the options in the configuration. I also disabled the
resolver by adding recursion no;, this forces the bind
to work as authoritative only.
Then I installed the PowerDNS Recursor
(pdns-recursor package in debian) and configured it to
listen on the internal address only
(local-address=10.0.0.1) and added the pre-cached zone
to the configuration with
auth-zones=ressukka.net=/path/to/internal-zone
Now, after restarting both daemons, I had a working split DNS with minimal configuration. I was also able to change the external DNS to authoritative only mode, which is a good idea in any case.
iptables -t nat -A POSTROUTING -d internal_network -j SNAT --to-source internal_ip_of_the_NAT_boxIt would be a lot easier if I could just do that and configure the firewall to transparently manage the connections. But due to the wonderful world that is IPv4 I can't.
The firewall I was configuring doesn't actually have the public IP address either. This is again due to technical reasons. If I wanted to configure the firewall to transparently route the traffic back it would first travel through my firewall, then over a slow link to another firewall that would do the NAT then come back the slow link and pass my firewall landing to the host in question. Then the response would do the same trip just to land back to my network. That doesn't sound like too much fun does it?
The only solution I was able to come up was to have something similar to Cisco ASA and do a DNS rewrite. This would require me to move the dns to the internal network, but at least I would have a single DNS server.
I use dnsmasq to achieve something similar.
dnsmasq is a recursor+. I can just specify the hostnames that are different, so I don't have to override a whole zone.