diff --git a/examples/server.toml b/examples/server.toml index 9a41738c5..1928205d2 100644 --- a/examples/server.toml +++ b/examples/server.toml @@ -13,16 +13,6 @@ bindaddress = "[::]:443" # Defaults to "" (disabled) # ldapbindaddress = "[::]:636" # -# HTTPS requests can be reverse proxied by a loadbalancer. -# To preserve the original IP of the caller, these systems -# will often add a header such as "Forwarded" or -# "X-Forwarded-For". If set to true, then this header is -# respected as the "authoritative" source of the IP of the -# connected client. If you are not using a load balancer -# then you should leave this value as default. -# Defaults to false -# trust_x_forward_for = false -# # The path to the kanidm database. db_path = "/var/lib/private/kanidm/kanidm.db" # @@ -86,6 +76,30 @@ domain = "idm.example.com" # origin = "https://idm.example.com" origin = "https://idm.example.com:8443" # + +# HTTPS requests can be reverse proxied by a loadbalancer. +# To preserve the original IP of the caller, these systems +# will often add a header such as "Forwarded" or +# "X-Forwarded-For". Some other proxies can use the HAProxy +# proxy v2 header. +# This setting allows configuration of the range of trusted +# IPs which can supply this header information, and which +# format the information is provided in. +# Defaults to "none" (no trusted sources) +# [http_client_address_info] +# proxy-v2 = ["127.0.0.1"] +# x-forward-for = ["127.0.0.1"] + +# LDAPS requests can be reverse proxied by a loadbalancer. +# To preserve the original IP of the caller, these systems +# will can add a header such as the HAProxy proxy v2 header. +# This setting allows configuration of the range of trusted +# IPs which can supply this header information, and which +# format the information is provided in. +# Defaults to "none" (no trusted sources) +# [ldap_client_address_info] +# proxy-v2 = ["127.0.0.1"] + [online_backup] # The path to the output folder for online backups path = "/var/lib/private/kanidm/backups/" diff --git a/examples/server_container.toml b/examples/server_container.toml index f57923a40..8c628eeb4 100644 --- a/examples/server_container.toml +++ b/examples/server_container.toml @@ -13,16 +13,6 @@ bindaddress = "[::]:8443" # Defaults to "" (disabled) # ldapbindaddress = "[::]:3636" # -# HTTPS requests can be reverse proxied by a loadbalancer. -# To preserve the original IP of the caller, these systems -# will often add a header such as "Forwarded" or -# "X-Forwarded-For". If set to true, then this header is -# respected as the "authoritative" source of the IP of the -# connected client. If you are not using a load balancer -# then you should leave this value as default. -# Defaults to false -# trust_x_forward_for = false -# # The path to the kanidm database. db_path = "/data/kanidm.db" # @@ -85,7 +75,30 @@ domain = "idm.example.com" # not consistent, the server WILL refuse to start! # origin = "https://idm.example.com" origin = "https://idm.example.com:8443" -# + +# HTTPS requests can be reverse proxied by a loadbalancer. +# To preserve the original IP of the caller, these systems +# will often add a header such as "Forwarded" or +# "X-Forwarded-For". Some other proxies can use the HAProxy +# proxy v2 header. +# This setting allows configuration of the range of trusted +# IPs which can supply this header information, and which +# format the information is provided in. +# Defaults to "none" (no trusted sources) +# [http_client_address_info] +# proxy-v2 = ["127.0.0.1"] +# x-forward-for = ["127.0.0.1"] + +# LDAPS requests can be reverse proxied by a loadbalancer. +# To preserve the original IP of the caller, these systems +# will can add a header such as the HAProxy proxy v2 header. +# This setting allows configuration of the range of trusted +# IPs which can supply this header information, and which +# format the information is provided in. +# Defaults to "none" (no trusted sources) +# [ldap_client_address_info] +# proxy-v2 = ["127.0.0.1"] + [online_backup] # The path to the output folder for online backups path = "/data/kanidm/backups/" diff --git a/server/core/src/config.rs b/server/core/src/config.rs index 1805b0336..44211b46c 100644 --- a/server/core/src/config.rs +++ b/server/core/src/config.rs @@ -105,12 +105,12 @@ pub enum LdapAddressInfo { #[default] None, #[serde(rename = "proxy-v2")] - ProxyV2 { trusted: HashSet<IpAddr> }, + ProxyV2(HashSet<IpAddr>), } impl LdapAddressInfo { pub fn trusted_proxy_v2(&self) -> Option<HashSet<IpAddr>> { - if let Self::ProxyV2 { trusted } = self { + if let Self::ProxyV2(trusted) = self { Some(trusted.clone()) } else { None @@ -122,7 +122,7 @@ impl Display for LdapAddressInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::None => f.write_str("none"), - Self::ProxyV2 { trusted } => { + Self::ProxyV2(trusted) => { f.write_str("proxy-v2 [ ")?; for ip in trusted { write!(f, "{} ", ip)?; @@ -152,24 +152,24 @@ pub enum HttpAddressInfo { #[default] None, #[serde(rename = "x-forward-for")] - XForwardFor { trusted: HashSet<IpAddr> }, + XForwardFor(HashSet<IpAddr>), #[serde(rename = "x-forward-for-all-source-trusted")] XForwardForAllSourcesTrusted, #[serde(rename = "proxy-v2")] - ProxyV2 { trusted: HashSet<IpAddr> }, + ProxyV2(HashSet<IpAddr>), } impl HttpAddressInfo { pub(crate) fn trusted_x_forward_for(&self) -> Option<AddressRange> { match self { Self::XForwardForAllSourcesTrusted => Some(AddressRange::All), - Self::XForwardFor { trusted } => Some(AddressRange::Range(trusted.clone())), + Self::XForwardFor(trusted) => Some(AddressRange::Range(trusted.clone())), _ => None, } } pub(crate) fn trusted_proxy_v2(&self) -> Option<HashSet<IpAddr>> { - if let Self::ProxyV2 { trusted } = self { + if let Self::ProxyV2(trusted) = self { Some(trusted.clone()) } else { None @@ -182,7 +182,7 @@ impl Display for HttpAddressInfo { match self { Self::None => f.write_str("none"), - Self::XForwardFor { trusted } => { + Self::XForwardFor(trusted) => { f.write_str("x-forward-for [ ")?; for ip in trusted { write!(f, "{} ", ip)?; @@ -192,7 +192,7 @@ impl Display for HttpAddressInfo { Self::XForwardForAllSourcesTrusted => { f.write_str("x-forward-for [ ALL SOURCES TRUSTED ]") } - Self::ProxyV2 { trusted } => { + Self::ProxyV2(trusted) => { f.write_str("proxy-v2 [ ")?; for ip in trusted { write!(f, "{} ", ip)?; diff --git a/server/testkit/tests/testkit/https_extractors.rs b/server/testkit/tests/testkit/https_extractors.rs index 076d27f32..8ce0ad9e5 100644 --- a/server/testkit/tests/testkit/https_extractors.rs +++ b/server/testkit/tests/testkit/https_extractors.rs @@ -58,7 +58,7 @@ async fn dont_trust_xff_dont_send_header(rsclient: &KanidmClient) { // *test where we trust the x-forwarded-for header -#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor { trusted: [DEFAULT_IP_ADDRESS].into() })] +#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor ( [DEFAULT_IP_ADDRESS].into() ))] async fn trust_xff_send_invalid_header_single_value(rsclient: &KanidmClient) { let client = rsclient.client(); @@ -78,7 +78,7 @@ async fn trust_xff_send_invalid_header_single_value(rsclient: &KanidmClient) { // TODO: Right now we reject the request only if the leftmost address is invalid. In the future that could change so we could also have a test // with a valid leftmost address and an invalid address later in the list. Right now it wouldn't work. // -#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor { trusted: [DEFAULT_IP_ADDRESS].into() })] +#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor ( [DEFAULT_IP_ADDRESS].into() ))] async fn trust_xff_send_invalid_header_multiple_values(rsclient: &KanidmClient) { let client = rsclient.client(); @@ -95,7 +95,7 @@ async fn trust_xff_send_invalid_header_multiple_values(rsclient: &KanidmClient) assert_eq!(res.status(), 400); } -#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor { trusted: [DEFAULT_IP_ADDRESS].into() })] +#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor ( [DEFAULT_IP_ADDRESS].into() ))] async fn trust_xff_send_valid_header_single_ipv4_address(rsclient: &KanidmClient) { let ip_addr = "2001:db8:85a3:8d3:1319:8a2e:370:7348"; @@ -115,7 +115,7 @@ async fn trust_xff_send_valid_header_single_ipv4_address(rsclient: &KanidmClient assert_eq!(ip_res, IpAddr::from_str(ip_addr).unwrap()); } -#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor { trusted: [DEFAULT_IP_ADDRESS].into() })] +#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor ( [DEFAULT_IP_ADDRESS].into() ))] async fn trust_xff_send_valid_header_single_ipv6_address(rsclient: &KanidmClient) { let ip_addr = "203.0.113.195"; @@ -135,7 +135,7 @@ async fn trust_xff_send_valid_header_single_ipv6_address(rsclient: &KanidmClient assert_eq!(ip_res, IpAddr::from_str(ip_addr).unwrap()); } -#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor { trusted: [DEFAULT_IP_ADDRESS].into() })] +#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor ( [DEFAULT_IP_ADDRESS].into() ))] async fn trust_xff_send_valid_header_multiple_address(rsclient: &KanidmClient) { let first_ip_addr = "203.0.113.195, 2001:db8:85a3:8d3:1319:8a2e:370:7348"; @@ -176,7 +176,7 @@ async fn trust_xff_send_valid_header_multiple_address(rsclient: &KanidmClient) { ); } -#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor { trusted: [DEFAULT_IP_ADDRESS].into() })] +#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor ( [DEFAULT_IP_ADDRESS].into() ))] async fn trust_xff_dont_send_header(rsclient: &KanidmClient) { let client = rsclient.client();