I have a local DNS server running on my Linux router. I have it configured to only allow requests from my LAN ( I also want the server to be able to query itself for DNS. To that end I did allow as a source as well.

The problem is that every query the box makes to itself has its source IP set to my external IP. I confirmed this with tcpdump; when the server queries itself at, a packet arrives on interface lo with the destination IP but the source IP is that of my ISP.

Using dig -b does not help. The same exact effect occurs.

This means that unless I explicitly add the IP of my ISP to the allowed IPs, DNS lookup will not work locally. Since my IP can be dynamic, this actually means adding an entire range of IPs to the DNS server. This is obviously not a problem on machines on my LAN as they are setting their source IPs properly. The problem is specific to local queries on the server to itself.

I want to be able to tell the server to use an explicit source IP address (not just a source interface necessarily) to make queries to itself. Can this be done?

  • It it BIND? Please add to the post, version too. – Rui F Ribeiro Nov 6 '16 at 21:17
  • 1
    You should be able to fix the underlying issue so that it works in the general case and not just for bind. Can you add your POSTROUTING rules for iptables to the question? – roaima Nov 6 '16 at 23:09

For setting a source query other than the primary interface of the server, you use the query-sourcein BIND options.

The setup is such, that only queries initiated by the server/daemon are going out with that IP.

Beware that if it is an internal/RFC 1918 private address, you will have to NAT it when going to the outside.

As per my server, in /etc/bind/named.conf.options:

options {
    query-source address X.X.X.X;

where X.X.X.X is your IP address.

Another option is using a dynamic DNS service, register your IP address there, and do the rules based on the DNS name. Granted, there is the small inconvenience of having to do a script to be placed as a DHCP hook to reapply the rules whenever the IP address changes.


@roaima's comment led me in the right direction.

My iptables POSTROUTING rule looks like this:

-t nat -A POSTROUTING -s -j SNAT --to <my public IP>

Just adding a rule above this to exclude the router's own IP fixed everything:

-t nat -I POSTROUTING 1 -s -j ACCEPT

@roaima if you want to post as an answer I'll give you an upvote.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.