From 8f1f051a547b62e5ff01c80c33700486bdf49c84 Mon Sep 17 00:00:00 2001 From: artemws <59208085+artemws@users.noreply.github.com> Date: Fri, 20 Feb 2026 16:03:03 +0200 Subject: [PATCH 1/4] Add ipnetwork dependency to Cargo.toml --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 62f32d0..cdfbda9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ anyhow = "1.0" # HTTP reqwest = { version = "0.12", features = ["rustls-tls"], default-features = false } notify = { version = "6", features = ["macos_fsevent"] } +ipnetwork = "0.20" hyper = { version = "1", features = ["server", "http1"] } hyper-util = { version = "0.1", features = ["tokio", "server-auto"] } http-body-util = "0.1" From dbd9b5394007e1591fd09bde5d04a79230293a87 Mon Sep 17 00:00:00 2001 From: artemws <59208085+artemws@users.noreply.github.com> Date: Fri, 20 Feb 2026 16:03:38 +0200 Subject: [PATCH 2/4] Change metrics_whitelist type from Vec to Vec --- src/config/types.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config/types.rs b/src/config/types.rs index fa69c12..832070a 100644 --- a/src/config/types.rs +++ b/src/config/types.rs @@ -1,4 +1,5 @@ use chrono::{DateTime, Utc}; +use ipnetwork::IpNetwork; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::net::IpAddr; @@ -304,7 +305,7 @@ pub struct ServerConfig { pub metrics_port: Option, #[serde(default = "default_metrics_whitelist")] - pub metrics_whitelist: Vec, + pub metrics_whitelist: Vec, #[serde(default)] pub listeners: Vec, From 0d2958fea77b811075490c25efc1bb875cfd6986 Mon Sep 17 00:00:00 2001 From: artemws <59208085+artemws@users.noreply.github.com> Date: Fri, 20 Feb 2026 16:03:57 +0200 Subject: [PATCH 3/4] Change metrics whitelist to use IpNetwork --- src/config/defaults.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/config/defaults.rs b/src/config/defaults.rs index a022021..f9d878a 100644 --- a/src/config/defaults.rs +++ b/src/config/defaults.rs @@ -1,5 +1,6 @@ use std::net::IpAddr; use std::collections::HashMap; +use ipnetwork::IpNetwork; use serde::Deserialize; // Helper defaults kept private to the config module. @@ -66,8 +67,11 @@ pub(crate) fn default_weight() -> u16 { 1 } -pub(crate) fn default_metrics_whitelist() -> Vec { - vec!["127.0.0.1".parse().unwrap(), "::1".parse().unwrap()] +pub(crate) fn default_metrics_whitelist() -> Vec { + vec![ + "127.0.0.1/32".parse().unwrap(), + "::1/128".parse().unwrap(), + ] } pub(crate) fn default_prefer_4() -> u8 { From 88928604907aeba0d70a75ed2078b87bc0c78d66 Mon Sep 17 00:00:00 2001 From: artemws <59208085+artemws@users.noreply.github.com> Date: Fri, 20 Feb 2026 16:04:21 +0200 Subject: [PATCH 4/4] Change whitelist to use IpNetwork for IP filtering --- src/metrics.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/metrics.rs b/src/metrics.rs index fa6c680..5222295 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -1,5 +1,5 @@ use std::convert::Infallible; -use std::net::{IpAddr, SocketAddr}; +use std::net::SocketAddr; use std::sync::Arc; use http_body_util::Full; @@ -7,12 +7,13 @@ use hyper::body::Bytes; use hyper::server::conn::http1; use hyper::service::service_fn; use hyper::{Request, Response, StatusCode}; +use ipnetwork::IpNetwork; use tokio::net::TcpListener; use tracing::{info, warn, debug}; use crate::stats::Stats; -pub async fn serve(port: u16, stats: Arc, whitelist: Vec) { +pub async fn serve(port: u16, stats: Arc, whitelist: Vec) { let addr = SocketAddr::from(([0, 0, 0, 0], port)); let listener = match TcpListener::bind(addr).await { Ok(l) => l, @@ -32,7 +33,7 @@ pub async fn serve(port: u16, stats: Arc, whitelist: Vec) { } }; - if !whitelist.is_empty() && !whitelist.contains(&peer.ip()) { + if !whitelist.is_empty() && !whitelist.iter().any(|net| net.contains(peer.ip())) { debug!(peer = %peer, "Metrics request denied by whitelist"); continue; }