Sending All DNS Traffic on LAN via PiHole

Ok so having got my guest wifi setup and all working time for the next little 'problem'

I've added a USB to ethernet adaptor as eth1 & configured it for a static IP of 192.168.1.254 with the intention being of issuing DHCP clients with an IP in the range 192.168.1.100-200 (as it does currently) , DNS of 192.168.1.2 (again as per current setup) but with a default gateway of 192.168.1.254

I already have masquerading setup to allow traffic from wlan0 & eth0 and if I configure my laptop statically for testing with

IP 192.168.1.10
DNS 192.168.1.2
DGW: 192.168.1.254

Everything works as expected.

So far so good as that means when I flip the DHCP config everything will still get out to the internet via my main router on 192.168.1.1 (which is set as the DGW for eth0/192.168.1.2)

SO my next challenge is intercepting all outbound DNS traffic and forcing it via the PiHole much the same as this post

I've added the Pre routing rules and from the laptop an nslookup without any IP specified works as expected via PiHole.

Nslookup using 192.168.1.1 also works as expected as that bounces it back to the PiHole anyways.

The problem comes when i try running nslookup against say 8.8.8.8

C:\Users\mike>nslookup news.bbc.co.uk 8.8.8.8
DNS request timed out.
    timeout was 2 seconds.
Server:  UnKnown
Address:  8.8.8.8

DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
*** Request to UnKnown timed-out

my expectation was that it would route transparently vi the Pihole

pi@Heimdall:~ $ sudo iptables -t nat -L --line-numbers
Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    DNAT       tcp  -- !Heimdall             anywhere             tcp dpt:domain to:192.168.1.2:53
2    DNAT       udp  -- !Heimdall             anywhere             udp dpt:domain to:192.168.1.2:53

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    MASQUERADE  all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination

NB1 have also tried it without adding :53 at the end of the destination but that made no difference

NB2 command used to load iptables was

iptables -t nat -A PREROUTING -i eth1 ! -s 192.168.1.2 -p tcp --dport 53 -j DNAT --to 192.168.1.2:53
iptables -t nat -A PREROUTING -i eth1 ! -s 192.168.1.2 -p udp --dport 53 -j DNAT --to 192.168.1.2:53

Just tried explictly routing traffic from .10 only and not specifying the interface but still getting the same nslookup error

pi@Heimdall:~ $ sudo iptables -t nat -A PREROUTING   -s 192.168.1.10  -p tcp --dport 53 -j DNAT --to-destination 192.168.1.2:53
pi@Heimdall:~ $ sudo iptables -t nat -A PREROUTING   -s 192.168.1.10  -p udp --dport 53 -j DNAT --to-destination 192.168.1.2:53
pi@Heimdall:~ $ sudo iptables -t nat -L --line-numbers
Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    DNAT       tcp  --  192.168.1.10         anywhere             tcp dpt:domain to:192.168.1.2:53
2    DNAT       udp  --  192.168.1.10         anywhere             udp dpt:domain to:192.168.1.2:53

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    MASQUERADE  all  --  anywhere             anywhere

ALso not working

pi@Heimdall:~ $ sudo iptables -t nat -A PREROUTING -s 192.168.1.10  -d 8.8.8.8 -p tcp --dport 53 -j DNAT --to-destination 192.168.1.2:53
pi@Heimdall:~ $ sudo iptables -t nat -A PREROUTING -s 192.168.1.10  -d 8.8.8.8 -p udp --dport 53 -j DNAT --to-destination 192.168.1.2:53
pi@Heimdall:~ $ sudo iptables -t nat -L --line-numbers
Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    DNAT       tcp  --  192.168.1.10         dns.google           tcp dpt:domain to:192.168.1.2:53
2    DNAT       udp  --  192.168.1.10         dns.google           udp dpt:domain to:192.168.1.2:53

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    MASQUERADE  all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination

Before probing deeper into possible solutions:
You'd probably get working results quicker if you simplify your setup.
An additional ethernet interface wouldn't be strictly required - setting your Pi as both gateway and DNS with your existing eth0 will suffice (just like DSL modem/router combos).

May I recommend cutting out eth1 from your setup (reduces complexity and saves some power, too)?
Once we find a solution for your DNS diverting problem, you can always add it later on, should you find you really need it.

Other than my laptop which I configure statically as I'm testing configs nothing else is currently going via eth1/192.168.1.254.

Everything else is set up (& working properly) as

