If you’re doing a NSLOOKUP for a DNS Name that resolves to your routers public IPv4 address you may find that the result returned from any external DNS server will resolve to your clients internal IP address. If you have an internal DNS server that is forwarding queries to an external DNS server then you may see the DNS servers IP address when querying.
Scenario: You have a server internally which you’re NATing from your outside interface on your Cisco router to an internal IP address. You run a dynamic DNS client to map WWW.YOURDOMAIN.COM to your public IP. Your clients on the LAN also use this router to get internet access using PAT/NAT Overload. You want to verify that the DNS entry has propagated to Google DNS so you perform an NSLOOKUP to 8.8.8.8 or 8.8.4.4
nslookup WWW.YOURDOMAIN.COM 8.8.8.8 Snslookup WWW.YOURDOMAIN.COM 8.8.8.8 Server: dns.google Address: 8.8.8.8 Non-authoritative answer: Name: WWW.YOURDOMAIN.COM Address: 192.168.0.10
But if you try an online DNS check tool like MX Toolbox it will return the correct result or if you get someone else to try for you to the same External DNS server they get the correct result.
Investigation: Lets confirm what we appear to be seeing. To do this we will capture the DNS queries for an external website (www.google.com) and one to an entry mapped to my external IP (testdns.kierandrain.com).
So we can see the reply to our query here and it has resolved www.google.com to 172.214.169.36 correctly. Next we’ll test for testdns.kierandrain.com which is currently mapped to the public IP of my Cisco router.
So we can see this time that 8.8.8.8 appears to have returned the IP address of the querying host. So why did 8.8.8.8 return the incorrect result and how did google know what the local IP address was to return that in the query? As far as 8.8.8.8 was concerned the request came from my public IP and my client was using NAT to contact 8.8.8.8.
Problem Statement: In short any internal queries where the results IP matches the routers outside interface are somehow modified to return the querying hosts IP address. The same issue doesn’t affect IPv6 traffic.
Root cause: You might suspect that this behavior of the external IP being mapped to an internal one looks supiciously like a NAT issue but since NAT only affects the Layer 3 and Layer 4 information on the packets and we see application layer changes then surely this couldn’t be the case. Could it?
The culprit here is a feature known as ALG – Application Layer Gateway. This isn’t specific to Cisco however it does come enabled on all Cisco routers. ALG is intended to support traffic flows where NAT is being performed by changing application layer data on a packet to reflect the changes performed by NAT. This can however cause problems like the scenario above and particularly for SIP and VoIP traffic where the changes can actually cause the packets to become malformed.
As there’s nothing in our router configuration to tell us this is enabled you will need to use the all command when tryting to view the configuration.
Router#show run all | i ip nat service ip nat service all-algs
As you can see all ALG services are currently enabled by default. To get a detailed view of the ALG subservices we can run the following command.
router(config)#ip nat service ? H225 H323-H225 protocol all-algs Enable all NAT ALGs dns DNS protocol dns-reset-tl Reset dns cname ttl value dns-v6 dns v6 packet processing ftp ftp protocol fullrange allocate all available port of 1024 to 65535 gatekeeper Gatekeeper protocol ipsec-esp ipsec esp packet processing options ldap LDAP protocol list Specify access list describing global addresses modify-in-progress Packet processing options when config is being modified and/or cleared msrpc MS-RPC protocol netbios-dgm NetBios datagram protocol netbios-ns NetBios name protocol netbios-ssn NetBios session protocol pptp PPTP protocol ras H323-RAS protocol rcmd RCMD protocol rtsp RTSP protocol sip SIP protocol skinny skinny protocol sunrpc SUNRPC protocol tftp TFTP protocol
Resolution: To resolve this issue we simply disable the NAT ALG service for DNS by issuing the No command for the service. Note we must do this for tcp and udp separately.
! Most modern IOS/IOSXE will disable the service using these commands ! Router(config)#no ip nat service dns tcp Router(config)#no ip nat service dns udp ! Some older IOS devices use the following format ! Router(config)#no ip nat service alg udp dns Router(config)#no ip nat service alg tcp dns
Now that this service is disabled the DNS lookups data will not be inspected/changed and so they will return the correct IP address for a client behind NAT.