Add support for trusting X-Forwarded-For header to get client IP

falls back to remote ip if header unavailable
This commit is contained in:
Skyler Mansfield 2023-11-13 15:24:20 +00:00 committed by Eugene
parent 8b91e4a328
commit b0a9130a51
2 changed files with 17 additions and 1 deletions

View file

@ -139,6 +139,9 @@ pub struct HTTPConfig {
#[serde(default)] #[serde(default)]
pub key: String, pub key: String,
#[serde(default)]
pub trust_x_forwarded_for: bool,
} }
impl Default for HTTPConfig { impl Default for HTTPConfig {
@ -148,6 +151,7 @@ impl Default for HTTPConfig {
listen: _default_http_listen(), listen: _default_http_listen(),
certificate: "".to_owned(), certificate: "".to_owned(),
key: "".to_owned(), key: "".to_owned(),
trust_x_forwarded_for: false,
} }
} }
} }

View file

@ -1,18 +1,30 @@
use http::{Method, StatusCode, Uri}; use http::{Method, StatusCode, Uri};
use poem::{FromRequest, Request}; use poem::{FromRequest, Request};
use poem::web::Data;
use tracing::*; use tracing::*;
use warpgate_core::Services;
use crate::session_handle::WarpgateServerHandleFromRequest; use crate::session_handle::WarpgateServerHandleFromRequest;
pub async fn span_for_request(req: &Request) -> poem::Result<Span> { pub async fn span_for_request(req: &Request) -> poem::Result<Span> {
let handle = WarpgateServerHandleFromRequest::from_request_without_body(req).await; let handle = WarpgateServerHandleFromRequest::from_request_without_body(req).await;
let services: Data<&Services> = <_>::from_request_without_body(req).await?;
let config = services.config.lock().await;
let client_ip = req let remote_ip = req
.remote_addr() .remote_addr()
.as_socket_addr() .as_socket_addr()
.map(|x| x.ip().to_string()) .map(|x| x.ip().to_string())
.unwrap_or("<unknown>".into()); .unwrap_or("<unknown>".into());
let client_ip = match config.store.http.trust_x_forwarded_for {
true => req
.header("X-Forwarded-For")
.map(|x| x.to_string())
.unwrap_or(remote_ip),
false => remote_ip,
};
Ok(match handle { Ok(match handle {
Ok(ref handle) => { Ok(ref handle) => {
let handle = handle.lock().await; let handle = handle.lock().await;