Redirecting DNS port to a specific DNS server
I use a ubuntu server as a router for my users on a NAT network. I want to force all users to use a local dns server setup on the network. Even if they use a public DNS server in their client machines, the DNS port should be redirected (DNAT) to my local DNS server. This is what I have come up with:
iptables -t nat -A PREROUTING -i eth5 -p udp --dport 53 -j DNAT --to 192.168.1.1:53
iptables -A FORWARD -d 192.168.1.1 -i eth5 -p udp --dport 53 -j ACCEPT
The interface facing NAT network is eth5
. The above rules were not working for me. Are there any better solutions?
EDIT 1: My aim is to implement Opndns filter to prevent bittorrent traffic on the network. The filter is working quite well at present, and the users get the local dns server because they use DHCP. But I fear that they might discover a work around, like, specifying ip address and dns server ip's manually.
EDIT 2: The following code implements the feature on tomato firmware:
if (nvram_match("dns_intcpt", "1")) {
ipt_write("-A PREROUTING -p udp -s %s/%s ! -d %s/%s --dport 53 -j DNAT --to-destination %s\n",
lanaddr, lanmask,
lanaddr, lanmask,
lanaddr);
}
Here is more about it.
Solution 1:
Are there any better solutions?
Yes - not doing it at all.
Messing with normal DNS resolution is almost never the right answer, whatever the problem is that you're trying to solve.
EDIT re: your update. You are inappropriately trying to use technology to solve a policy problem. Don't.
Solution 2:
It's not working because the reply from your DNS server is bypassing the firewall. The clients will then (correctly) drop those responses as they don't match what was sent out.
You need to add another rule to your POSTROUTING table to SNAT the packets headed for the DNS server to the router's IP.
Alternatively, putting the DNS server on a separate network would solve the problem as the responses would be forced back through the router.
Solution 3:
Why not just drop DNS traffic to any external DNS server? Those who explicitly specify an external server will simply notice that that isn't working.