I ran into an interesting situation while helping a colleague build out a PaaS prototype a few weeks back.
The problem is: Server A has to get to Server B by using the DNS name PaaS.Prototype.com. He goes out and asks the DNS servers (internal) what the IP address is. There are no “internal” DNS zones put together for the prototype DNS name (only the local internal a record exists for PaaS.Prototype.local that resolves to the real internal IP of 192.168.52.21). So the DNS server reaches out to external DNS servers to resolve the name. The external DNS servers hand back an IP that is the Public outside IP address of the Prototype server (say, 22.214.171.124).
Since Server A now needs to target Server B on its Public NAT IP instead of its real inside IP, you run into an issue where the ASA has to try to hairpin the traffic. Instead of creating a (inside,inside) NAT to fix this solution (potentially causing other traffic issues) or updating the hosts file on Server A, there is a much more elegant method.
The Solution is DNS Doctoring on the ASA. What happens is Host A makes a DNS request for PaaS.Prototype.com (1) and the DNS server replies (2) with the 126.96.36.199 external Public IP address. The Cisco ASA inspects this DNS packet, notices it is coming from a request on the “inside” interface, and returning from the “management” interface, so it edits (3) the DNS packet to match the NAT statement below:
nat (inside,management) source static SERVER_B-PRIV SERVER_B-PUB dns
You also need DNS inspect turned on in the global policy.
In this statement, SERVER_B-PRIV is equal to the real IP 192.168.52.21, while SERVER_B-PUB is equal to the public IP 188.8.131.52, defined by network objects (ASA code 8.3+).
After Server A gets the correct internal IP of Server B, they are able to communicate with each other (4), while hosts on the internet are still able to communicate on the Public NAT IP with Server B.