While working on some DNS and web server configurations today, I discovered a bug (in my opinion) in he way that NAT is implemented in the Cisco 678 DSL router. From what I’ve read, it occurs in the 675 as well. I suspect that this bug would be found in all CBOS based devices.
My Cisco 678 is connected to a Linux server which provides firewall, proxy, DNS, DHCP and a bunch of other services to my internal network. There’s not much more than DNS which is visible to the outside world. I found that DNS requests for A records (address lookups) from the outside world coming through the Cisco 678 to my DNS server would always get the IP address of my DSL link and a TTL of 0. Other record types seemed unaffected (though, I never tested most RR types).
After some fiddling around with my DNS server, I realized that it was returning the right information. In other words, the data was being alteredchanged in transit. Since I am using NAT on the Cisco 678, I decided to look into the possibility that something was wrong there.
It turns out that the CBOS NAT implementation does not just translate IP addresses in the IP header, but will look at the entire payload of an IP packet, substituting it’s IP everywhere. Since the format of the IP address in a DNS response is the same as what is found in a nIP header, they were being translated on the way to the outside of my network.
A quick Google Search yielded a workaround, which I’ll describe here.
The Cisco 67x CBOS NAT implementation will not translate payload addresses if the packets are not on port 53. So, simple change the port to something else (like 5300) in a NAT entry, and your DNS lookup responses won’t be messed with. The syntax of the CBOS command to do just that is:
cbos#set nat entry add 192.0.2.254 5300 0.0.0.0 53 udp
In the workaround I found online, they never address the use of DNS over TCP. It doesn’t happen much, but it is possible for DNS requests to come over TCP rather than UDP (this usually only occurs for zone transfers and when a request produces such a large response that a single UDP datagram is too small to carry the answer back).So, I also ran:
cbos#set nat entry add 192.0.2.254 5300 0.0.0.0 53 tcp
After implementing the workaround, it didn’t work. I deleted the NAT entries from my Cisco 678, re-created them, wrote the memory, rebooted it at which point it started working for me. During this process, I also kept tcpdump monitoring for the traffic I wanted to see between the DSL router and my firewall box.