diff --git a/Cargo.lock b/Cargo.lock index 2f5d12b8..dea29a0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -227,6 +227,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "axum-client-ip" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72188bed20deb981f3a4a9fe674e5980fd9e9c2bd880baa94715ad5d60d64c67" +dependencies = [ + "axum 0.7.5", + "forwarded-header-value", + "serde", +] + [[package]] name = "axum-core" version = "0.3.4" @@ -625,6 +636,7 @@ name = "conduit_api" version = "0.4.1" dependencies = [ "axum 0.7.5", + "axum-client-ip", "axum-extra", "base64 0.22.1", "bytes", @@ -715,6 +727,7 @@ name = "conduit_router" version = "0.4.1" dependencies = [ "axum 0.7.5", + "axum-client-ip", "axum-server", "axum-server-dual-protocol", "bytes", @@ -1100,6 +1113,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "forwarded-header-value" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9" +dependencies = [ + "nonempty", + "thiserror", +] + [[package]] name = "futf" version = "0.1.5" @@ -2044,6 +2067,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nonempty" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" + [[package]] name = "nu-ansi-term" version = "0.46.0" diff --git a/Cargo.toml b/Cargo.toml index 3a12069b..a9c35d8f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,6 +83,9 @@ features = ["typed-header"] version = "0.6.0" features = ["tls-rustls"] +[workspace.dependencies.axum-client-ip] +version = "0.6.0" + [workspace.dependencies.tower] version = "0.4.13" features = ["util"] diff --git a/src/api/Cargo.toml b/src/api/Cargo.toml index 5ac15dd5..fb486a71 100644 --- a/src/api/Cargo.toml +++ b/src/api/Cargo.toml @@ -33,6 +33,7 @@ brotli_compression = [ ] [dependencies] +axum-client-ip.workspace = true axum-extra.workspace = true axum.workspace = true base64.workspace = true diff --git a/src/router/Cargo.toml b/src/router/Cargo.toml index 6084aa07..f613826b 100644 --- a/src/router/Cargo.toml +++ b/src/router/Cargo.toml @@ -46,6 +46,7 @@ axum_dual_protocol = [ ] [dependencies] +axum-client-ip.workspace = true axum-server-dual-protocol.optional = true axum-server-dual-protocol.workspace = true axum-server.workspace = true diff --git a/src/router/layers.rs b/src/router/layers.rs index c09f7e87..b358a3e6 100644 --- a/src/router/layers.rs +++ b/src/router/layers.rs @@ -4,6 +4,7 @@ use axum::{ extract::{DefaultBodyLimit, MatchedPath}, Router, }; +use axum_client_ip::SecureClientIpSource; use conduit::Server; use http::{ header::{self, HeaderName}, @@ -46,6 +47,7 @@ pub(crate) fn build(server: &Arc) -> io::Result { .on_response(DefaultOnResponse::new().level(Level::DEBUG)), ) .layer(axum::middleware::from_fn_with_state(Arc::clone(server), request::handle)) + .layer(SecureClientIpSource::ConnectInfo.into_extension()) .layer(SetResponseHeaderLayer::if_not_present( HeaderName::from_static("origin-agent-cluster"), // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin-Agent-Cluster HeaderValue::from_static("?1"),