DNS highjacking without masquerading every query? Pihole

My two DNS servers are running on 10.1.101.2 and 10.1.101.3.

I would like all outgoing traffic on port 53 to be rerouted to 10.1.101.2, if it doesn't originate from 10.1.101.2 or 10.1.101.3.

After googling I came up with these rules:

config redirect                                 
        option dest 'SafeZone'     
        option target 'DNAT'                    
        option src 'SafeZone'                   
        option ipset '!piholes'                 
        option src_dport '53'                   
        option dest_ip '10.1.101.2'             
        option dest_port '53'                   
        option name 'ForwardDNSToPiholeSafeZone'
                                               
config redirect                                 
        option dest 'SafeZone'         
        option target 'DNAT'                    
        option src 'LessSafe'                   
        option ipset '!piholes'                 
        option src_dport '53'                   
        option dest_ip '10.1.101.2'             
        option dest_port '53'                   
        option name 'ForwardDNSToPiholeLessSafe'
                                               
config redirect                                
        option dest 'SafeZone'                 
        option target 'DNAT'                   
        option name 'ForwardDNSToPiholeDienste'
        option src 'Dienste'       
        option ipset '!piholes'        
        option src_dport '53'          
        option dest_ip '10.1.101.2'    
        option dest_port '53'          
                                       
config nat                             
        option name 'DNSRerouteRewrite'
        list proto 'all'           
        option src '*'             
        option dest_ip '10.1.101.2'
        option target 'MASQUERADE'

What is happening here is that for every one of my zones I created a port foward that if a connection is going out on port 53 and isn't going to my dns servers (ipset piholes = 10.1.101.2, 10.1.101.3 it is rerouted to 10.1.101.2. I also created a NAT rule that rewrites (masquerades) the source IP so that to the client it looks like the server that was supposed to answer actually answered.

This works ok so far, the issue is though that ALL dns traffic is now masqueraded, which means that the pihole-GUI can't show which client actually sent off a query.

Is there any way to only masquerade querys that were redirected?

I am also open to using pure nftables, since I had iptables rules that worked flawlessly, but I have tried getting nftables to work for over three hours now and I just couldn't get it to play ball.

Thanks!

Are you sending the Pi Hole IPs via DHCP Option 6, so clients go directly to the Pi Hole if they respect the DHCP-served DNS servers.

Then only the clients with hard-coded DNS would be subjected to the redirect rules.

uci add_list dhcp.lan.dhcp_option='6,10.1.101.2,10.1.101.3'
uci commit dhcp
/etc/init.d/dnsmasq restart

Alternatively, Pi-Hole can receive the client MAC and IP from requests forwarded by dnsmasq if you add some extra native dnsmasq options to /etc/dnsmasq.conf (don't leave these active if you forward to external DNS servers, however):

add-mac
add-subnet=32,128

Then you just need to tell dnsmasq to forward to your Pi-Hole, instead of an internet DNS server:

uci -q delete dhcp.@dnsmasq[0].server
uci add_list dhcp.@dnsmasq[0].server="10.1.101.2"
uci add_list dhcp.@dnsmasq[0].server="10.1.101.3"
uci commit dhcp
/etc/init.d/dnsmasq restart

Then update your redirect rules to only forward to the router (remove the destination IP from the rule). "Bad" clients will get intercepted to dnsmasq, and dnsmasq will forward to Pi-Hole while sending the original client IP and MAC address to the Pi-Hole for client identification in the Pi-Hole logs.

2 Likes

DNS hijacking can work without masquerading by moving the DNS server to a separate subnet.

1 Like

Yes, I am using option 6. Without the nat rule I can see all client names in pihole, but as soon as I enable the nat rule I only see "Openwrt.lan". Isn't that to be expected with the rule? The way I read it it masquerade all traffic, regardless of who send it.

I'll have a look at dnsmasq, thank you! Just to be sure: those options should be set on the router, right?

Thank you. I am already running a bunch of vlans. Could I set up one more for the piholes or would that be overkill?

You can limit masquerading to a specific subnet with your DNS server.
But moving it to a separate subnet makes the masquerading rule redundant.

It only needs to be in a separate routed subnet.
Whether it is another VLAN or not is irrelevant.

I tried it with the alias and somehow f'ed up my config. I then read that adding another subnet on the interface is almost functionally the same and that worked.
image

Thank you very much for your help!

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.