From 9fe38ed41508bfc3b733aaaecbce950671706b77 Mon Sep 17 00:00:00 2001 From: Conrad Ludgate Date: Wed, 24 Apr 2024 12:44:22 +0100 Subject: [PATCH] aws dns --- Cargo.lock | 23 +++++++++++++++++++++-- Cargo.toml | 1 + proxy/Cargo.toml | 9 ++++++++- proxy/src/bin/proxy.rs | 40 ++++++++++++++++++++++++++++++++++++++-- proxy/src/dns.rs | 22 +++++++++++++++++++++- 5 files changed, 89 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 956573b274..862217ada6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -595,7 +595,7 @@ dependencies = [ "http 0.2.9", "http-body 0.4.5", "hyper 0.14.26", - "hyper-rustls", + "hyper-rustls 0.24.0", "once_cell", "pin-project-lite", "pin-utils", @@ -2582,6 +2582,23 @@ dependencies = [ "tokio-rustls 0.24.0", ] +[[package]] +name = "hyper-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "399c78f9338483cb7e630c8474b07268983c6bd5acee012e4211f9f7bb21b070" +dependencies = [ + "futures-util", + "http 0.2.9", + "hyper 0.14.26", + "log", + "rustls 0.22.4", + "rustls-native-certs 0.7.0", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.25.0", +] + [[package]] name = "hyper-timeout" version = "0.4.1" @@ -4387,6 +4404,7 @@ dependencies = [ "aws-config", "aws-sdk-iam", "aws-sigv4", + "aws-smithy-runtime", "aws-types", "base64 0.13.1", "bstr", @@ -4412,6 +4430,7 @@ dependencies = [ "humantime", "hyper 0.14.26", "hyper 1.2.0", + "hyper-rustls 0.25.0", "hyper-tungstenite", "hyper-util", "ipnet", @@ -4787,7 +4806,7 @@ dependencies = [ "http 0.2.9", "http-body 0.4.5", "hyper 0.14.26", - "hyper-rustls", + "hyper-rustls 0.24.0", "hyper-tls", "ipnet", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index a7a277bf98..23dc344dcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,6 +57,7 @@ aws-sdk-s3 = "1.14" aws-sdk-iam = "1.15.0" aws-smithy-async = { version = "1.1.4", default-features = false, features=["rt-tokio"] } aws-smithy-types = "1.1.4" +aws-smithy-runtime = "1.1.8" aws-credential-types = "1.1.4" aws-sigv4 = { version = "1.2.0", features = ["sign-http"] } aws-types = "1.1.7" diff --git a/proxy/Cargo.toml b/proxy/Cargo.toml index f1070895fc..2713365109 100644 --- a/proxy/Cargo.toml +++ b/proxy/Cargo.toml @@ -16,6 +16,7 @@ atomic-take.workspace = true aws-config.workspace = true aws-sdk-iam.workspace = true aws-sigv4.workspace = true +aws-smithy-runtime.workspace = true aws-types.workspace = true base64.workspace = true bstr.workspace = true @@ -38,8 +39,14 @@ http.workspace = true humantime.workspace = true hyper-tungstenite.workspace = true hyper.workspace = true +hyper-rustls = { version = "0.25.0", features = ["rustls-native-certs", "http1", "http2"] } hyper1 = { package = "hyper", version = "1.2", features = ["server"] } -hyper-util = { version = "0.1", features = ["server", "http1", "http2", "tokio"] } +hyper-util = { version = "0.1", features = [ + "server", + "http1", + "http2", + "tokio", +] } http-body-util = { version = "0.1" } ipnet.workspace = true itertools.workspace = true diff --git a/proxy/src/bin/proxy.rs b/proxy/src/bin/proxy.rs index f75408e07d..1fbf65c1cf 100644 --- a/proxy/src/bin/proxy.rs +++ b/proxy/src/bin/proxy.rs @@ -5,7 +5,10 @@ use aws_config::meta::region::RegionProviderChain; use aws_config::profile::ProfileFileCredentialsProvider; use aws_config::provider_config::ProviderConfig; use aws_config::web_identity_token::WebIdentityTokenCredentialsProvider; +use aws_smithy_runtime::client::http::hyper_014::HyperClientBuilder; use futures::future::Either; +use hyper::client::HttpConnector; +use hyper_rustls::ConfigBuilderExt; use proxy::auth; use proxy::auth::backend::AuthRateLimiter; use proxy::auth::backend::MaybeOwned; @@ -34,6 +37,7 @@ use proxy::usage_metrics; use anyhow::bail; use proxy::config::{self, ProxyConfig}; use proxy::serverless; +use rustls::crypto::CryptoProvider; use std::net::SocketAddr; use std::pin::pin; use std::sync::Arc; @@ -271,8 +275,40 @@ async fn main() -> anyhow::Result<()> { info!("Using region: {}", config.aws_region); let region_provider = RegionProviderChain::default_provider().or_else(&*config.aws_region); // Replace with your Redis region if needed - let provider_conf = - ProviderConfig::without_region().with_region(region_provider.region().await); + + let aws_tls_client_config = + rustls::ClientConfig::builder_with_provider(Arc::new(CryptoProvider { + cipher_suites: vec![ + // TLS1.3 suites + rustls::crypto::ring::cipher_suite::TLS13_AES_256_GCM_SHA384, + rustls::crypto::ring::cipher_suite::TLS13_AES_128_GCM_SHA256, + // TLS1.2 suites + rustls::crypto::ring::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + rustls::crypto::ring::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + rustls::crypto::ring::cipher_suite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + rustls::crypto::ring::cipher_suite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + rustls::crypto::ring::cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + ], + ..rustls::crypto::ring::default_provider() + })) + .with_safe_default_protocol_versions() + .unwrap() + .with_native_roots()? + .with_no_client_auth(); + + let provider_conf = ProviderConfig::without_region() + .with_region(region_provider.region().await) + .with_http_client( + HyperClientBuilder::new().build( + hyper_rustls::HttpsConnectorBuilder::new() + .with_tls_config(aws_tls_client_config) + .https_or_http() + .enable_http1() + .enable_http2() + .wrap_connector(HttpConnector::new_with_resolver(config.dns.clone())), + ), + ); + let aws_credentials_provider = { // uses "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY" CredentialsProviderChain::first_try("env", EnvironmentVariableCredentialsProvider::new()) diff --git a/proxy/src/dns.rs b/proxy/src/dns.rs index ffe3bf9b95..c0aaa91bd4 100644 --- a/proxy/src/dns.rs +++ b/proxy/src/dns.rs @@ -5,7 +5,10 @@ use std::{ sync::Arc, }; +use aws_sdk_iam::error::BoxError; use hickory_resolver::{error::ResolveError, proto::rr::RData}; +use hyper::client::connect::dns::Name; +use reqwest::dns::Addrs; use tokio::time::Instant; use tracing::trace; @@ -61,8 +64,25 @@ impl Dns { } } +impl hyper::service::Service for Dns { + type Response = Addrs; + type Error = BoxError; + type Future = reqwest::dns::Resolving; + + fn poll_ready( + &mut self, + _cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + std::task::Poll::Ready(Ok(())) + } + + fn call(&mut self, req: Name) -> Self::Future { + reqwest::dns::Resolve::resolve(self, req) + } +} + impl reqwest::dns::Resolve for Dns { - fn resolve(&self, name: hyper::client::connect::dns::Name) -> reqwest::dns::Resolving { + fn resolve(&self, name: Name) -> reqwest::dns::Resolving { let this = self.clone(); Box::pin(async move { match this.resolve(name.as_str()).await {