Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
jol64 opened this issue Dec 11, 2020 · 14 comments
Open

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

jol64 opened this issue Dec 11, 2020 · 14 comments

Comments

@jol64
Copy link

jol64 commented Dec 11, 2020

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

@MichaCo
Copy link
Owner

MichaCo commented Feb 8, 2021

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.

@Indigo744
Copy link

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.

@jol64
Copy link
Author

jol64 commented Feb 24, 2022

@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.

@Indigo744
Copy link

@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.

@MichaCo
Copy link
Owner

MichaCo commented Feb 24, 2022

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

@jol64
Copy link
Author

jol64 commented Feb 24, 2022

@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...

@Indigo744
Copy link

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.

@MichaCo
Copy link
Owner

MichaCo commented Feb 25, 2022

@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

@Indigo744
Copy link

@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?

@rmbadmin
Copy link

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?

@chn-lee-yumi
Copy link

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

@nd1012
Copy link

nd1012 commented Oct 29, 2023

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.

@jol64
Copy link
Author

jol64 commented Feb 10, 2024

@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..

@deepak-nawathe
Copy link

@MichaCo I am using DnsClient.NET and working out quite well, however, now DoT and DoH capabilities are a must. So, any plans or ETA for DoT at least?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants