Pi-hole query loop by misbehaving IoT device

I have a misbehaving IoT device on my network that occasionally sends a malformed DNS query. Because I have Conditional forwarding enabled on Pi-hole, it gets sent to my router and stuck in a loop until rate limiting kicks in. My usual workaround is to manually block those queries, but in this case, since it's malformed, I have no idea what to block. The deny button in the Query Log fails with Timeout or Network Connection Error! when I try to block it.

The query itself appears in different formats depending on where I'm looking at it:

  • The Query Log tab shows it just as "0", but if you copy the text, it copies as "0" (Please copy paste that text to see the actual output. The browser doesn't render it) .

  • The Top Permitted Domains on the Dashboard page shows it as "%01%02%100".

Querying the SQLite DB returns this:

root@pihole:/etc/pihole# pihole-FTL sqlite3 pihole-FTL.db "SELECT * from queries WHERE client = '192.168.100.158' LIMIT 10"
32|1750495527.70349|1|2|go6j5la9fn2.iot-as-mqtt.cn-shanghai.aliyuncs.com|192.168.100.158|127.0.0.1#5053||3|0.0226447582244873|0||-1
53|1750495676.91641|1|2|www.cloudinverter.net|192.168.100.158|127.0.0.1#5053||4|0.0234313011169434|0||-1
78|1750496102.47433|1|17|www.cloudinverter.net|192.168.100.158|127.0.0.1#5053||4|1.04904174804688e-05|0||-1
157|1750496416.85393|1|3|www.cloudinverter.net|192.168.100.158|||4|1.04904174804688e-05|0||-1
426|1750496417.82532|0|12|0|192.168.100.158|192.168.1.1#53||7|0.02866530418396|0||-1
440|1750496417.81419|0|12|0|192.168.100.158|192.168.1.1#53||7|0.00997829437255859|0||-1
1489|1750496419.8444|0|14|0|192.168.100.158|||0||0||-1
3198|1750496421.84896|0|14|0|192.168.100.158|||0||0||-1
21499|1750496535.99662|1|17|go6j5la9fn2.iot-as-mqtt.cn-shanghai.aliyuncs.com|192.168.100.158|127.0.0.1#5053||3|1.00135803222656e-05|0||-1
21500|1750496536.84712|1|2|ntp2.aliyun.com|192.168.100.158|127.0.0.1#5053||3|0.0217499732971191|0||-1

Things I have tried blocking:

  • "0" – This doesn't block the query.
  • "%01%02%100" – Pi-hole doesn't allow this entry; it returns the error invalid domain.

The only workaround I can think of for now is to just make the IoT device bypass Pi-hole, but I would love some other way.

https://tricorder.pi-hole.net/ifRKXzk5/

There is another workaround you could consider.

Create a new group containing just the device in question

Block everything by default (in domains, set a regex blocking filter with domain of .*) and ensure it is applied only to the group for this device.

Whitelist the domains you want it to be able to reach, ensuring that they are set only to the group of this device.
From your log except above, you'd probably want to start with something along the lines of:
aliyuncs.com
aliyn.com
www.cloudinverter.net
and select Add domain as wildcard for the first two of those.

Alternatively, if the invalid domain is always the same (0x01 0x02 0x10 0x30 - your three unprintable characters followed by a zero), you could just block it with a regex blocking entry in the domains menu:

^...0$

This will match any domain name that is four characters long and ending with a zero.

If the invalid domain is different every time, then probably follow the approach I mentioned in my first response.

This sounds like the best solution if it actually blocks the domain. The domain is always the same so fingers crossed it will work!

I will post an update when the device makes the query again

Thank you :folded_hands:t4:

Unfortunately, the ^...0$ regex didn't work. It's weird because when I test it under Tools > Search List, it correctly detects the query using regex, but the actual query was still not blocked.


I'm now trying ^%..%..%..0$, as it matches %01%02%100.

In your screenshot the query type is listed as "NONE".

There is more wrong with these queries than the malformed domain name.

Yah, somehow mentioning that completely skipped my mind :sweat_smile:

Anyways, the update is that my other regex ^%..%..%..0$ also didn't work. Now I am trying your original idea of blocking everything with .* and then whitelisting domains it need. Lets see if .* can block it or not.

Try to block everything ending with 0 using this regex: 0$.

As a side note, these queries containing image are very weird.

For what it may be worth, I once had a problem something like this (mangled names, strange DNS packet types, the little hex squares) that turned out to be a USB-Ethernet adapter that was mangling the data stream going through it.

The problem disappeared when the adapter was replaced with a different make/model.

1 Like

I was already halfway of explaining how to extract the hex values for the offending domain using tcpdump and use those to create a fitting regex:

sudo tcpdump -ntvXi eth0 'udp port 53 and ether src host 00:16:3e:XX:XX:XX'

Until I noticed below:

Why is that creating a loop?
DNS queries being forwarded by Pi-hole via CF to the router should not loop back to Pi-hole.
Have you configured the Pi-hole IP in the WAN/Internet DNS settings of the router by chance?
That in combination with CF would create a loop and is not the proper way and can be avoided.

Below the proper way:

In those same docs are even a couple of "Router setup" examples for some popular brands.

The .* regex also didn't work. At this point, I wonder if it's even possible to block this query, considering even .* can't block it.

I’ll try this regex too, just to be sure.

In my current setup, all devices on my network use Pi-hole as the DNS server, including the router. Pi-hole is configured to use Cloudflared (DNS over HTTPS) to make the actual queries. So, in the case of Conditional forwarding queries, if Pi-hole decides to send the query to the router, and the router is unable to answer it because it doesn't have that entry in its hosts file, the query gets sent back to Pi-hole causing the loop.

But after reading your comment, I did recheck my configs and saw Pi-hole mention this under the Conditional forwarding setting:

Enabling Conditional Forwarding will also forward all hostnames (i.e., non-FQDNs) to the router when "Never forward non-FQDNs" is not enabled.

I had that setting turned off. I just turned it on, and perhaps this will stop Pi-hole from sending the malformed query to the router? We'll see, I guess.

The device making these queries is over WIFI and I have been able to reproduce this on 2 separate machines running pihole so its unlikely

Ya lost me there.
So you have a partial loop on purpose while this is not necessary.
Why does the router need Pi-hole blocking?

Normally it only sends out queries for syncing time, checking firmware updates and maybe some ISP stuff... thats it.
Expect lots of troubles when devices join your network that perform some kind of network service discovery!

EDIT: Discourse here is full of "partial DNS loop" mistakes:

https://discourse.pi-hole.net/search?q=partial%20dns%20loop

I understand your confusion :sweat_smile: without having full visibility in my network this will look weird but the long story short is that i have openwrt router running with some extra services that require openwrt to make DNS queries to pihole for them to work

Have you tried reaching out to the manufacturer, they may not be aware and may be able to update the firmware.

It seems like enabling Never forward non-FQDNs does stop Pi-hole from sending the malformed query to the router. On top of that, it looks like once the IoT device received an NXDOMAIN response, it stopped making the query!

Thank you all for the help :folded_hands: I will continue to monitor this and if anything changes i will post an update

I will have better luck praying to Odin to fix this :stuck_out_tongue: but for the curious the device is a solar inverter from company SolarMax and the dashboard to monitor it is called cloudinverter

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