Skip to content

Commit 1bf0e2d

Browse files
committed
middleware/log_request: Add logging for processed X-Forwarded-For header values
This is supposed to eventually replace the `X-Real-IP` header usage once production traffic has shown that our implementation is correct.
1 parent 7f59175 commit 1bf0e2d

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

src/middleware/log_request.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
use crate::controllers::util::RequestPartsExt;
55
use crate::headers::{XRealIp, XRequestId};
66
use crate::middleware::normalize_path::OriginalPath;
7+
use crate::real_ip::process_xff_headers;
78
use axum::headers::UserAgent;
89
use axum::middleware::Next;
910
use axum::response::IntoResponse;
1011
use axum::{Extension, TypedHeader};
1112
use http::{Method, Request, StatusCode, Uri};
1213
use parking_lot::Mutex;
1314
use std::fmt::{self, Display, Formatter};
15+
use std::net::IpAddr;
1416
use std::ops::Deref;
1517
use std::sync::Arc;
1618
use std::time::{Duration, Instant};
@@ -39,6 +41,7 @@ pub struct Metadata<'a> {
3941
cause: Option<&'a CauseField>,
4042
error: Option<&'a ErrorField>,
4143
duration: Duration,
44+
real_ip: Option<IpAddr>,
4245
custom_metadata: RequestLog,
4346
}
4447

@@ -71,10 +74,19 @@ impl Display for Metadata<'_> {
7174
};
7275
}
7376

74-
match &self.request.real_ip {
75-
Some(header) => line.add_quoted_field("fwd", header.as_str())?,
76-
None => line.add_quoted_field("fwd", "")?,
77-
};
77+
let real_ip = self.real_ip.map(|ip| ip.to_string()).unwrap_or_default();
78+
line.add_quoted_field("ip", &real_ip)?;
79+
80+
let x_real_ip = self.request.real_ip.as_ref();
81+
let x_real_ip = x_real_ip
82+
.map(|ip| ip.as_str().to_string())
83+
.unwrap_or_default();
84+
line.add_quoted_field("fwd", &x_real_ip)?;
85+
86+
// TODO: Remove this once production traffic has shown that `ip == fwd`
87+
if real_ip != x_real_ip {
88+
line.add_marker("ip!=fwd")?;
89+
}
7890

7991
let response_time_in_ms = self.duration.as_millis();
8092
if !is_download_redirect || response_time_in_ms > 0 {
@@ -122,6 +134,8 @@ pub async fn log_requests<B>(
122134
let custom_metadata = RequestLog::default();
123135
req.extensions_mut().insert(custom_metadata.clone());
124136

137+
let real_ip = process_xff_headers(req.headers());
138+
125139
let response = next.run(req).await;
126140

127141
let metadata = Metadata {
@@ -130,6 +144,7 @@ pub async fn log_requests<B>(
130144
cause: response.extensions().get(),
131145
error: response.extensions().get(),
132146
duration: start_instant.elapsed(),
147+
real_ip,
133148
custom_metadata,
134149
};
135150

src/real_ip.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ fn is_cloud_front_ip(ip: &IpAddr) -> bool {
156156
.any(|trusted_proxy| trusted_proxy.contains(*ip))
157157
}
158158

159-
#[allow(dead_code)]
160159
pub fn process_xff_headers(headers: &HeaderMap) -> Option<IpAddr> {
161160
let mut xff_iter = headers.get_all(X_FORWARDED_FOR).iter();
162161
let first_header = xff_iter.next()?;

0 commit comments

Comments
 (0)