Repository navigation
Replies: 1 comment 1 reply
|
Maybe you can run multiple dnscrypt-proxy instances, each listening to a different port and connecting to a single server. |
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Setup
I run dnscrypt-proxy 2.1.20 inside a container with
NET_ADMINenabled. All outgoing UDP traffic on port 53 is redirected to the local resolver using iptables NAT rules inPREROUTINGandOUTPUT, which DNAT the traffic to127.0.0.1:53.Applications inside the container, as well as containers sharing its network namespace, are configured to use public DNS resolvers such as
8.8.8.8and1.1.1.1. The iptables rules transparently redirect their DNS queries to dnscrypt-proxy.My configuration includes five static DoH servers in
server_names: two Google servers, two Cloudflare servers, and one Quad9 server. dnscrypt-proxy selects upstreams from this pool based on latency.Observed behavior
When I run
nslookup google.com 1.1.1.1, the query is answered through whichever upstream dnscrypt-proxy selects, rather than necessarily going through Cloudflare.Using
dig TXT o-o.myaddr.l.google.com, I can observe Google egress IPs, sometimes with an ECS line, or Cloudflare egress IPs without one. This behavior occurs regardless of which resolver address I specify in the client command.This is expected because DNAT changes the packet's destination before dnscrypt-proxy receives it, so the proxy no longer has the original destination address available through the usual socket interface.
Desired behavior
I would like dnscrypt-proxy to select an upstream based on the resolver address originally targeted by the client, while retaining the existing upstream pool as a fallback.
For example:
1.1.1.1should usecloudflare1.8.8.8.8should usegoogle2.Ideally, this should work within a single dnscrypt-proxy instance, with shared caching, connection management, and latency tracking wherever possible.
Existing approaches and their limitations
1. Separate instances for each upstream
Without modifying dnscrypt-proxy, I can run a separate instance for each upstream, assign each instance its own
listen_addressesport andserver_names, and configure iptables to DNAT each original destination to the corresponding local port.This approach works, but each instance maintains its own cache, connection pool, and latency tracking. When deployed across many containers, the additional CPU and memory overhead becomes significant, making this approach difficult to scale.
2. Packet marking
iptables can mark packets using
-j MARKor assign DSCP/TOS values based on the original destination before DNAT occurs.However, packet marks and TOS values are kernel-level metadata rather than part of the DNS message. The receiving application would need to retrieve this information through socket ancillary data, for example, using
SO_RCVMARKorIP_RECVTOSwithrecvmsg().As far as I know, dnscrypt-proxy does not currently read this metadata, so this approach would require support within the application.
Questions
server_nameslist, or a single upstream server, with a particularlisten_addressesaddress or port within one instance? From what I can tell, all listeners share the same upstream pool, whileforwarding_rulesonly supports matching queried domains.The existing integration is available in the test branch of Internet Income Script.
Thank you for your time and any guidance you can provide.
All reactions