Background
I've been stuggling to get a redirection working via iptables - a combination of restrictive capabilities of the s/w versions on DD-WRT and (more likely) my shoddy script.
We have a very limited bandwidth out to the internet on the network in question, and so I've deployed a number of measures to make utilisation more efficient e.g. ad blocking & replacement technology, traffic filtering, QoS prioritisation
I have the ISP-supplied router as the outer router, and an inner router running WiFi, LANs & VPN out to the internet.
Specific Problem
Among the list of enhancements is DNS caching on a dedicated server node, and redirection of all DNS requests to this server. Most of this is done via network settings in the dhcp servers, but some mobile & desktop apps are overriding this.
I use DNS upstream servers as targets from the LAN DNS server which I know are trustworthy. The inner router has a firewall script which is designed to apply a vpn killswitch and allow sticky IP's access outside of the VPN / straight out via our ISP (thanks a bunch Netflix).
However I'm struggling to get the DNS traffic redirection working on DD-WRT - I tested it on a combination of servers and desktops using dig and tcpdump, simulating a request being made to server A, redirected to server B, and the client getting a DNS response accordingly. That appeared to work as expected, but when I applied the same configuration to the inner router it has no effect. I can't see any traffic arriving at the DNS server when I fire a request out to a public resolver e.g. Cloudflare.
In fact the request is still blocked.
lanDns="dns server IP"
iptables -I FORWARD -s ! $lanDns -p tcp --dport 53 -j ACCEPT
iptables -I FORWARD -s ! $lanDns -p udp --dport 53 -j ACCEPT
iptables -t nat -A PREROUTING -s ! $lanDns -p tcp --dport 53 -j DNAT --to $lanDns:53
iptables -t nat -A PREROUTING -s ! $lanDns -p udp --dport 53 -j DNAT --to $lanDns:53
iptables -I FORWARD -s ! $lanDns -p tcp --dport 5353 -j ACCEPT
iptables -I FORWARD -s ! $lanDns -p udp --dport 5353 -j ACCEPT
iptables -t nat -A PREROUTING -s ! $lanDns -p tcp --dport 5353 -j DNAT --to $lanDns:53
iptables -t nat -A PREROUTING -s ! $lanDns -p udp --dport 5353 -j DNAT --to $lanDns:53
# secure DNS - TODO letsencrypt certificate for <servername>
iptables -t nat -A PREROUTING -s ! $lanDns -p tcp --dport 853 -j DNAT --to $lanDns:853
# allow direct DNS traffic from the LAN DNS server, don't need to drop as well as this will only interfere
iptables -A FORWARD -p tcp --dport 53 -s $lanDns -j ACCEPT
iptables -A FORWARD -p udp --dport 53 -s $lanDns -j ACCEPT
iptables output looks ok, but what am I missing? Is it as simple as ordering or just my poor iptables usage? :)
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:53 to:[DNS server ip]
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:53 to:[DNS server ip]
DNAT tcp -- ![DNS server ip] 0.0.0.0/0 tcp dpt:53 to:[DNS server ip]:53
DNAT udp -- ![DNS server ip] 0.0.0.0/0 udp dpt:53 to:[DNS server ip]:53
DNAT tcp -- ![DNS server ip] 0.0.0.0/0 tcp dpt:5353 to:[DNS server ip]:53
DNAT udp -- ![DNS server ip] 0.0.0.0/0 udp dpt:5353 to:[DNS server ip]:53
iptables version on DD-WRT (Kong Ac): 1.3.7