Enable connecting to pict-rs over TLS

This commit is contained in:
asonix 2024-02-01 16:32:17 -06:00
parent d467dfb2d1
commit 7a862bc8ff
3 changed files with 235 additions and 46 deletions

186
Cargo.lock generated
View file

@ -8,7 +8,7 @@ version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"bytes",
"futures-core",
"futures-sink",
@ -21,9 +21,9 @@ dependencies = [
[[package]]
name = "actix-http"
version = "3.3.1"
version = "3.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2079246596c18b4a33e274ae10c0e50613f4d32a4198e09c7b93771013fed74"
checksum = "129d4c88e98860e1758c5de288d1632b07970a16d59bdf7b8d66053d582bb71f"
dependencies = [
"actix-codec",
"actix-rt",
@ -31,14 +31,14 @@ dependencies = [
"actix-utils",
"ahash 0.8.3",
"base64 0.21.2",
"bitflags",
"bitflags 2.4.2",
"bytes",
"bytestring",
"derive_more",
"encoding_rs",
"futures-core",
"h2",
"http",
"http 0.2.9",
"httparse",
"httpdate",
"itoa",
@ -72,7 +72,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799"
dependencies = [
"bytestring",
"http",
"http 0.2.9",
"regex",
"serde",
"tracing",
@ -120,19 +120,23 @@ dependencies = [
[[package]]
name = "actix-tls"
version = "3.0.3"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fde0cf292f7cdc7f070803cb9a0d45c018441321a78b1042ffbbb81ec333297"
checksum = "929e47cc23865cdb856e59673cfba2d28f00b3bbd060dfc80e33a00a3cea8317"
dependencies = [
"actix-codec",
"actix-rt",
"actix-service",
"actix-utils",
"futures-core",
"http",
"log",
"http 0.2.9",
"http 1.0.0",
"impl-more",
"pin-project-lite",
"tokio",
"tokio-rustls",
"tokio-util",
"tracing",
"webpki-roots 0.25.3",
]
[[package]]
@ -166,7 +170,7 @@ dependencies = [
"encoding_rs",
"futures-core",
"futures-util",
"http",
"http 0.2.9",
"itoa",
"language-tags",
"log",
@ -332,9 +336,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "awc"
version = "3.1.1"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ef547a81796eb2dfe9b345aba34c2e08391a0502493711395b36dd64052b69"
checksum = "b625cad34428b3b82d0bd548b26a1cd0a3d70b6109e9b4e3355d8f1802a8b1c6"
dependencies = [
"actix-codec",
"actix-http",
@ -342,7 +346,6 @@ dependencies = [
"actix-service",
"actix-tls",
"actix-utils",
"ahash 0.7.6",
"base64 0.21.2",
"bytes",
"cfg-if",
@ -350,13 +353,14 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http 0.2.9",
"itoa",
"log",
"mime",
"percent-encoding",
"pin-project-lite",
"rand",
"rustls",
"serde",
"serde_json",
"serde_urlencoded",
@ -371,10 +375,10 @@ checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39"
dependencies = [
"async-trait",
"axum-core",
"bitflags",
"bitflags 1.3.2",
"bytes",
"futures-util",
"http",
"http 0.2.9",
"http-body",
"hyper",
"itoa",
@ -400,7 +404,7 @@ dependencies = [
"async-trait",
"bytes",
"futures-util",
"http",
"http 0.2.9",
"http-body",
"mime",
"rustversion",
@ -426,6 +430,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
[[package]]
name = "block-buffer"
version = "0.10.4"
@ -493,7 +503,7 @@ checksum = "4f423e341edefb78c9caba2d9c7f7687d0e72e89df3ce3394554754393ac3990"
dependencies = [
"anstream",
"anstyle",
"bitflags",
"bitflags 1.3.2",
"clap_lex",
"strsim",
]
@ -855,7 +865,7 @@ dependencies = [
"futures-core",
"futures-sink",
"futures-util",
"http",
"http 0.2.9",
"indexmap",
"slab",
"tokio",
@ -914,6 +924,17 @@ dependencies = [
"itoa",
]
[[package]]
name = "http"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea"
dependencies = [
"bytes",
"fnv",
"itoa",
]
[[package]]
name = "http-body"
version = "0.4.5"
@ -921,7 +942,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
dependencies = [
"bytes",
"http",
"http 0.2.9",
"pin-project-lite",
]
@ -954,7 +975,7 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http 0.2.9",
"http-body",
"httparse",
"httpdate",
@ -989,6 +1010,12 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "impl-more"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d"
[[package]]
name = "indexmap"
version = "1.9.3"
@ -1288,7 +1315,7 @@ dependencies = [
"async-trait",
"futures",
"futures-util",
"http",
"http 0.2.9",
"opentelemetry",
"opentelemetry-proto",
"prost",
@ -1417,9 +1444,12 @@ dependencies = [
"opentelemetry",
"opentelemetry-otlp",
"ructe",
"rustls",
"rustls-pemfile",
"serde",
"serde_qs",
"thiserror",
"tokio",
"tracing",
"tracing-actix-web",
"tracing-awc",
@ -1429,6 +1459,7 @@ dependencies = [
"tracing-opentelemetry",
"tracing-subscriber",
"url",
"webpki-roots 0.26.0",
]
[[package]]
@ -1555,7 +1586,7 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
"bitflags 1.3.2",
]
[[package]]
@ -1590,6 +1621,20 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
[[package]]
name = "ring"
version = "0.17.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e"
dependencies = [
"cc",
"getrandom",
"libc",
"spin",
"untrusted",
"windows-sys 0.48.0",
]
[[package]]
name = "rsass"
version = "0.27.0"
@ -1643,7 +1688,7 @@ version = "0.37.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
dependencies = [
"bitflags",
"bitflags 1.3.2",
"errno",
"io-lifetimes",
"libc",
@ -1651,6 +1696,44 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "rustls"
version = "0.21.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
dependencies = [
"log",
"ring",
"rustls-webpki",
"sct",
]
[[package]]
name = "rustls-pemfile"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35e4980fa29e4c4b212ffb3db068a564cbf560e51d3944b7c88bd8bf5bec64f4"
dependencies = [
"base64 0.21.2",
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e9d979b3ce68192e42760c7810125eb6cf2ea10efae545a156063e61f314e2a"
[[package]]
name = "rustls-webpki"
version = "0.101.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "rustversion"
version = "1.0.12"
@ -1669,6 +1752,16 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "sct"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "semver"
version = "1.0.17"
@ -1785,6 +1878,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "strsim"
version = "0.10.0"
@ -1931,6 +2030,16 @@ dependencies = [
"syn 2.0.16",
]
[[package]]
name = "tokio-rustls"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
dependencies = [
"rustls",
"tokio",
]
[[package]]
name = "tokio-stream"
version = "0.1.14"
@ -1970,7 +2079,7 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http 0.2.9",
"http-body",
"hyper",
"hyper-timeout",
@ -2001,7 +2110,7 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"http",
"http 0.2.9",
"http-body",
"hyper",
"hyper-timeout",
@ -2209,6 +2318,12 @@ dependencies = [
"tinyvec",
]
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.3.1"
@ -2269,6 +2384,21 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "webpki-roots"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10"
[[package]]
name = "webpki-roots"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de2cfda980f21be5a7ed2eadb3e6fe074d56022bea2cdeb1a62eb220fc04188"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "winapi"
version = "0.3.9"

View file

@ -19,7 +19,7 @@ default = []
actix-rt = "2.7.0"
actix-web = { version = "4.0.0", default-features = false }
anyhow = "1.0"
awc = { version = "3.0.0", default-features = false }
awc = { version = "3.0.0", default-features = false, features = ["rustls-0_21"] }
clap = { version = "4.0.2", features = ["derive", "env"] }
console-subscriber = "0.1"
dotenv = "0.15.0"
@ -28,9 +28,12 @@ minify-html = "0.11.1"
once_cell = "1.4"
opentelemetry = { version = "0.19", features = ["rt-tokio"] }
opentelemetry-otlp = "0.12"
rustls = "0.21"
rustls-pemfile = "2.0.0"
serde = { version = "1.0", features = ["derive"] }
serde_qs = { version = "0.12", features = ["actix4"] }
thiserror = "1.0"
tokio = { version = "1", features = ["fs"] }
tracing = "0.1"
tracing-error = "0.2"
tracing-futures = "0.2"
@ -42,6 +45,7 @@ tracing-subscriber = { version = "0.3", features = [
"fmt",
] }
url = "2.1"
webpki-roots = "0.26"
[dependencies.tracing-actix-web]
version = "0.7.5"

View file

@ -10,7 +10,7 @@ use actix_web::{
middleware::NormalizePath,
web, App, HttpRequest, HttpResponse, HttpResponseBuilder, HttpServer, ResponseError,
};
use awc::Client;
use awc::{Client, Connector};
use clap::Parser;
use console_subscriber::ConsoleLayer;
use once_cell::sync::Lazy;
@ -19,9 +19,12 @@ use opentelemetry::{
KeyValue,
};
use opentelemetry_otlp::WithExportConfig;
use rustls::{Certificate, ClientConfig, OwnedTrustAnchor, RootCertStore};
use std::{
io::Cursor,
net::SocketAddr,
path::PathBuf,
sync::Arc,
time::{Duration, SystemTime},
};
use tracing_actix_web::TracingLogger;
@ -29,8 +32,7 @@ use tracing_awc::Tracing;
use tracing_error::{ErrorLayer, SpanTrace};
use tracing_log::LogTracer;
use tracing_subscriber::{
filter::Targets, fmt::format::FmtSpan, layer::SubscriberExt, registry::LookupSpan, Layer,
Registry,
filter::Targets, layer::SubscriberExt, registry::LookupSpan, Layer, Registry,
};
use url::Url;
@ -47,7 +49,7 @@ struct Config {
short,
long,
env = "PICTRS_PROXY_ADDR",
default_value = "0.0.0.0:8081",
default_value = "[::]:8081",
help = "The address and port the server binds to"
)]
addr: SocketAddr,
@ -73,10 +75,17 @@ struct Config {
#[arg(
long,
env = "PICTRS_PROXY_CONSOLE_BUFFER_SIZE",
help = "Number of events to buffer for the console subscriber. When unset, console will be disabled"
help = "Number of events to buffer for the console subscriber"
)]
console_event_buffer_size: Option<usize>,
#[arg(
long,
env = "PICTRS_PROXY_CONSOLE",
help = "Enable the tokio-console at the specified address"
)]
console_addr: Option<SocketAddr>,
#[arg(
short,
long,
@ -84,6 +93,14 @@ struct Config {
help = "URL of OpenTelemetry Collector"
)]
opentelemetry_url: Option<Url>,
#[arg(
short,
long,
env = "PICTRS_PROXY_CERTIFICATE",
help = "Path to the certificate file to connec to pict-rs over TLS"
)]
certificate: Option<PathBuf>,
}
impl Config {
@ -834,6 +851,7 @@ fn render(
fn init_tracing(
service_name: &'static str,
opentelemetry_url: Option<&Url>,
console_addr: Option<SocketAddr>,
console_event_buffer_size: Option<usize>,
) -> Result<(), anyhow::Error> {
opentelemetry::global::set_text_map_propagator(TraceContextPropagator::new());
@ -844,27 +862,32 @@ fn init_tracing(
.unwrap_or_else(|_| "info".into())
.parse()?;
let format_layer = tracing_subscriber::fmt::layer()
.with_span_events(FmtSpan::NEW | FmtSpan::CLOSE)
.with_filter(targets.clone());
let format_layer = tracing_subscriber::fmt::layer().with_filter(targets.clone());
let subscriber = Registry::default()
.with(format_layer)
.with(ErrorLayer::default());
if let Some(buffer_size) = console_event_buffer_size {
let console_layer = ConsoleLayer::builder()
if let Some(console_addr) = console_addr {
let console_builder = ConsoleLayer::builder()
.with_default_env()
.server_addr(([0, 0, 0, 0], 6669))
.event_buffer_capacity(buffer_size)
.spawn();
.server_addr(console_addr);
let console_layer = if let Some(buffer_size) = console_event_buffer_size {
console_builder.event_buffer_capacity(buffer_size).spawn()
} else {
console_builder.spawn()
};
let subscriber = subscriber.with(console_layer);
init_subscriber(subscriber, targets, opentelemetry_url, service_name)
init_subscriber(subscriber, targets, opentelemetry_url, service_name)?;
tracing::info!("Launched console on {console_addr}");
} else {
init_subscriber(subscriber, targets, opentelemetry_url, service_name)
init_subscriber(subscriber, targets, opentelemetry_url, service_name)?;
}
Ok(())
}
fn init_subscriber<S>(
@ -905,22 +928,54 @@ where
Ok(())
}
async fn create_rustls_config() -> anyhow::Result<ClientConfig> {
let mut cert_store = RootCertStore {
roots: webpki_roots::TLS_SERVER_ROOTS
.into_iter()
.map(|anchor| {
OwnedTrustAnchor::from_subject_spki_name_constraints(
anchor.subject.to_vec(),
anchor.subject_public_key_info.to_vec(),
anchor.name_constraints.as_ref().map(|d| d.to_vec()),
)
})
.collect(),
};
if let Some(cert) = CONFIG.certificate.as_ref() {
let cert_bytes = tokio::fs::read(&cert).await?;
for res in rustls_pemfile::certs(&mut cert_bytes.as_slice()) {
cert_store.add(&Certificate(res?.to_vec()))?;
}
};
Ok(ClientConfig::builder()
.with_safe_defaults()
.with_root_certificates(cert_store)
.with_no_client_auth())
}
#[actix_rt::main]
async fn main() -> Result<(), anyhow::Error> {
async fn main() -> anyhow::Result<()> {
dotenv::dotenv().ok();
init_tracing(
"pict-rs-proxy",
CONFIG.opentelemetry_url.as_ref(),
CONFIG.console_addr,
CONFIG.console_event_buffer_size,
)?;
let client_config = create_rustls_config().await?;
HttpServer::new(move || {
let client = Client::builder()
.wrap(Tracing)
.add_default_header(("User-Agent", "pict-rs-frontend, v0.5.0-alpha.1"))
.add_default_header(("User-Agent", "pict-rs-frontend, v0.5.0"))
.timeout(Duration::from_secs(30))
.disable_redirects()
.connector(Connector::new().rustls_021(Arc::new(client_config.clone())))
.finish();
App::new()