fix dns over TLS and HTTPS

This commit is contained in:
erebe 2024-06-19 20:34:53 +00:00 committed by Σrebe - Romain GERARD
parent fb378d29d5
commit 7165f328a8
No known key found for this signature in database
GPG key ID: 7A42B4B97E0332F4
4 changed files with 48 additions and 17 deletions

20
Cargo.lock generated
View file

@ -305,7 +305,7 @@ dependencies = [
"log", "log",
"pin-project-lite", "pin-project-lite",
"rustls 0.22.4", "rustls 0.22.4",
"rustls-native-certs", "rustls-native-certs 0.7.0",
"rustls-pemfile 2.1.2", "rustls-pemfile 2.1.2",
"rustls-pki-types", "rustls-pki-types",
"serde", "serde",
@ -983,6 +983,7 @@ dependencies = [
"once_cell", "once_cell",
"rand", "rand",
"rustls 0.21.12", "rustls 0.21.12",
"rustls-native-certs 0.6.3",
"rustls-pemfile 1.0.4", "rustls-pemfile 1.0.4",
"thiserror", "thiserror",
"tinyvec", "tinyvec",
@ -1008,6 +1009,7 @@ dependencies = [
"rand", "rand",
"resolv-conf", "resolv-conf",
"rustls 0.21.12", "rustls 0.21.12",
"rustls-native-certs 0.6.3",
"smallvec", "smallvec",
"thiserror", "thiserror",
"tokio", "tokio",
@ -1140,7 +1142,7 @@ dependencies = [
"hyper-util", "hyper-util",
"log", "log",
"rustls 0.22.4", "rustls 0.22.4",
"rustls-native-certs", "rustls-native-certs 0.7.0",
"rustls-pki-types", "rustls-pki-types",
"tokio", "tokio",
"tokio-rustls 0.25.0", "tokio-rustls 0.25.0",
@ -2002,6 +2004,18 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "rustls-native-certs"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
dependencies = [
"openssl-probe",
"rustls-pemfile 1.0.4",
"schannel",
"security-framework",
]
[[package]] [[package]]
name = "rustls-native-certs" name = "rustls-native-certs"
version = "0.7.0" version = "0.7.0"
@ -3091,7 +3105,7 @@ dependencies = [
"pin-project", "pin-project",
"ppp", "ppp",
"regex", "regex",
"rustls-native-certs", "rustls-native-certs 0.7.0",
"rustls-pemfile 2.1.2", "rustls-pemfile 2.1.2",
"scopeguard", "scopeguard",
"serde", "serde",

View file

@ -18,7 +18,7 @@ clap = { version = "4.5.6", features = ["derive", "env"] }
fast-socks5 = { version = "0.9.6", features = [] } fast-socks5 = { version = "0.9.6", features = [] }
fastwebsockets = { version = "0.7.2", features = ["upgrade", "simd", "unstable-split"] } fastwebsockets = { version = "0.7.2", features = ["upgrade", "simd", "unstable-split"] }
futures-util = { version = "0.3.30" } futures-util = { version = "0.3.30" }
hickory-resolver = { version = "0.24.1", features = ["tokio", "dns-over-https-rustls", "dns-over-rustls"] } hickory-resolver = { version = "0.24.1", features = ["tokio", "dns-over-https-rustls", "dns-over-rustls", "native-certs"] }
ppp = { version = "2.2.0", features = [] } ppp = { version = "2.2.0", features = [] }
# For config file parsing # For config file parsing

View file

@ -1,6 +1,6 @@
use anyhow::anyhow; use anyhow::{anyhow, Context};
use futures_util::FutureExt; use futures_util::FutureExt;
use hickory_resolver::config::{NameServerConfig, ResolverConfig, ResolverOpts}; use hickory_resolver::config::{NameServerConfig, Protocol, ResolverConfig, ResolverOpts};
use hickory_resolver::name_server::{GenericConnector, RuntimeProvider, TokioRuntimeProvider}; use hickory_resolver::name_server::{GenericConnector, RuntimeProvider, TokioRuntimeProvider};
use hickory_resolver::proto::iocompat::AsyncIoTokioAsStd; use hickory_resolver::proto::iocompat::AsyncIoTokioAsStd;
use hickory_resolver::proto::TokioTime; use hickory_resolver::proto::TokioTime;
@ -67,10 +67,24 @@ impl DnsResolver {
// otherwise, use the specified resolvers // otherwise, use the specified resolvers
let mut cfg = ResolverConfig::new(); let mut cfg = ResolverConfig::new();
for resolver in resolvers.iter() { for resolver in resolvers.iter() {
let (protocol, port) = match resolver.scheme() { let (protocol, port, tls_sni) = match resolver.scheme() {
"dns" => (hickory_resolver::config::Protocol::Udp, resolver.port().unwrap_or(53)), "dns" => (Protocol::Udp, resolver.port().unwrap_or(53), None),
"dns+https" => (hickory_resolver::config::Protocol::Https, resolver.port().unwrap_or(443)), "dns+https" => {
"dns+tls" => (hickory_resolver::config::Protocol::Tls, resolver.port().unwrap_or(853)), let tls_sni = resolver
.query_pairs()
.find(|(k, _)| k == "sni")
.with_context(|| "Missing `sni` query parameter for dns over https")?
.1;
(Protocol::Https, resolver.port().unwrap_or(443), Some(tls_sni.to_string()))
}
"dns+tls" => {
let tls_sni = resolver
.query_pairs()
.find(|(k, _)| k == "sni")
.with_context(|| "Missing `sni` query parameter for dns over tls")?
.1;
(Protocol::Tls, resolver.port().unwrap_or(853), Some(tls_sni.to_string()))
}
_ => return Err(anyhow!("invalid protocol for dns resolver")), _ => return Err(anyhow!("invalid protocol for dns resolver")),
}; };
let host = resolver let host = resolver
@ -87,7 +101,10 @@ impl DnsResolver {
Host::Ipv4(ip) => SocketAddr::V4(SocketAddrV4::new(ip, port)), Host::Ipv4(ip) => SocketAddr::V4(SocketAddrV4::new(ip, port)),
Host::Ipv6(ip) => SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0)), Host::Ipv6(ip) => SocketAddr::V6(SocketAddrV6::new(ip, port, 0, 0)),
}; };
cfg.add_name_server(NameServerConfig::new(sock, protocol))
let mut ns = NameServerConfig::new(sock, protocol);
ns.tls_dns_name = tls_sni;
cfg.add_name_server(ns);
} }
let mut opts = ResolverOpts::default(); let mut opts = ResolverOpts::default();
@ -174,4 +191,4 @@ impl RuntimeProvider for TokioRuntimeProviderWithSoMark {
Box::pin(socket) Box::pin(socket)
} }
} }

