Why can't I map the client's proper IP with DoT implemented with Traefik?

My setup is as follow (with lastest PiHole docker image)

Traefik on Docker with network_mode=host

PiHole on Docker, listening on Host's 53UDP+TCP with Traefik proxying with TCP router DoT's 853/TCP to local 53
CoreDNS on Docker with Traefik proxying a https://domain to CoreDNS's 80, CoreDNS forwarding to PiHole fixed docker IP, and as such implementing DoH in front of PiHole.

Now all request have their source IP properly identified by PiHole (most of them are from the LAN, no NAT) except DoT's ones.
Even a DoH request gives me a proper source (the original computer's IP AND the coredns.dockerhost_default as source), showing that it CAN identify a container's IP/Name.

DoT are only performed by Android Mobile using the system's DNS feature.

AFAIK, EDNS0 is used to identify client's IP when requesting through NAT.
I'm not sure it's used here, probably for DoH as it goes: BOX Public IP -> Internet BOX(NAT to 192.168.1.0/24)->ProperRouter(NAT 192.168.0.0/24)->TraefikHostmode->PiHole.
And client's are identified properly (though trying from LAN through public IP that resolves to BOX public IP)

I'm guessing the Traefik TCP router is the issue here and have read that having PiHole container in network_mode=host would help. But I want to grasp the issue before moving anything.

I just don't get what's preventing PiHole to get the client's IP with this setup.
Is it because no headers are passed in TCP?
Are HTTP headers used to get client's IP when receiving DoH requests?

Thanks to anyone reading all of this!

Your DoT requests are terminating at your DoT proxy, and that proxy is then forwarding plain DNS requests to Pi-hole, which would show up as originating from your proxy's IP.

You are correct that EDNS Client Subnet (ECS) would mitigate this, by injecting original requestor's (partial) IP address information into a special section of the forwarded DNS request, and if provided correctly, Pi-hole would process such information by default.

You'd have to consult Traefik's documentation and support forums for details whether and how it would support enabling ECS.

thanks!

I don't think Traefik would modify anything on the DNS request, the EDNS part should be preserved.

In this case, wouldn't it be an issue with Android's Private DNS feature or with how Android execute DNS requests? Is it not setting the EDNS part in its requests?

When using DoH, I see the client's identified as coredns.dockerhost_default, showing Traefik is not removing information. Though it's using a HTTP router as opposed to TCP for DoT.
I'm not really sure EDNS is at play here.

That coredns.dockerhost_default client name is not part of the DNS request at all.

Pi-hole would have learned that by means of a reverse lookup for the DNS request's client source IP, and it shows that name instead of the client IP in its UI to allow for easier client identification.

The original client won't supply any ECS info (that would be redundant, as the request's source IP already is the original IP).
It's a (recursive) resolver's optional(!) job to add ECS information, so that authoritative servers can adjust their IP replies to topologically match ECS's original requestor's IP range.

You'd have to get your DoT proxy to add ECS info.
In your case, Traefik's support would be the preferred source to find a solution.
If Traefik doesn't support it, you may have to consider switching to a DoT proxy that would.

I see! Enlightening, it all make sense now.

So I'd probably have a better chance using CoreDNS to implement DoT and forward to Pihole.
Hopefully it should implement EDNS ECS properly.

Then the CoreDNS forward plugins doesn't transfer any client info by default but I can probably work on it

Thanks a lot !

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