PowerDNS / pdns

PowerDNS Authoritative, PowerDNS Recursor, dnsdist
https://www.powerdns.com/
GNU General Public License v2.0
3.7k stars 909 forks source link

DoH and DoT on the same IP:port via distinct SNIs #9063

Open appliedprivacy opened 4 years ago

appliedprivacy commented 4 years ago

Short description

IPv4 addresses are rare, but at the same time we want to offer DoH and DoT on TCP port 443 since this is the most likely reachable port for many users in many network environments. Such a setup is not currently possible.

Usecase

Currently we use nginx in front of dnsdist to allow DoT and DoH on a single IP:port.

--> ngnix (SNI demultiplexing but does not terminate TLS connection) --> dnsdist --> resolver

On the long run we would like to remove the nginx dependency.

Description

Example: Both hostnames bellow point to the same IP address(es)

To decide where to route the incoming connection (DoH or DoT request?) the SNI is inspected and matched with the configuration that tells dnsdist what SNI is used for what protocol. In case of a DoH connection, the request is routed to libh2o. So the code of this new feature would be a shim in front of the current listeners.

This topic was previously mentioned on the dnsdist mailing list in June 2019: https://mailman.powerdns.com/pipermail/dnsdist/2019-June/000562.html

RobinGeuze commented 4 years ago

Wouldn't ALPN be a much nicer solution for this? I mean, that is specifically meant for this.

Habbie commented 4 years ago

https://mailarchive.ietf.org/arch/msg/dns-privacy/iZ2rDIhFB2ZWsGC3PcdBVLGa8Do/

rgacogne commented 4 years ago

To decide where to route the incoming connection (DoH or DoT request?) the SNI is inspected and matched with the configuration that tells dnsdist what SNI is used for what protocol. In case of a DoH connection, the request is routed to libh2o.

That looks good in theory, but that means we need to handle the start of the TLS session outside of libh2o then somehow feed it the state when we decide that it looks like DoH. Or to handle DoT inside libh2o as well then somehow tell libh2o to stop handling the socket and transfer the state back to us. I'm not aware of any clean way to do that, but patches are welcome :)

johnhtodd commented 4 years ago

As a side note: would this be a bit more useful if it was possible to then use SNI to signal between different policy regimens inside of dnsdist, as well as different protocols? Or would that be specific to the protocol? (i.e.: "dot-adultfilter.example.com" and "dot-nofiltering.example.com" and "doh-customer1.example.com" all resolving to the same address, and allowing dnsdist to treat them differently based on SNI.

rgacogne commented 4 years ago

As a side note: would this be a bit more useful if it was possible to then use SNI to signal between different policy regimens inside of dnsdist, as well as different protocols? Or would that be specific to the protocol? (i.e.: "dot-adultfilter.example.com" and "dot-nofiltering.example.com" and "doh-customer1.example.com" all resolving to the same address, and allowing dnsdist to treat them differently based on SNI.

If I'm correctly understanding what you want to do, dnsdist has the SNIRule for that since 1.4.0 :-)