iptables, PiHole and DNS redirection?

Post new topic   Reply to topic    DD-WRT Forum Forum Index -> Atheros WiSOC based Hardware
Author Message
ArjenR49
DD-WRT User


Joined: 05 Oct 2008
Posts: 288
Location: Helsinki, Finland

PostPosted: Sun Jun 28, 2020 12:55    Post subject: iptables, PiHole and DNS redirection? Reply with quote
I have an R7800 running f/w build 43516 with a Raspberry Pi running PiHole as the DNS server.
I do not use the GUI setting Force DNS Redirection and AFAIK my setup works, but it doesn't prevent clients from using a different DNS. Even though I won't loose sleep over it, I'd still like to know how I can prevent that.

Mimicking from a post on the DD-WRT forum concerning Marvell gear, I therefore added the following iptables rules:

iptables -t nat -I PREROUTING -i br0 -s ! 192.168.5.60 -p tcp --dport 53 -j DNAT --to 192.168.5.60:53
iptables -t nat -I PREROUTING -i br0 -s ! 192.168.5.60 -p udp --dport 53 -j DNAT --to 192.168.5.60:53
iptables -I FORWARD -d 192.168.5.60 -p tcp --dport 53 -j ACCEPT
iptables -I FORWARD -d 192.168.5.60 -p udp --dport 53 -j ACCEPT

The result is that when I execute a dig command my laptop for a blocked domain and make it use a DNS server different from the PiHole, I get an error message instead of 0.0.0.0 like I do when I do not try to force a different DNS server:

Misbehaving client machine:
arjen@HP430G5:~$ dig google-analytics.com @9.9.9.9

; <<>> DiG 9.11.3-1ubuntu1.12-Ubuntu <<>> google-analytics.com @9.9.9.9
;; global options: +cmd
;; connection timed out; no servers could be reached

Client machine playing nice:
arjen@HP430G5:~$ dig google-analytics.com

; <<>> DiG 9.11.3-1ubuntu1.12-Ubuntu <<>> google-analytics.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24735
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;google-analytics.com. IN A

;; ANSWER SECTION:
google-analytics.com. 2 IN A 0.0.0.0

;; Query time: 2 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Sun Jun 28 15:37:49 EEST 2020
;; MSG SIZE rcvd: 65

The author of the post that I took the rules from I think did say that they were untested.

What to add or change to get the 'misbehaving' client the result it should get, viz. 0.0.0.0?
Sponsor
Wildlion
DD-WRT Guru


Joined: 24 May 2016
Posts: 717

PostPosted: Mon Jun 29, 2020 22:21    Post subject: Reply with quote
Have you done any debugging?

based on what you are showing this seems suspect that you are not getting any dns:
Quote:

;; connection timed out; no servers could be reached


I think that the rule should be

Code:
iptables -t nat -I PREROUTING -i br0 ! -s 192.168.5.60 -p udp --dport 53 -j DNAT --to 192.168.5.60


The not (!) should be on the other side of the -s (and I took the :53 off of the end, because that should be redundant)

not sure why you would need the forward rules, but could always check.
ArjenR49
DD-WRT User


Joined: 05 Oct 2008
Posts: 288
Location: Helsinki, Finland

PostPosted: Tue Jun 30, 2020 5:58    Post subject: Reply with quote
There's so much I don't know about iptables that it could be regarded as foolish to fumble around with those rules ...

I don't know exactly how to do debugging in practice. I've tested what rules do by means of the dig command.
Yesterday I even installed the dig command to the dd-wrt router. I have had entware on it for ages because of unbound.
I agree that it very much looks like I'm not getting any dns reply back from a dig command that is rerouted by the rule.

I was under the impression that the forward rules were there to assure the answer to the dns request gets back to the requestor. However, it seemsto make no difference at all.
In fact nothing I've done in the way of varying the 'force redirection' rule according to what variations of it I've found here and there, has not made any difference. I always get the time-out, no servers found message.

I can't continue testing in the daytime, as my wife is working from home because of the pandemic and using the very LAN I try wo work on when I am in this country. Today she's partaking in video job interviews for her successor, so ...
As I can't be sitting on my hands for months while in this country, I change things when she's not on line and have to get everything working again no matter how late in the night it gets.

I checked iptables syntax on the exclamation point position and it's supposed to go to the right of the -s etc.
Not all manuals are equally clear about it though, but https://linux.die.net/man/8/iptables indicates the correct position clearly:

-s, --source [!] address[/mask]

I've found and read many posts from all over the internet on the subject of redirecting DNS hard-wired in client devices and the rule proposed always seems to be essentially like the one I applied. The extra forward rule was only mentioned in one dd-wrt forum post. Not many mention of how to make sure the reply reaches the requestor nor of how to make sure the requestor doesn't immediately notice it gets fooled.

I am aware of the fact that dd-wrt runs the firewall script many times during startup. BTW, going by logging messages I added to the script it is sometimes even started again before it has even finished. Anyway, to prevent rules to be multiplicated, I make sure I add the same rule to the start of the script with the -I or -A changed to -D.
Iptables is still immensely hard to grasp overall. I once tried to study a graphic explaining what is going on inside, but it looked like a bowl of spaghetti.
Wildlion
DD-WRT Guru


Joined: 24 May 2016
Posts: 717

PostPosted: Tue Jun 30, 2020 21:41    Post subject: Reply with quote
I can explain the iptables rules, i just never remember which side the "!" goes.

And that was my first guess was that it was on the opposite side.

based on a small test i did internally (i do not have a pihole setup)

the command:

Code:

iptables -t nat -I PREROUTING -i br0 -s 192.168.1.50 -p udp --dport 53 -j DNAT --to 10.0.0.60


On the 192.168.1.60, I could see the dns requests going to the machine.


using
Code:

iptables -t nat -I PREROUTING -i br0 ! -s 192.168.1.60 -p udp --dport 53 -j DNAT --to 192.168.1.60


In my short test, the packets are getting to the machine and coming back, but I am wondering if it is because the local machine does not understand why the packet is coming back from a different machine.



EDIT:

Okay so after testing (on something similar) what you want is:

Code:

iptables -t nat -I PREROUTING -i br0 ! -s 192.168.5.60 -p udp --dport 53 -j DNAT --to 192.168.5.60
iptables -t nat -I POSTROUTING -o br0 ! -s 192.168.5.60 -p udp --dport 53 -j SNAT --to 192.168.5.1


