feat(security): add domain-scoped IP allow list support across HTTP and passthrough filtering

This commit is contained in:
2026-04-06 12:46:09 +00:00
parent 572e31587a
commit 99a026627d
11 changed files with 256 additions and 57 deletions

View File

@@ -100,7 +100,7 @@ impl ConnectionRegistry {
let mut recycled = 0u64;
self.connections.retain(|_, entry| {
if entry.route_id.as_deref() == Some(route_id) {
if !RequestFilter::check_ip_security(new_security, &entry.source_ip) {
if !RequestFilter::check_ip_security(new_security, &entry.source_ip, entry.domain.as_deref()) {
info!(
"Terminating connection from {} — IP now blocked on route '{}'",
entry.source_ip, route_id

View File

@@ -409,10 +409,10 @@ pub async fn quic_accept_loop(
}
};
// Check route-level IP security (previously missing for QUIC)
// Check route-level IP security for QUIC (domain from SNI context)
if let Some(ref security) = route.security {
if !rustproxy_http::request_filter::RequestFilter::check_ip_security(
security, &ip,
security, &ip, ctx.domain,
) {
debug!("QUIC connection from {} blocked by route security", real_addr);
continue;

View File

@@ -737,10 +737,10 @@ impl TcpListenerManager {
},
);
// Check route-level IP security
// Check route-level IP security (fast path: no SNI available)
if let Some(ref security) = quick_match.route.security {
if !rustproxy_http::request_filter::RequestFilter::check_ip_security(
security, &peer_addr.ip(),
security, &peer_addr.ip(), None,
) {
warn!("Connection from {} blocked by route security", peer_addr);
return Ok(());
@@ -929,11 +929,12 @@ impl TcpListenerManager {
},
);
// Check route-level IP security for passthrough connections
// Check route-level IP security for passthrough connections (SNI available)
if let Some(ref security) = route_match.route.security {
if !rustproxy_http::request_filter::RequestFilter::check_ip_security(
security,
&peer_addr.ip(),
domain.as_deref(),
) {
warn!("Connection from {} blocked by route security", peer_addr);
return Ok(());