-
Notifications
You must be signed in to change notification settings - Fork 249
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
[guide section]: How to customize TLS #469
Comments
I previously raised #334 and later ca-certs was added which I thought I could follow. I need to do this behind a proxy and I have tried to add This means I'm back to attempting to configure native-tls with a custom root cert. I just can't work out the right combination of types. The closest I've gotten is below but this doesn't compile. Some better documentation would really be appreciated here. use std::{fs::File, env};
use std::io::BufReader;
use aws_config::provider_config::ProviderConfig;
use aws_config::profile::ProfileFileCredentialsProvider;
use aws_sdk_s3::Region;
use aws_smithy_client::hyper_ext;
use hyper::Client;
use hyper_proxy::{Proxy, Intercept, ProxyConnector};
use hyper_tls::HttpsConnector;
use native_tls::Certificate;
use std::path::Path;
fn load_ca_cert(pem_file: &Path) -> Result<Certificate, CertLoadError> {
use std::fs;
let bytes =
fs::read(pem_file).map_err(|e| CertLoadError::Io(format!("Loading {:?}", pem_file), e))?;
Certificate::from_pem(&bytes).map_err(CertLoadError::TlsError)
}
#[derive(Debug)]
enum CertLoadError {
TlsError(native_tls::Error),
Io(String, std::io::Error),
}
#[tokio::main]
async fn main() {
env_logger::init();
// insert your root CAs
let certificate: native_tls::Certificate =
load_ca_cert(&Path::new("/etc/ssl/certs/ca-certificates.crt")).expect("Failed to load your CA cert");
let native_tls_connector = native_tls::TlsConnector::builder()
.add_root_certificate(certificate)
.build()
.expect("Building native_tls::TlsConnector");
let tokio_tls_tls_connector = tokio_native_tls::TlsConnector::from(native_tls_connector);
let mut hyper_http_connector = hyper::client::HttpConnector::new();
hyper_http_connector.enforce_http(false);
let hyper_tls_https_connector = hyper_tls::HttpsConnector::from((
hyper_http_connector,
tokio_tls_tls_connector,
));
let client_main = Client::builder().build::<_, hyper::Body>(hyper_tls_https_connector);
let https_proxy = env::var("https_proxy").unwrap();
let proxy_uri = https_proxy.replace("http", "https").parse().unwrap();
let proxy = Proxy::new(Intercept::All, proxy_uri);
let pc = ProxyConnector::from_proxy(tokio_tls_tls_connector, proxy).unwrap();
let profile_creds = ProfileFileCredentialsProvider::builder()
.profile_name("profile-name")
.build();
// Currently, aws_config connectors are buildable directly from something that implements `hyper::Connect`.
// This enables different providers to construct clients with different timeouts.
let provider_config = ProviderConfig::default()
.with_tcp_connector(pc.clone());
let shared_conf = aws_config::from_env()
.region(Region::new("us-east-1"))
.credentials_provider(profile_creds)
.configure(provider_config)
.load()
.await;
let s3_config = aws_sdk_s3::Config::from(&shared_conf);
// however, for generated clients, they are constructred from a Hyper adapter directly:
let s3_client = aws_sdk_s3::Client::from_conf_conn(
s3_config,
hyper_ext::Adapter::builder().build(pc),
);
let buckets = s3_client.list_buckets().send().await.unwrap();
let items = buckets.buckets().unwrap();
print!("buckets: {}", items[0].name.clone().unwrap());
} |
is it possible to add a DNS name to |
Unfortunately I don't have write access to |
@rcoh sorry I'm still having trouble working this all out. I'm trying to find an example of specifying a custom DNS resolver for Hyper but I've not managed to find much documentation on this. I don't suppose you have a link to an example or pointer in the right direction? |
does this help? https://docs.rs/hyper/latest/hyper/client/connect/index.html |
Sorry, I'm afraid not. I was aware of the above documentation and I really appreciate you patience but it's not clear to me how one would go about combining the below code with the custom DNS resolver example. The hyper client itself appears to be hidden behind layers of other abstraction for aws_smithy, Proxy and rust_tls. use std::{fs, io};
use std::{fs::File, env};
use std::io::BufReader;
use aws_config::provider_config::ProviderConfig;
use aws_config::profile::ProfileFileCredentialsProvider;
use aws_sdk_s3::Region;
use aws_smithy_client::hyper_ext;
use hyper_proxy::{Proxy, Intercept, ProxyConnector};
use rustls::{RootCertStore, Certificate, internal::msgs::codec::Codec};
use rustls_pemfile::certs;
#[tokio::main]
async fn main() {
env_logger::init();
// insert your root CAs
let f = File::open("/etc/ssl/certs/ca-certificates.crt").unwrap();
let mut reader = BufReader::new(f);
let mut root_store = RootCertStore::empty();
for cert in certs(&mut reader).unwrap() {
root_store.add(&Certificate(cert));
}
let config = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_store)
.with_no_client_auth();
let rustls_connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_tls_config(config.clone())
.https_only()
.enable_http1()
.enable_http2()
.build();
let https_proxy = env::var("https_proxy").unwrap();
let proxy_uri = https_proxy.replace("http", "https").parse().unwrap();
let proxy = Proxy::new(Intercept::All, proxy_uri);
let pc = ProxyConnector::from_proxy(rustls_connector, proxy).unwrap();
let profile_creds = ProfileFileCredentialsProvider::builder()
.profile_name("fiaim-deployer-dev")
.build();
// Currently, aws_config connectors are buildable directly from something that implements `hyper::Connect`.
// This enables different providers to construct clients with different timeouts.
// let provider_config = ProviderConfig::default()
// .with_tcp_connector(pc.clone());
let provider_config = ProviderConfig::default();
let shared_conf = aws_config::from_env()
.region(Region::new("us-east-1"))
.credentials_provider(profile_creds)
.configure(provider_config)
.load()
.await;
let s3_config = aws_sdk_s3::Config::from(&shared_conf);
// however, for generated clients, they are constructred from a Hyper adapter directly:
let s3_client = aws_sdk_s3::Client::from_conf_conn(
s3_config,
hyper_ext::Adapter::builder().build(pc),
);
let buckets = s3_client.list_buckets().send().await.unwrap();
let items = buckets.buckets().unwrap();
print!("buckets: {}", items[0].name.clone().unwrap());
} I fear I may be fundamentally misunderstanding. |
I'll see if I can whip up an example, but I think you want this: https://docs.rs/hyper-rustls/latest/hyper_rustls/struct.HttpsConnectorBuilder.html#method.wrap_connector-1 Which will enable you to drop in your own custom |
here's a snippet that compiles for me in the context of the larger example you posted above. use std::net::SocketAddr;
use std::iter;
use hyper::client::HttpConnector
// ... snip ...
let config = rustls::ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(root_store)
.with_no_client_auth();
let resolver = tower::service_fn(|_name| async {
// update to _always_ return the corp IP address. This will enable you to pass in a DNS
// name but will always return your corp IP address
Ok::<_, Infallible>(iter::once(SocketAddr::from(([127, 0, 0, 1], 8080))))
});
let http_conector = HttpConnector::new_with_resolver(resolver);
let rustls_connector = hyper_rustls::HttpsConnectorBuilder::new()
.with_tls_config(config.clone())
.https_only()
.enable_http1()
.wrap_connector(http_conector); |
that's great, thanks. It makes sense now. It's compiling fine but panicking now I'll keep digging. Thanks again. |
I just had to turn off |
A note for the community
Community Note
Tell us about your request
Tell us about the problem you're trying to solve.
N/A
Are you currently working around this issue?
N/A
Additional context
No response
The text was updated successfully, but these errors were encountered: