Skip to content

Commit

Permalink
Handle multiple forwarded-for addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
j-chmielewski committed Mar 22, 2024
1 parent 32354fd commit af4c3ed
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,23 @@ async fn healthcheck() -> &'static str {
"I'm alive!"
}

// Retrieves client address from the request. Uses either the left most x-forwarded-for
// header value, or socket address if the header is not present.
fn get_client_addr(request: &Request<Body>) -> String {
request
.headers()
.get("X-Forwarded-For")
.and_then(|h| h.to_str().ok())
.and_then(|h| h.split(',').next())
.map(|ip| ip.trim().to_string())
.unwrap_or_else(|| {
request
.extensions()
.get::<ConnectInfo<SocketAddr>>()
.map_or("unknown".to_string(), |addr| addr.0.to_string())
})
}

pub async fn run_server(config: Config) -> anyhow::Result<()> {
info!("Starting Defguard proxy server");
debug!("Using config: {config:?}");
Expand Down Expand Up @@ -132,16 +149,7 @@ pub async fn run_server(config: Config) -> anyhow::Result<()> {
.layer(
TraceLayer::new_for_http()
.make_span_with(|request: &Request<Body>| {
let addr = match request.headers().get("x-forwarded-for") {
// extract client address from x-forwarded-for header
Some(addr) => addr.to_str().map(|s| s.to_string()).ok(),
// use TCP/IP client address
None => request
.extensions()
.get::<ConnectInfo<SocketAddr>>()
.map(|addr| addr.0.to_string()),
};
let addr = addr.unwrap_or_else(|| "unknown".to_string());
let addr = get_client_addr(request);
info_span!(
"http_request",
method = ?request.method(),
Expand Down

0 comments on commit af4c3ed

Please sign in to comment.