So here is the scenario. You have a private network behind a NAT router. The private network has servers that have two network interfaces. One with private ip's and one with public ip's. Some servers just have ports being forwarded from the NAT router to one interface on servers with a private inteface. Now these public ip's have DNS names attached to them. They have DNS names on the internal network. The zones are served out by the internal DNS servers with internal ip's. They also have DNS names on the external network. These DNS names have have zones that are served by an external DNS server on a public address that we have no control over.
When a user on the internal network makes a request to one of the internal DNS servers they do the zone lookup for the domain requested. If they don't own that zone they forward the request to the external upstream DNS servers for an answer. That answer comes back with the public ip that server. So the person who made the request makes a connection to the server using it's public ip address. Everything will work perfectly fine. Problem is the same service is is running on the internal ip of the same server they are trying to contact. Contacting it internally it's like 2 or 3 hops over the network. Contacting the server with the external ip the hops go up to like double or triple that. How inefficient and slow.
So to fix this all we really want to do is tell the internal DNS servers that if they recieve any queries for specific external names respond with the internal ip addresses of those servers and let any other query for those zones through. Easier said than done. DNS is a bit strict about zones. You either own the whole zone or you don't. So if we put that zone in our internal DNS server we would have to know all the ip's for that zone so any name looked up by internal clients would work correctly. We only know the names for the servers names we have in the zone. You can't just put part of a zone in a dns server and tell the DNS daemon to forward the rest of the queries. That is as far as I know you can't. You either forward all the queries on zones you don't have or give answers to queries on zones you do control.
The hack to work around this is not pretty but it works great. I downloaded source for the suite of programs called Dsniff created by Dug Song. This is a great package for evaluating the security of your network. Anyway there is a program in there called dnsspoof. It will listen on your network interface and rewrite and respond to DNS queries coming into that interface. You list the host names and matching ip's in a file and give it to dnsspoof. If a query comes in with that name it responds with the ip you gave in the file.
So you just give it a list of your external names your servers are known by and the internal ip that same server is known by. Run it on your internal (caching) DNS servers and they will respond with the internal ip anytime they specified external name is queried. Any other queries not on the dnsspoof list is ignored by it. The query then reaches the actual DNS service and it is forwarded upstream for the name lookup. The external ip address is returned like usual.
The only problem I found with this is the program rsh does not like when the reverse and forward lookup hostnames don't match. So I had to edit the source of dnsspoof to disable reverse DNS lookups (PTR records). Since I really only needed forward (A record) lookups anyway this was not a big deal.
The results are fantastic. Traffic that used to go all the way out of the network then come back in is now staying local. Bandwidth to the outside interface has dropped by a large margin. Users can access the local services that have public and private addresses at gigabit speeds instead of the speeds of the external networks.