Skip to content

Commit

Permalink
add support for extra ca certs (#470)
Browse files Browse the repository at this point in the history
* add support for extra ca certs

* remove unnecessary deref call

* add warning message for failing to read cert file

* add extra ca certs info to the readme

* throw an exception if extra ca certs file cannot be opened

* use io result

* wrap http client in io result
  • Loading branch information
georgesmith46 authored Jul 15, 2024
1 parent 13b23a0 commit 9e8dc2e
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 24 deletions.
35 changes: 26 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,11 @@ Then run llrt:
make run
## Environment Variables
### `LLRT_EXTRA_CA_CERTS=file`
Load extra certificate authorities from a PEM encoded file
## Benchmark Methodology
Although Init Duration [reported by Lambda](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtime-environment.html) is commonly used to understand cold start impact on overall request latency, this metric does not include the time needed to copy code into the Lambda sandbox.
Expand Down
1 change: 1 addition & 0 deletions llrt_core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ flate2 = { version = "1.0.30", features = [
], default-features = false }
brotlic = "0.8.2"
encoding_rs = "0.8.34"
rustls-pemfile = "2.1.2"

[build-dependencies]
rquickjs = { version = "0.6.2", features = [
Expand Down
1 change: 1 addition & 0 deletions llrt_core/src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub const ENV_LLRT_NET_DENY: &str = "LLRT_NET_DENY";
pub const ENV_LLRT_NET_POOL_IDLE_TIMEOUT: &str = "LLRT_NET_POOL_IDLE_TIMEOUT";
pub const ENV_LLRT_HTTP_VERSION: &str = "LLRT_HTTP_VERSION";
pub const ENV_LLRT_TLS_VERSION: &str = "LLRT_TLS_VERSION";
pub const ENV_LLRT_EXTRA_CA_CERTS: &str = "LLRT_EXTRA_CA_CERTS";

//log
pub const ENV_LLRT_LOG: &str = "LLRT_LOG";
Expand Down
2 changes: 1 addition & 1 deletion llrt_core/src/modules/http/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub(crate) fn init(ctx: &Ctx<'_>, globals: &Object) -> Result<()> {
}

//init eagerly
let client = &*HTTP_CLIENT;
let client = HTTP_CLIENT.as_ref().or_throw(ctx)?;

globals.set(
"fetch",
Expand Down
44 changes: 31 additions & 13 deletions llrt_core/src/modules/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
mod socket;

use std::{env, time::Duration};
use std::{env, fs::File, io, time::Duration};

use bytes::Bytes;
use http_body_util::Full;
Expand Down Expand Up @@ -41,41 +41,59 @@ pub fn get_pool_idle_timeout() -> u64 {
pool_idle_timeout
}

pub static HTTP_CLIENT: Lazy<Client<HttpsConnector<HttpConnector>, Full<Bytes>>> =
pub static HTTP_CLIENT: Lazy<io::Result<Client<HttpsConnector<HttpConnector>, Full<Bytes>>>> =
Lazy::new(|| {
let pool_idle_timeout: u64 = get_pool_idle_timeout();

let maybe_tls_config = match &*TLS_CONFIG {
Ok(tls_config) => io::Result::Ok(tls_config.clone()),
Err(e) => io::Result::Err(io::Error::new(e.kind(), e.to_string())),
};

let builder = hyper_rustls::HttpsConnectorBuilder::new()
.with_tls_config(TLS_CONFIG.clone())
.with_tls_config(maybe_tls_config?)
.https_or_http();

let https = match env::var(environment::ENV_LLRT_HTTP_VERSION).as_deref() {
Ok("1.1") => builder.enable_http1().build(),
_ => builder.enable_all_versions().build(),
};

Client::builder(TokioExecutor::new())
Ok(Client::builder(TokioExecutor::new())
.pool_idle_timeout(Duration::from_secs(pool_idle_timeout))
.pool_timer(TokioTimer::new())
.build(https)
.build(https))
});

pub static TLS_CONFIG: Lazy<ClientConfig> = Lazy::new(|| {
pub static TLS_CONFIG: Lazy<io::Result<ClientConfig>> = Lazy::new(|| {
let mut root_certificates = RootCertStore::empty();

for cert in TLS_SERVER_ROOTS.iter().cloned() {
root_certificates.roots.push(cert)
}

if let Ok(extra_ca_certs) = env::var(environment::ENV_LLRT_EXTRA_CA_CERTS) {
if !extra_ca_certs.is_empty() {
let file = File::open(extra_ca_certs)
.map_err(|_| io::Error::other("Failed to open extra CA certificates file"))?;
let mut reader = io::BufReader::new(file);
root_certificates.add_parsable_certificates(
rustls_pemfile::certs(&mut reader).filter_map(io::Result::ok),
);
}
}

let builder = ClientConfig::builder_with_provider(ring::default_provider().into());

match env::var(environment::ENV_LLRT_TLS_VERSION).as_deref() {
Ok("1.3") => builder.with_safe_default_protocol_versions(),
_ => builder.with_protocol_versions(&[&version::TLS12]), //Use TLS 1.2 by default to increase compat and keep latency low
}
.unwrap()
.with_root_certificates(root_certificates)
.with_no_client_auth()
Ok(
match env::var(environment::ENV_LLRT_TLS_VERSION).as_deref() {
Ok("1.3") => builder.with_safe_default_protocol_versions(),
_ => builder.with_protocol_versions(&[&version::TLS12]), //Use TLS 1.2 by default to increase compat and keep latency low
}
.unwrap()
.with_root_certificates(root_certificates)
.with_no_client_auth(),
)
});

pub struct NetModule;
Expand Down
2 changes: 1 addition & 1 deletion llrt_core/src/runtime_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ async fn start_with_cfg(ctx: &Ctx<'_>, config: RuntimeConfig) -> Result<()> {
));
}

let client = (*HTTP_CLIENT).clone();
let client = HTTP_CLIENT.as_ref().or_throw(ctx)?.clone();

let base_url = ["http://", &config.runtime_api, "/", ENV_RUNTIME_PATH].concat();
let handler = handler.as_function().unwrap();
Expand Down

0 comments on commit 9e8dc2e

Please sign in to comment.