1
0
Fork 0
mirror of https://gitlab.com/famedly/conduit.git synced 2025-10-20 19:52:07 +00:00

feat: make IP address detection method configurable

This commit is contained in:
Matthias Ahouansou 2025-10-20 18:44:06 +01:00
parent 13dade46ae
commit 4261c008e7
No known key found for this signature in database
5 changed files with 45 additions and 9 deletions

2
Cargo.lock generated
View file

@ -171,6 +171,7 @@ dependencies = [
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper 1.0.2",
"tokio",
"tower 0.5.2",
"tower-layer",
"tower-service",
@ -3628,6 +3629,7 @@ dependencies = [
"futures-util",
"pin-project-lite",
"sync_wrapper 1.0.2",
"tokio",
"tower-layer",
"tower-service",
]

View file

@ -34,6 +34,7 @@ axum = { version = "0.8", default-features = false, features = [
"http2",
"json",
"matched-path",
"tokio",
], optional = true }
axum-extra = { version = "0.10", features = ["typed-header"] }
axum-server = { version = "0.7", features = ["tls-rustls"] }

View file

@ -2,13 +2,13 @@ use std::{
collections::BTreeMap,
error::Error as _,
iter::FromIterator,
net::IpAddr,
net::{IpAddr, SocketAddr},
str::{self, FromStr},
};
use axum::{
body::Body,
extract::{FromRequest, Path},
extract::{ConnectInfo, FromRequest, Path},
response::{IntoResponse, Response},
RequestPartsExt,
};
@ -31,6 +31,7 @@ use tracing::{debug, error, warn};
use super::{Ruma, RumaResponse};
use crate::{
config::IpAddrDetection,
service::{appservice::RegistrationInfo, rate_limiting::Target},
services, Error, Result,
};
@ -336,12 +337,21 @@ where
}
};
let sender_ip_address = parts
.headers
.get("X-Forwarded-For")
.and_then(|header| header.to_str().ok())
.map(|header| header.split_once(',').map(|(ip, _)| ip).unwrap_or(header))
.and_then(|ip| IpAddr::from_str(ip).ok());
let sender_ip_address: Option<IpAddr> =
match &services().globals.config.ip_address_detection {
IpAddrDetection::None => None,
#[cfg(unix)]
IpAddrDetection::Socket => {
let addr: ConnectInfo<SocketAddr> = parts.extract().await?;
Some(addr.ip())
}
IpAddrDetection::Header(name) => parts
.headers
.get(name)
.and_then(|header| header.to_str().ok())
.map(|header| header.split_once(',').map(|(ip, _)| ip).unwrap_or(header))
.and_then(|ip| IpAddr::from_str(ip).ok()),
};
let target = if let Some(server_name) = sender_servername.clone() {
Some(Target::Server(server_name))

View file

@ -82,6 +82,8 @@ pub struct IncompleteConfig {
pub trusted_servers: Vec<OwnedServerName>,
#[serde(default = "default_log")]
pub log: String,
#[serde(default)]
pub ip_address_detection: IpAddrDetection,
pub turn_username: Option<String>,
pub turn_password: Option<String>,
pub turn_uris: Option<Vec<String>>,
@ -137,6 +139,7 @@ pub struct Config {
pub jwt_secret: Option<String>,
pub trusted_servers: Vec<OwnedServerName>,
pub log: String,
pub ip_address_detection: IpAddrDetection,
pub turn: Option<TurnConfig>,
@ -183,6 +186,7 @@ impl From<IncompleteConfig> for Config {
jwt_secret,
trusted_servers,
log,
ip_address_detection,
turn_username,
turn_password,
turn_uris,
@ -286,6 +290,7 @@ impl From<IncompleteConfig> for Config {
jwt_secret,
trusted_servers,
log,
ip_address_detection,
turn,
media,
rate_limiting,
@ -617,6 +622,20 @@ pub struct S3MediaBackend {
pub directory_structure: DirectoryStructure,
}
#[derive(Deserialize, Debug, Clone)]
pub enum IpAddrDetection {
None,
Header(String),
#[cfg(unix)]
Socket,
}
impl Default for IpAddrDetection {
fn default() -> Self {
Self::Header("X-Forwarded-For".to_owned())
}
}
const DEPRECATED_KEYS: &[&str] = &[
"cache_capacity",
"turn_username",

View file

@ -242,7 +242,11 @@ async fn run_server() -> io::Result<()> {
)
.layer(map_response(set_csp_header));
let app = routes(config).layer(middlewares).into_make_service();
let app = routes(config).layer(middlewares);
#[cfg(not(unix))]
let app = app.into_make_service();
#[cfg(unix)]
let app = app.into_make_service_with_connect_info::<SocketAddr>();
let handle = ServerHandle::new();
tokio::spawn(shutdown_signal(handle.clone()));