Support for add-subnet option from dnsmasq (ECS/EDNS0 Client Subnet)

Was this a copy-paste error or was the MAC address actually cropped?

I simplified the routines somewhat further.

This. MAC was full and right.

The one stubborn device still re appeared with two entries. Will flush the table and re-enable DEBUG ARP, EDNS0 and DATABASE.

1 Like

You do not need to flush, just enable the debug messages and check if FTL is still receiving the MAC addresses through EDNS. If it doesn't, the problem is elsewhere. If it does, then something is broken on the Pi-hole end.

... too late, already did.

I'm actually not 100% confident in my router that it sends the MAC very often. Inspecting the log, it seems it send the MAC for one device a few times and later (or on some kind of trigger?) the MAC of another device - even though both sending DNS queries constantly.


But I can say, everything is working fine now. All clients show up with their corresponding MAC address and no duplicates.

Apologies if I missed this in a previous post, but what kind of router are you using?

I'm using a Ubiquity USG 3, dnsmasq is enables by default since some firmware versions and I added a config.gateway.json to add add-mac and add-subnet=32 options.

Can you check the version of dnsmasq? But it may not matter when thinking more about this. Can you sniff on the wire if the DNS packets really always contain the EDNS(0) data? We should find out when dnsmasq sends the data.

edit I checked the code and it should always send the information when it is available (should always be available).

http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=blob;f=src/edns0.c;h=d75d3cc1f1d38765ca2133c49352dfd4a01def3f;hb=f60fea1fb0a288011f57a25dfb653b8f6f8b46b9

1 Like

As expected.. it's really old.

root@USG:~# dnsmasq -v
Dnsmasq version 2.78-23-g9e09429  Copyright (c) 2000-2017 Simon Kelley
Compile time options: IPv6 GNU-getopt DBus i18n IDN DHCP DHCPv6 no-Lua TFTP conntrack ipset auth DNSSEC loop-detect inotify

But history-wise nothing should have changed regarding the frequency of EDNS information:
http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=history;f=src/edns0.c;h=d75d3cc1f1d38765ca2133c49352dfd4a01def3f;hb=f60fea1fb0a288011f57a25dfb653b8f6f8b46b9

I wouldn't consider this really old. However you are right about that it doesn't matter. Any possibility to use WireShark etc. to sniff the DNS packets?

Or maybe tcpdump:

sudo tcpdump -lnqtX src <SOURCE_IP> and dst <DESTINATION_IP> and udp port 53 or tcp port 53

EDIT: looks like it:

https://help.ui.com/hc/en-us/articles/227129127-UniFi-Methods-for-Capturing-Useful-Debug-Information#4

EDIT2: added tcp just in case

Did a tcpdump on the device hosting pihole for everything on port 53

All request that have been forwarded from the router contain EDNS0 information (subnet+ MAC), except my wireguard client and router's localhost (both only IP/subnet)

Still have to figure out, why my laptop, both on wifi and eth still sends requests directly to pihole ignoring the DNS server address it gets via DHCP.

Bildschirmfoto zu 2020-08-25 19-50-37

Maybe you edited /etc/resolv.conf (or similar) manually or setup something that does this.

Sot he conclusion is that all packets contain the data but FTL is not seeing them every time? This is ... surprising. How about the log in /var/log/pihole-FTL.log? Are there records for **** new UDP/TCP querys without EDNS(0) information?

Bingo!

I totally forgot about it. It was not directly edited but via systemd-resolvd as a workaround to change the DNS server order for my wireguard interface...


No. Conclusion is: Pihole is doing fine. But one client with two interfaces ignored the DHCP DNS settings and were still sending requests directly to pihole instead of the router, which would then had added EDSN0 information.

2 Likes

But why does this client then show up as mock-device? Because it was able to connect to Pi-hole but separated into a VPN caused Pi-hole to see queries from this client once through the router (with MAC added) and one directly (but without visible MAC address)?

That was what I wanted to figure out/reproduce.

WOW, I have waited so long for this option :slight_smile:

I would have liked to solve this with the proxy protocol, but it works for now. Maybe the proxy protocol will be implemented as well.

So far I have tested the following, and Pihole now receives the IP address of the requesting client.

Dns over port 53 (lokal network):
LAN -(port 53)-> dnsdist -(dns,53, docker internal)-> pihole --(dns,53, docker internal)-> unbound

DoH:
Internet -(HTTPS,443)-> Haproxy -(HTTP,80, docker internal)-> dnsdist -(dns,53, docker internal)-> pihole --(dns,53, docker internal)-> unbound

DoT:
Internet —(DoT,853)—> dnsdist —(dns,53, docker internal)—> pihole --(dns,53, docker internal)—> unbound

Changes in dnsdist:
To evaluate the X-Forwarded-For header of haproxy (haproxy -> dnsdist) you have to activate the parameter addDOHLocal(..., trustForwardedForHeader=true).
https://dnsdist.org/reference/config.html?highlight=trustforwardedforheader

For EDNS (dnsdist -> pihole) you have to adjust three global parameters

setECSOverride(true)
setECSSourcePrefixV4(32)
setECSSourcePrefixV6(128)

and activate newServer(..., useClientSubnet=true) for pihole.
https://dnsdist.org/advanced/ecs.html

in Pihole Docker container I did the following:

# docker exec -it dnsrec_pihole_1 bash
root@32302c83e05e:/var/log# pihole checkout ftl new/edns0
  Please note that changing branches severely alters your Pi-hole subsystems
  Features that work on the master branch, may not on a development branch
  This feature is NOT supported unless a Pi-hole developer explicitly asks!
  Have you read and understood this? [y/N] y

  [✓] Branch new/edns0 exists
  [✓] Downloading and Installing FTL
  [✓] Restarting pihole-FTL service...
  [✓] Enabling pihole-FTL service to start on reboot...

QUESTION: how can I activate this permanently in the pihole docker container?

Here my futile efforts for the implementation of the proxy protocol:

2 Likes

I have never heard of it before, neither have I seen a feature request. You should open a new one as it is not directly related to EDNS(0). Please provide some easily-accessible reading for the proxy protocol so we can have a look. However, if it is something outside of DNS, I don't see much of a chance to get this implemented. EDNS(0) has the benefit of being nice and in-place so it was possible to extend our existing DNS service with little effort (we just started processing something we ignored before, not really added an entirely new thing).

Container always starts "fresh". So you changed something in the container and this change is reset on restart. This is expected. I'm not a docker expert, but I seem to remember that you can docker commit any changes into a new container containing your changes (the checkout). If this doesn't work (or you don't know how to do it), then this is certainly another thing for another new discussion outside of the current topic.

I already opened a Feature Request in February (see link in last post), but at that time only the outdated "DNS X-Proxied-For" (XPF) was supported. But with dnsdist 1.5 the support of the "PROXY protocol" was added.

The most exciting new feature is the implementation of the Proxy Protocol between dnsdist and its backends. Aimed to replace the use of EDNS Client Subnet and our own XPF, the Proxy Protocol is an existing standard where a small header is prepended to the query, passing not only the source and destination addresses and ports along to the backend, but also custom values. Support for parsing the Proxy Protocol is already available in the development tree of the PowerDNS Recursor ;

Do this. Any posts on this thread about a different topic will be ignored.