From 51e2a0d05b607e3eae32adfa7a4fb95374939908 Mon Sep 17 00:00:00 2001 From: Christof Weickhardt Date: Wed, 13 Apr 2022 14:53:37 +0000 Subject: [PATCH] feat: use rustls --- Cargo.toml | 24 ++++++++++++++++-------- README.md | 32 ++++++++++++++++++++++++++++++++ src/lib.rs | 19 +++++++++++++++---- 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3798bdd..401b339 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,19 +19,27 @@ include = [ ] [dependencies] -hyper = { version = "0.14", features = ["full"] } -lazy_static = "1.4" -hyper-tls = { version = "0.5", optional = true } +hyper = { version = "0.14.18", features = ["full"] } +hyper-trust-dns = { version = "0.4.2", optional = true, default-features = false, features = ["rustls-webpki", "rustls-http1"] } +lazy_static = "1.4.0" rand = "0.8.5" [dev-dependencies] -tokio = { version = "1", features = ["full"] } -futures = "0.3" -async-trait = "0.1" +tokio = { version = "1.17.0", features = ["full"] } +futures = "0.3.21" +async-trait = "0.1.53" tokio-test = "0.4.2" test-context = "0.1.3" -tokiotest-httpserver = "0.2.0" +tokiotest-httpserver = "0.2.1" [features] -https = ["hyper-tls"] default = ["https"] + +https = ["hyper-trust-dns", "dnssec", "hyper-trust-dns/rustls-webpki", "http2"] +doh = ["hyper-trust-dns/dns-over-https-rustls"] +dot = ["hyper-trust-dns/dns-over-rustls"] +dnssec = ["hyper-trust-dns/dnssec-ring"] +http2 = ["hyper/http2", "hyper-trust-dns/rustls-http2"] +https-only = ["hyper-trust-dns/https-only"] +tls-1-2 = ["hyper-trust-dns/rustls-tls-12"] +native-cert-store = ["hyper-trust-dns/rustls-native"] diff --git a/README.md b/README.md index 946a815..0deb0a6 100644 --- a/README.md +++ b/README.md @@ -103,3 +103,35 @@ async fn main() { } } ``` + +### Security + +Handling outgoing requests can be a security nightmare. This crate includes some features to reduce some of the risks. Everthing uses `rustls` benieth, a rust implementation for tls, faster and more secure as `openssl` + +#### HTTPS + +By default the `https` feature is enabled which will allow you to request resources over https. This does not limit to only `https` traffic, if you would like so add the feature `https-only` to your `Cargo.toml` for this crate. + +#### TLS 1.2 + +By default `tls 1.2` is disabled in favor of `tls 1.3`. As not yet all services support it `tls 1.2` can be enabled via the `tls-1-2` feature. + +#### DNSSEC + +By default if you enable `https` (which is enabled by default) `dnssec` is enabled. + +#### HTTP/2 + +While `http/3` might be just around the corner. `http/2` support can be enabled using the `http2` feature. + +#### DoT & DoH + +By default none of them are enabled. If you would like to enabled them, you can do so using the features `doh` and `dot`. + +Recommendations: + - If you need to monitor network activities in relation to accessed ports, use `dot` + - If you are out in the wild and have no need to monitor based on ports, use `doh` as it will blend in with other `https` traffic + +It is highly recommended to use one of them. + +> Currently only includes dns queries as `esni` or `ech` is still in draft by the `ietf` \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 78789cd..47acf73 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -99,11 +99,16 @@ #[cfg(all(not(stable), test))] extern crate test; +#[cfg(feature = "https")] +use hyper_trust_dns::TrustDnsResolver; + +#[cfg(not(feature = "https"))] use hyper::client::{connect::dns::GaiResolver, HttpConnector}; -use hyper::header::{HeaderName, HeaderValue, HOST}; + +use hyper::header::{HeaderMap, HeaderName, HeaderValue, HOST}; use hyper::http::header::{InvalidHeaderValue, ToStrError}; use hyper::http::uri::InvalidUri; -use hyper::{Body, Client, Error, HeaderMap, Request, Response}; +use hyper::{Body, Client, Error, Request, Response}; use lazy_static::lazy_static; use std::net::IpAddr; @@ -242,6 +247,7 @@ fn create_proxied_request( let upgrade_type = get_upgrade_type(request.headers()); let uri: hyper::Uri = forward_uri(forward_url, &request).parse()?; + request .headers_mut() .insert(HOST, HeaderValue::from_str(uri.host().unwrap())?); @@ -288,8 +294,13 @@ fn create_proxied_request( } #[cfg(feature = "https")] -fn build_client() -> Client>, hyper::Body> { - let https = hyper_tls::HttpsConnector::new(); +fn build_client() -> Client { + #[cfg(feature = "native-cert-store")] + let https = TrustDnsResolver::default().into_rustls_native_https_connector(); + + #[cfg(not(feature = "native-cert-store"))] + let https = TrustDnsResolver::default().into_rustls_webpki_https_connector(); + Client::builder().build::<_, hyper::Body>(https) }