DHCP Server : 192.168.1.2 (pihole/eth0)
Dynamic IPs : 192.168.1.100-200
DNS : 192.168.1.2 (pihole)
DGW : 192.168.1.1 (ISP provided router)

(oh and the guest network which is effectively a client of the main network but has no bearing on the traffic interception I'm trying to achieve)

My specific issue (which I accept isn't necessarily a pihole specific thing) is intercepting network traffic destined for the internet on a specific port and redirecting it to the same port an internal IP.

Ie if someone hard codes 8.8.8.8 or 1.1.1.1 or whatever into a client I want to redirect it to the pihole

If I had a decent router I could run wrt on or even had more granular control I would capture outbound DNS traffic there and then send it back into PiHole.

But I don't :frowning:

ok that's v.interesting

If I add a rule to redirect all non https traffic back to 192.168.1.2 that works exactly as expected (ie I get the default blocked page) so that says to my mind that the "rule" or "logic" or whatever you want to call it is correct.

So why do I get that nslookup error/timeout when specifying anything other than pihole with the same rule (other than port number) applied?

/me scratches head

pi@Heimdall:~ $ sudo iptables -t nat -A PREROUTING -i eth1   -p tcp --dport 80 -j DNAT --to-destination 192.168.1.2:80


pi@Heimdall:~ $ sudo iptables -t nat -L --line-numbers
Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    DNAT       tcp  --  anywhere             anywhere             tcp dpt:http to:192.168.1.2:80
2    DNAT       tcp  --  anywhere             anywhere             tcp dpt:domain to:192.168.1.2:53
3    DNAT       udp  --  anywhere             anywhere             udp dpt:domain to:192.168.1.2:53

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    MASQUERADE  all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination


Success!!!!!

Found the "solution" at this page.

Forward the DNS traffic to my ISP provided router and it then bounces it back to PiHole

pi@Heimdall:~ $ sudo iptables -t nat -A PREROUTING -i eth1 ! -s 192.168.1.2 -p tcp --dport 53 -j DNAT --to 192.168.1.1:53
pi@Heimdall:~ $ sudo iptables -t nat -A PREROUTING -i eth1 ! -s 192.168.1.2 -p udp --dport 53 -j DNAT --to 192.168.1.1:53
pi@Heimdall:~ $ sudo iptables -t nat -L --line-numbers
Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    DNAT       tcp  -- !Heimdall             anywhere             tcp dpt:domain to:192.168.1.1:53
2    DNAT       udp  -- !Heimdall             anywhere             udp dpt:domain to:192.168.1.1:53

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
num  target     prot opt source               destination
1    MASQUERADE  all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination

Top half below is the test results from my laptop configured statically as:
Static IP : 192.168.1.10
DNS : 192.168.1.2
DGW : 192.168.1.1

In the lower half the DGW was changed to 192.168.1.254 which is eth1 on the Pi, as you can see DNS requests to 8.8.8.8 now give the same response as going directly to the PiHole

Ok, understoood.
Your existing setup just blocks unsolicited DNS queries to external DNS, but you want to redirect it to be processed through your Pi-hole instead.

Let me rephrase my cautious recommendation to go without eth1 into something more action-oriented :wink:
Assuming that you have gigabit eth0 and otherwise kept your setup from Pihole plus Guest Wifi on different IP range, try the following eth1-free configuration:

  • unplug your second ethernet dongle (eth1)
  • undo any eth1 related configurations, including any iptables NAT entries
  • make sure that your eth0 interface is still configured to use your localhost DNS and your router by checking these lines in /etc/dhcpcd.conf
   static ip_address=192.168.1.2/24
   static routers=192.168.1.1
   static domain_name_servers=127.0.0.1
  • configure Pi-holes Settings|DHCP to hand out itself (192.168.1.2) as router (don't forget to save)
  • configure iptables to redirect incoming eth0 UDP/TCP traffic with a DNS target port to be handled by your machine's DNS:
   iptables -t nat -A PREROUTING -i eth0 -p udp --dport 53 -j REDIRECT --to-port 53
   iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 53 -j REDIRECT --to-port 53
  • (optional should you consider extending this to your 10.0.0.x guest wlan, also add the following)
   iptables -t nat -A PREROUTING -i wlan0 -p udp --dport 53 -j REDIRECT
   iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 53 -j REDIRECT

Bottom line difference to your solution:
You don't need a second ethernet dongle - save some power :wink:

Everything working using the 2 ethernet interfaces :+1:

Reduces risk of collisions on a single interface

EDIT: NB deliberately excluding the Guest Wifi from being forced through Pihole.

EDIT: Piccy added

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