feat: Allow configuring the desired client IP source

This commit is contained in:
timedout
2026-07-09 19:40:11 +00:00
committed by Ellis Git
parent ce185aff13
commit f71f6e922c
4 changed files with 55 additions and 1 deletions
+1
View File
@@ -0,0 +1 @@
Added a configuration option to allow choosing a client IP source that is not the TCP connecting IP. Contributed by @nex.
+20
View File
@@ -290,6 +290,26 @@
#
#ip_lookup_strategy = 5
# The source to use for discovering the real connecting client IP.
#
# Takes the number of any of the following options:
#
# 0 - Use the IP address of the TCP connection
# 1 - `Cf-Connecting-Ip` header
# 2 - `CloudFront-Viewer-Address` header
# 3 - `Fly-Client-IP` header
# 4 - rightmost value of the `X-Forwarded-For` header
# 5 - `True-Client-Ip` header
# 6 - `X-Envoy-External-Address` header
# 7 - `X-Real-Ip` header
#
# Only change this from `0` if you are certain only your reverse proxy
# will send the expected header. There is no "is the connecting IP allowed
# to set this header" check; if the header selected is present, it is
# used.
#
#request_ip_source = 0
# Max request size for file uploads in bytes. Defaults to 20MB.
# Also limits incoming federated media.
#
+22
View File
@@ -370,6 +370,28 @@ pub struct Config {
#[serde(default = "default_ip_lookup_strategy")]
pub ip_lookup_strategy: u8,
/// The source to use for discovering the real connecting client IP.
///
/// Takes the number of any of the following options:
///
/// 0 - Use the IP address of the TCP connection
/// 1 - `Cf-Connecting-Ip` header
/// 2 - `CloudFront-Viewer-Address` header
/// 3 - `Fly-Client-IP` header
/// 4 - rightmost value of the `X-Forwarded-For` header
/// 5 - `True-Client-Ip` header
/// 6 - `X-Envoy-External-Address` header
/// 7 - `X-Real-Ip` header
///
/// Only change this from `0` if you are certain only your reverse proxy
/// will send the expected header. There is no "is the connecting IP allowed
/// to set this header" check; if the header selected is present, it is
/// used.
///
/// default: 0
#[serde(default)]
pub request_ip_source: u8,
/// Max request size for file uploads in bytes. Defaults to 20MB.
/// Also limits incoming federated media.
///
+12 -1
View File
@@ -48,6 +48,17 @@ pub(crate) fn build(services: &Arc<Services>) -> Result<(Router, Guard)> {
))]
let layers = layers.layer(compression_layer(server));
let client_ip_layer = match services.config.request_ip_source {
| 1 => ClientIpSource::CfConnectingIp,
| 2 => ClientIpSource::CloudFrontViewerAddress,
| 3 => ClientIpSource::FlyClientIp,
| 4 => ClientIpSource::RightmostXForwardedFor,
| 5 => ClientIpSource::TrueClientIp,
| 6 => ClientIpSource::XEnvoyExternalAddress,
| 7 => ClientIpSource::XRealIp,
| _ => ClientIpSource::ConnectInfo,
};
let services_ = services.clone();
let layers = layers
.layer(SetSensitiveHeadersLayer::new([header::AUTHORIZATION]))
@@ -59,7 +70,7 @@ pub(crate) fn build(services: &Arc<Services>) -> Result<(Router, Guard)> {
.on_response(DefaultOnResponse::new().level(Level::DEBUG)),
)
.layer(axum::middleware::from_fn_with_state(Arc::clone(services), request::handle))
.layer(ClientIpSource::ConnectInfo.into_extension())
.layer(client_ip_layer.into_extension())
.layer(ResponseBodyTimeoutLayer::new(Duration::from_secs(
server.config.client_response_timeout,
)))