DnsClient.NET icon indicating copy to clipboard operation
DnsClient.NET copied to clipboard

Any plan to add support for DoT (preferred) or DoH?

Open jol64 opened this issue 3 years ago • 13 comments

both require a means for authentication in addition to an IPEndpoint. My preference is a server name. Thanks, Joachim

jol64 avatar Dec 11 '20 16:12 jol64

I always wanted to add a lot of the security features of the DNS protocol itself. But, mostly because of time constraints, never had the chance to really work on that yet.

Adding the transport layer over HTTPS is another thing. I have ideas of how that will work, but haven't really played with that yet.

MichaCo avatar Feb 08 '21 13:02 MichaCo

Hello @MichaCo

It seems the industry is shifting toward DoH instead of DoT.

What would be needed to bring DoH (RFC 8484) support to this library? DoT could follow of course, but I'm more interested in the former.

I'm willing to take some time to start working on it, but I'm not sure where to begin. Some pointers would be great.

Thanks.

Indigo744 avatar Feb 24 '22 15:02 Indigo744

@Indigo744 I disagree. There is poor adoption in general for either. https://www.dnsfilter.com/blog/dns-over-tls is a good take on why browsers kind of prefer DoH in browsers, but I am convincend organizations would prefer DoT and use existing infrastructure rather that also supports split horizon DNS. And here I believe the biggest challenge is missing support in DHCP for configuration of either DoT or DoH (and yes, I know DHCP is insecure, but it is a reality for mobile clients). I don´t want you (all) to convince not to implement DoH, but at least it should not preclude adding DoT. Thanks.

jol64 avatar Feb 24 '22 15:02 jol64

@jol64 I didn't want to sound negative of course. I've never implied that DoH was better than DoT or anything like that. Maybe "shifting toward DoH" was too strong. It's just that recent news are more focused on browsers and OS implementation (DoH support in Windows 11 / Server 2022 for instance).

Both exists and both implementation are needed. It's just that we need to pick one and start on it.

Indigo744 avatar Feb 24 '22 16:02 Indigo744

Hi @jol64 and @Indigo744 I did some testing for DoH manually a while ago. The problem there is that we'd have to rely on HttpClient. The biggest problem I'd have to solve is to manage the lifetime of the HttpClient.

The only implementation for properly managing HttpClients so far is IHttpClientFactory which is in one of those Microsoft extension packages. I'm not going to include that package as a dependency in DnsClient though, that would be too much in my opinion.

So, I'm looking for a good idea / API approach for that which does not involve any other 3rd part dependency - if you guys have a good idea, let me know

MichaCo avatar Feb 24 '22 16:02 MichaCo

@MichaCo would HttpClient itself be ok? I learned that Cloudflare closes the connection after every single DoT request. I´d consider that a bug, but so far that doesn´t seem a big issue to them and therefore I´d say using the same client only for a single request isn´t a showstopper, no matter whether it is DoT or DoH. Of course you can also define a transport abstraction interface that can be implemented somewhere else, may be pass that optionally to the DnsClient constructor. Then a heavy user could implement connection pooling etc...

jol64 avatar Feb 24 '22 16:02 jol64

In our codebase we use RestClient from Easy.Common. But then again it's another dependency.

We could implement an internal RestClient based on this with only the parts we're interested in. It shouldn't be too hard I guess.

Indigo744 avatar Feb 24 '22 17:02 Indigo744

@Indigo744 After looking at RestClient, that's just a wrapper for HttpClient and doesn't take care of lifetime of the message handler either. Not sure how that would help ;)

@jol64 using a new HttpClient instance per request is the worst thing you can do. Your OS will run out of sockets in no time. If you are interested in more details (socket issues and stale DNS issues with HttpClient), there are a bunch of good blog posts and MS docs explaining why IHttpClientFactory exists

MichaCo avatar Feb 25 '22 01:02 MichaCo

@MichaCo yeah sorry I didn't read properly your message and replied too quickly.

I can think of 2 options:

  1. Having a CTOR accepting an optional HttpClient in case the user wants to provide an application-wide static one,

  2. Implementing using IHttpClientFactory, but to avoid forcing this dependency for every users, it is implemented in another project in another namespace, published as another nuget (DnsClient.DnsOverHttps for instance),

Thoughts?

Indigo744 avatar Feb 25 '22 21:02 Indigo744

I think maybe you can let users pass in their own httpclient? My project has its own HttpClientFactory to unify the life cycle of httpclient, maybe you can consider supporting users to pass in their own httpclient?

rmbadmin avatar Nov 12 '22 16:11 rmbadmin

It would be great if it supports DoH. I have some needs about it.

chn-lee-yumi avatar Nov 14 '22 11:11 chn-lee-yumi

My project for this weekend was https://github.com/nd1012/wan24-DNS , and I'd like to attach to this issue, 'cause my future plans for the project are looking forward to add DoH support, and I'd really love to use your library for that, if possible.

About the HttpClient issue: I think it's difficult to add pre-defined HttpClient usage to a library, 'cause a library may be used in any environment, and every environment may require to handle HttpClient instances (or the underlying connections) in a different way.

For this reason I'd like to suggest that your library implements a simple default factory, but supports (and recommends) a custom factory also. There should also be an option which tells your code if a HttpClient instance, which was provided from a factory, should be disposed or not.

But in total, as you'd not like to reference an additional package, you'd have to separate DoH support into an own extension library, and open the API of this library to make it even possible to extend it in the way which would be required to allow plugin processing. Which is not a trivial task, I'd say. More a release 2.0.0.

Another option would be to use a different http client implementation (which would also imply to reference another package) - nah, that's not really an option, as this would blow up your package a lot for sure.

Anyway, I'm looking forward to use DnsClient.NET for DoH in the future, too! Hope there is a good solution. Maybe a HttpClient object pool? I think I'd not be too hard to implement an own HttpClientPool, which manages HttpClient lifetime in the way Microsoft does, but doesn't need to reference any package snail.

nd1012 avatar Oct 29 '23 11:10 nd1012

@MichaCo I implemented rudimentary DoT support in a local copy, primarily as part of my monitoring application. Essentially I

  • created class NamedIPEndPoint : IPEndPoint that provides the hostname for authentication and server name indication when connecting to the DoT server
  • modified one line in LookupClient: _tcpFallbackHandler = tcpHandler ?? (options.NameServers[0].IPEndPoint is NamedIPEndPoint ? new DnsDotMessageHandler() : new DnsTcpMessageHandler());
  • implemented a rudimentary DnsDotMessageHandler.Query, ignoring async and CancelationToken as I don´t need that in my application, but connecting to a given NamedIPEndPoint, starting TLS, sending request and parsing responses. Most of the last two steps are quick&dirty copy&paste from DnsTcpMessageHandler.QueryInternal(...). I didn´t care about pooling or connection reuse, as afaik that´s not used and I also have no need in my application
  • when creating LookupClientOptions I am passing UseTcpOnly=true.

I could share this as a starting point in case you are interested. The redundancy of copy&paste could be reduced by replacing TcpClient in DnsTcpMessageHandler.QueryInternal with a kind of facade to the NetworkStream (my copy uses two args, one NetworkStream, one SslStream/Stream). A similar approach could be used if connection pooling shall be supported. UseTcpOnly could be implicit for NamedIPEndPoint..

jol64 avatar Feb 10 '24 15:02 jol64