This assumes that your PIhole is at 192.168.5.60 and your router is at 192.168.5.1 and that you are on br0 (ie have not changed any bridge adapters

The reason this works is that the router initially gets the packet (trying to route to outside your network), the router then changes the destination to be 192.168.5.60 on the packet and sends the packet. On the way out, it changes the source of the packet to be the router's ipaddress in this case (192.168.5.1, yes I could probably script it up).

The packet is sent to the PIhole, and the pihole responds to the router, the router was expecting the packet and routes just like normal back to the client machine.

This will only work for udp connections, which is usually used for dns, but if you want to do it for tcp as well, just change the "udp" to "tcp" in the rules above.
ArjenR49
DD-WRT User


Joined: 05 Oct 2008
Posts: 288
Location: Helsinki, Finland

PostPosted: Tue Jun 30, 2020 22:27    Post subject: Reply with quote
Wildlion wrote:
I can explain the iptables rules, i just never remember which side the "!" goes.

And that was my first guess was that it was on the opposite side.

based on a small test i did internally (i do not have a pihole setup)

the command:

Code:

iptables -t nat -I PREROUTING -i br0 -s 10.0.0.50 -p udp --dport 53 -j DNAT --to 10.0.0.60


On the 10.0.0.60, I could see the dns requests going to the machine.


using
Code:

iptables -t nat -I PREROUTING -i br0 ! -s 10.0.0.60 -p udp --dport 53 -j DNAT --to 10.0.0.60


In my short test, the packets are getting to the machine and coming back, but I am wondering if it is because the local machine does not understand why the packet is coming back from a different machine.


With what tool did you see the packet coming back? If I could just somehow trace the DNS request going out and see the reply coming back.

I would expect the reply coming from a different machine might cause problems.

With IPTABLES you can do a whole lot, I know, but I just don't know how.
Only a few simple things I've picked up and even then mostly mimicking.
I know how to print the rules that are in force and can interpret single rules sort of. I can use dig and have it even on the router since I installed it from Entware.
That's about it.
Judging by the amount of posts all over the internet addressing redirection of hard-wired DNS server addresses etc., one might assume that getting the reply back to the requestor would have been addressed here and there in an adequate way, too, but I haven't found any. As if it's supposed to work with the one prerouting rule.

I made an observation that may not raise any eyebrows, but otoh could point to a problem:
If I execute a dig google-analytics.com on my laptop, the reply 0.0.0.0 comes from 127.0.0.53:53.

If I do the same on the router, I get an actual IP address for google-analytics from 192.168.5.1:53.
If I do the same and add @192.168.5.60 (PiHole) on the router, I again get 0.0.0.0, from 192.168.5.60:53.

If I do the same on the PiHole server itself, the reply is also 0.0.0.0 from 127.0.0.1:53

This is done in three terminal windows on my laptop, using SSH to log in to the router or the PiHole.

If I do dig google-analytics.com @9.9.9.9 on the laptop I get the time-out.
On the router or the PiHole I get an actual IP for the site, both from 9.9.9.9.

In the end the results from the laptop are which matter, the others may reveal something.

The PiHole server has Unbound, PiVPN and Wireguard installed and working together fine AFAIK.
Upstream DNS is 127.0.0.1:5335 only (that's for unbound).
Since a day or so I have disabled IPv6 so it won't mess up things. IPv6 works fine when enabled.

The IPTABLE rules are currently:
iptables -t nat -D PREROUTING -i br0 -p tcp -s ! 192.168.5.60 -d ! 192.168.5.60 --dport 53 -j DNAT --to 192.168.5.60 >/dev/null 2>&1

iptables -t nat -D PREROUTING -i br0 -p udp -s ! 192.168.5.60 -d ! 192.168.5.60 --dport 53 -j DNAT --to 192.168.5.60 >/dev/null 2>&1
Wildlion
DD-WRT Guru


Joined: 24 May 2016
Posts: 717

PostPosted: Tue Jun 30, 2020 22:44    Post subject: Reply with quote
read my post above specifically the "edit" area, that has the solution for you.

I used a combination of tools iptables and wireshark.
ArjenR49
DD-WRT User


Joined: 05 Oct 2008
Posts: 288
Location: Helsinki, Finland

PostPosted: Wed Jul 01, 2020 7:12    Post subject: Reply with quote
Wildlion wrote:
read my post above specifically the "edit" area, that has the solution for you.

I used a combination of tools iptables and wireshark.


Thanks a lot! I can't try the pre- postrouting rules until after work hours because my wife is teleworking on our private LAN, which was my playing field. Maybe I should have set her up on another router instead of creating a virtual AP for her work laptop ... Which was a learning exercise, though.

I've heard about Wireshark, but don't know exactly what it can do apart from making public wi-fi networks unsafe ... Hope to look into it later. Too much going on now. Hopefully in August when in my get-away Wink

Thanks again for thinking along and testing.
ArjenR49
DD-WRT User


Joined: 05 Oct 2008
Posts: 288
Location: Helsinki, Finland

PostPosted: Wed Jul 01, 2020 19:45    Post subject: Reply with quote
After my teleworking partner finally called it a day and after wednesday sauna Wink I installed the new iptables rules essentially as proposed by WildLion and hey presto, from my laptop I got the following great dig results:

arjen@HP430G5:~$ dig google-analytics.com

; <<>> DiG 9.11.3-1ubuntu1.12-Ubuntu <<>> google-analytics.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26601
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;google-analytics.com. IN A

;; ANSWER SECTION:
google-analytics.com. 2 IN A 0.0.0.0

;; Query time: 2 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Wed Jul 01 22:02:55 EEST 2020
;; MSG SIZE rcvd: 65

arjen@HP430G5:~$ dig google-analytics.com @9.9.9.9

; <<>> DiG 9.11.3-1ubuntu1.12-Ubuntu <<>> google-analytics.com @9.9.9.9
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9445
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;google-analytics.com. IN A

;; ANSWER SECTION:
google-analytics.com. 2 IN A 0.0.0.0

;; Query time: 3 msec
;; SERVER: 9.9.9.9#53(9.9.9.9)
;; WHEN: Wed Jul 01 22:02:59 EEST 2020
;; MSG SIZE rcvd: 54


Looks perfect to me.
Both results block google-analytics.com and they look like coming from the site that the requestor intended - whereas in reality both replies are from the PiHole server on 192.168.5.60.

The following IPTABLES rules:
iptables -t nat -I PREROUTING -i br0 -p tcp ! -s 192.168.5.60 --dport 53 -j DNAT --to 192.168.5.60
iptables -t nat -I PREROUTING -i br0 -p udp ! -s 192.168.5.60 --dport 53 -j DNAT --to 192.168.5.60
iptables -t nat -I POSTROUTING -o br0 -p tcp ! -s 192.168.5.60 --dport 53 -j SNAT --to 192.168.5.1
iptables -t nat -I POSTROUTING -o br0 -p udp ! -s 192.168.5.60 --dport 53 -j SNAT --to 192.168.5.1

I have a second set identical to these near the top of the script with just one change in every rule: -D instead of -I. This is done to prevent rules from being multiplicated which would otherwise happen as the firewall script is run many times during router startup.

My LAN setup is an R7800 router running DD-WRT (currently f/w build 43516), router IP 192.168.5.1, a Raspberry Pi for DNS server running PiHole and Unbound (also PiVPN and Wireguard) on IP address 192.168.5.60.

Additional DNSMasq options:
no-resolv
log-async=5
# PiHole DNS server
server=192.168.5.60
# Advertise PiHole DNS server address via DNSMasq in the router
dhcp-option=6,192.168.5.60

Of the list of GUI options above this field on the same page only DNSMasq is enabled.

Basic setup:
Use DNSMasq for DNS
DHCP-Authoritative
Recursive DNS Resolving (Unbound)
all enabled.
Unbound from Entware started in the startup script as per the wiki (unslung).

Local IP Address and Gateway both 192.168.5.1

Local DNS and three Static DNS IP's are all 0.0.0.0

The purpose of this setup is to prevent LAN clients using hard-wired DNS IP's of their own or 'rogue' users changing the DNS address advertised by DHCP (I think) and make them believe they get away with it. Except that the PiHole makes a lot of adverts and 'casino' sites go away.

Apart from thwarting google in using its own hard-wired dns adresses in a Chromecast module, this is still mainly an exercise Wink
I cannot test the Chromecast module, as we're moving house soon and it's somewhere in a box now Wink but I've prevented 8.8.8.8 and the like of it before in a blunt way and got away with it.

IPv6 is off for the moment as I'm not sure how it would interfere with this diversion exercise.
ArjenR49
DD-WRT User


Joined: 05 Oct 2008
Posts: 288
Location: Helsinki, Finland

PostPosted: Thu Jul 02, 2020 6:05    Post subject: Reply with quote
ArjenR49 wrote:

The IPTABLE rules are currently:
iptables -t nat -D PREROUTING -i br0 -p tcp -s ! 192.168.5.60 -d ! 192.168.5.60 --dport 53 -j DNAT --to 192.168.5.60 >/dev/null 2>&1

iptables -t nat -D PREROUTING -i br0 -p udp -s ! 192.168.5.60 -d ! 192.168.5.60 --dport 53 -j DNAT --to 192.168.5.60 >/dev/null 2>&1


Just two comments to my earlier post (from Wed Jul 01, 2020 12:27 am):

1. Those were the rules with -D instead of -I to delete the actual rule inserted in a previous execution of the firewall script (it is run many time during startup!). I copied the wrong lines to my post from my firewall script at the time.

2. I picked up the 'double negation' (having -s ! and -d !) in the above rule from another discussion. It looked attractive as it seemed 'logical' supposedly preventing changing the destination address in case where the destination address is already right, i.e. the PiHole, but in practice it doesn't work like that.
I'll have to leave it to others to explain why this is a bad idea.
Alozaros
DD-WRT Guru


Joined: 16 Nov 2015
Posts: 3642
Location: UK, London, just across the river..

PostPosted: Thu Jul 02, 2020 8:51    Post subject: Reply with quote
ArjenR49 i ve no idea/clue why you run those on your router, as your goal is external DNS via Pi...if i understood correctly...??!!

Recursive DNS Resolving (Unbound)
all enabled.
Unbound from Entware started in the startup script as per the wiki (unslung).

if your goal is, to route DNS requests over to Pi, there is absolutely no need to run those services as they do not do anything, than mess... well your own mess...

honestly on ggl ive seen many manual's how to run PI hole DNS on DDWRT router (or type Pi-hole DNS DDWRT)..all working ive set it for my client, well later he removed it and kept on DNSmasq DDWWRT only, but your struggles are immense...i think you are quite flummoxed by, what you want to achieve...and how the things work..or may be i didn't have my coffee yet and got off the bed too early ...

p.s. best bet to get rid of the adverts...(kind of)...
1. use ad-blocker on router level... there are many many that work great...with DDWRT...
2. use uBlock Origin on Browser level ...
3. add an enormous amount of host's to block in your (windows) host file...literally you can download all the ad-blockers list and make a huge entry list there, so no buggers around on OS level too...

as basically those ways to block ads above, all use DNS host list to block...you cannot avoid some adds that blend into the web-sites, or inside the stream...

_________________
Atheros
TP-Link WR740Nv1 ------DD-WRT 43334 BS AP,NAT
TP-Link WR740Nv4 ------DD-WRT 43028 BS WAP/Switch
TP-Link WR1043NDv2 ----DD-WRT 43516 BS AP,NAT,AD Block,AP Isolation,Firewall,Local DNS,Forced DNS,DoT,VPN
TP-Link WR1043NDv2 ----DD-WRT 43334 BS AP,NAT,AD Block,Firewall,Local DNS,Forced DNS,DoT,VPN
TP-Link WR1043NDv2 ----Gargoyle OS 1.12.0 AP,NAT,QoS,Quotas
Qualcomm/IPQ8065
Netgear R7800 -------DD-WRT 43334 BS AP,NAT,AD-Block,AP&Net Isolation,VLAN's,Firewall,Local DNS,DoT
Broadcom
Netgear R7000 -------DD-WRT 43334 BS AP,Wi-Fi OFF,NAT,AD-Block,Firewall,Local DNS,Forced DNS,DoT,VPN
------------------------------------------------------------------------------------------------
Stubby for DNS over TLS I DNSCrypt v2 via Entware by mac913
ArjenR49
DD-WRT User


Joined: 05 Oct 2008
Posts: 288
Location: Helsinki, Finland

PostPosted: Thu Jul 02, 2020 16:05    Post subject: Reply with quote
Alozaros wrote:
ArjenR49 i ve no idea/clue why you run those on your router, as your goal is external DNS via Pi...if i understood correctly...??!!

Recursive DNS Resolving (Unbound)
all enabled.
Unbound from Entware started in the startup script as per the wiki (unslung).

if your goal is, to route DNS requests over to Pi, there is absolutely no need to run those services as they do not do anything, than mess... well your own mess...


Earlier on I tried without unbound on the dd-wrt router, as I figured that it should not be needed on the router in my setup, but that didn't work well. I will get rid of unbound on the router as soon as I get it to work without.
So I will try again when I get the chance. It may be different now with different IPTABLES rules.

I don't find my setup overly complicated. IPTABLES are complicated allright. I like the statistics of the PiHole. And enjoy setting up a Raspberry Pi4B. I have it boot off an SSD disk now.

This is also a passtime, a hobby for me, maybe even fun. More fun than getting unwanted stuff on my smartphone and loads of weird links promising one thing but suddenly opening up casino pages etc. when I've been looking for reviews of let's say Ikea mattresses. Rubbish that I haven't asked nor looked for.

In my view the internet is broken in that respect. Broken by unscrupulous and perhaps even criminal parties. In our home when we speak a few words about something or another the next thing we know is getting ads about that subject on Facebook. Very annoying.

I used to be a licensed radio-amateur mostly building stuff, but without proper space for an antenna and no work-room and all stuff I collected over tens of years given away before we'll move to a smaller apartment, I apply myself to what is left. LAN, NAS, remote backup using a Pi with two BTRFS drives behind double firewalls using my own scripts, and a few more Pi projects.
And most recently also more modern, i.e. much smaller Hi-Fi gear.

In addition to unbound, from Entware I have installed nano and dig (bind-utils). I installed Entware a long time ago. Dig wasn't included in DD-WRT but it is easier to use just a single utility on different machines than two different ones for the same purpose (nslookup vs. dig).
ArjenR49
DD-WRT User


Joined: 05 Oct 2008
Posts: 288
Location: Helsinki, Finland

PostPosted: Thu Jul 02, 2020 21:30    Post subject: Reply with quote
I was able to clean up the mess Alozaros accused me of having created Wink

As it turned out after more testing and rebooting, when using an external DNS server like PiHole on a Raspberry Pi, in DD-WRT on the basic setup page of the Network Address Server Settings (DHCP) one can leave DNSMasq for DNS and Unbound disabled.

On the services page under DNSMasq only DNSMasq is now left enabled. It is needed for DHCP.
In additional DNSMasq setting the options I've posted in an earlier post in this thread are unchanged.

The PiHole isn't used for DHCP in my setup. DHCP is left to DNSMasq on the router.

With Conditional Forwarding on the PiHole's DNS Settings ticked my local domain name would be appended to every query in PiHole's query log, which looked very strange. After unticking the query log looked normal again. DNS lookup for local clients still worked as it is supposed to.

During earlier tests with unbound disabled in DD-WRT DNS resolution become very slow, but now with DNSMasq for DNS disabled as well, overall DNS performance is back to normal or faster.

By virtue of the PRE- and POSTROUTING rules in the firewall script any dig requests with an alternative DNS server IP as the second parameter (@[IP]) are resolved by PiHole and the result appears to come from the address in the parameter.
Display posts from previous:    Page 1 of 1
Post new topic   Reply to topic    DD-WRT Forum Forum Index -> Atheros WiSOC based Hardware All times are GMT

Navigation

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum