openWRT - DNS Traffic Hijack

openWRT - DNS Traffic Hijack

We previously have deployed a pihole to serve DNS queries to our network and block undesired queries for ads and tracking, however, any host can manually define its DNS server and reach the internet, therefore, bypassing our pihole.

We will deploy a set of iptables rules to capture all traffic reaching port 53 and forward it to our pihole. Also, preserving the host IP the traffic is originating and allowing the use of the advanced groupings and graphing options that pihole has.


Let's create a new chain in the nat table to forward our DNS traffic to.

root@R1 /root > iptables -t nat -N dnshijack

-t This option specifies the packet matching table.

-N Create a new user-defined chain by the given name. There must be no target of that name already.


In the line below is just used for logging and it is recommended to be used only for troubleshooting hence we leave will leave it disabled once the rules are tested. Otherwise, your logs will get clogged with  DNS entries.

root@R1 /root > iptables -t nat -I dnshijack -j LOG --log-prefix "dnshijackipv4 "

-I Insert one or more rules in the selected chain as the given rule number.

-j, --jump This specifies the target of the rule; i.e., what to do if the packet matches it.

LOG Turn on kernel logging of matching packets. When this option is set for a rule, the Linux kernel will print some information on all matching packets (like most IP header fields) via the kernel log.


With this line, we are redirecting the traffic to our pihole and changing only the destination and keeping the source which is very important for graphing and traffic shaping.

root@R1 /root > iptables -t nat -A dnshijack -j DNAT --to-destination 192.168.6.10

-A Append one or more rules to the end of the selected chain.

DNAT This target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains. It specifies that the destination address of the packet should be modified (and all future packets in this connection will also be mangled), and rules should cease being examined.

--to-destination which can specify a single new destination IP address, an inclusive range of IP addresses, and optionally, a port range (which is only valid if the rule also specifies -p tcp or -p udp). If no port range is specified, then the destination port will never be modified.


And finally, we are capturing all the traffic for the VLAN20.

root@R1 /root > iptables -t nat -A prerouting_vlan20_rule -p udp --dport 53 -j dnshijack
root@R1 /root > iptables -t nat -A prerouting_vlan20_rule -p tcp --dport 53 -j dnshijack

We just need to repeat the two lines above changing the VLAN we want to forward the traffic.

-p The protocol of the rule or of the packet to check.

--dport Destination port or port range specification.


The changes made into our  OpenWRT are still temporary and for them to be permanent they need to be added to the firewall startup script.

In LUCI navigate to Network > Firewall > Custom Rules and add them as below.

######## DNS TRAFFIC HIJACK ########

# Creating the DNS Hijack Chain
iptables -t nat -N dnshijack

# LOG the queries, leave disabled and just enable for troubleshoting
#iptables -t nat -I dnshijack -j LOG --log-prefix "dnshijackipv4 "

# Forwarding the traffic to pihole
iptables -t nat -A dnshijack -j DNAT --to-destination 192.168.6.10

# VLAN5 (Routers) - Traffic forwarding
iptables -t nat -A prerouting_vlan5_rule -p udp --dport 53 -j dnshijack
iptables -t nat -A prerouting_vlan5_rule -p tcp --dport 53 -j dnshijack

# VLAN10 (Servers) - Traffic forwarding
iptables -t nat -A prerouting_vlan10_rule -p udp --dport 53 -j dnshijack
iptables -t nat -A prerouting_vlan10_rule -p tcp --dport 53 -j dnshijack

# VLAN20 (Personal) - Traffic forwarding
iptables -t nat -A prerouting_vlan20_rule -p udp --dport 53 -j dnshijack
iptables -t nat -A prerouting_vlan20_rule -p tcp --dport 53 -j dnshijack

# VLAN30 (Games,TV & IoT) - Traffic forwarding
iptables -t nat -A prerouting_vlan30_rule -p udp --dport 53 -j dnshijack
iptables -t nat -A prerouting_vlan30_rule -p tcp --dport 53 -j dnshijack

# VLAN50 (Guest) - Traffic forwarding
iptables -t nat -A prerouting_vlan50_rule -p udp --dport 53 -j dnshijack
iptables -t nat -A prerouting_vlan50_rule -p tcp --dport 53 -j dnshijack

####################################

Resources

42.9. IPTables
iptables(8) - Linux man page
Iptables is used to set up, maintain, and inspect the tables of IP packet filter rules in the Linux kernel. Several different tables may be defined. Each ...
Block and Redirect DNS to PiHole
You are right! I tried the masquerade rules (initially I thought you were saying about the wan postrouting masquerade) and now replies back to clients seem to come from the legitimate nameserver. Regarding IPv6 why are you trying to masquerade on the wan? Any host contacting some other host on the …