View file

@ -248,8 +248,8 @@ struct Client {
/// Dns resolver to use to lookup ips of domain name. Can be specified multiple time /// Dns resolver to use to lookup ips of domain name. Can be specified multiple time
/// Example: /// Example:
/// dns://1.1.1.1 for using udp /// dns://1.1.1.1 for using udp
/// dns+https://1.1.1.1 for using dns over HTTPS /// dns+https://1.1.1.1?sni=loudflare-dns.com for using dns over HTTPS
/// dns+tls://8.8.8.8 for using dns over TLS /// dns+tls://8.8.8.8?sni=dns.google for using dns over TLS
/// To use libc resolver, use /// To use libc resolver, use
/// system://0.0.0.0 /// system://0.0.0.0
/// ///
@ -286,8 +286,8 @@ struct Server {
/// Can be specified multiple time /// Can be specified multiple time
/// Example: /// Example:
/// dns://1.1.1.1 for using udp /// dns://1.1.1.1 for using udp
/// dns+https://1.1.1.1 for using dns over HTTPS /// dns+https://1.1.1.1?sni=loudflare-dns.com for using dns over HTTPS
/// dns+tls://8.8.8.8 for using dns over TLS /// dns+tls://8.8.8.8?sni=dns.google for using dns over TLS
/// To use libc resolver, use /// To use libc resolver, use
/// system://0.0.0.0 /// system://0.0.0.0
#[arg(long, verbatim_doc_comment)] #[arg(long, verbatim_doc_comment)]
@ -1316,4 +1316,4 @@ async fn main() {
} }
tokio::signal::ctrl_c().await.unwrap(); tokio::signal::ctrl_c().await.unwrap();
} }