From 2bc51daa9869697da0916fd38f7bdc44d8039c6c Mon Sep 17 00:00:00 2001 From: KKRainbow <443152178@qq.com> Date: Mon, 8 Dec 2025 21:56:27 +0800 Subject: [PATCH] fix whitelist cause packets of other protocal dropped (#1660) --- easytier/src/common/acl_processor.rs | 38 ++++++++++- easytier/src/tests/three_node.rs | 94 ++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) diff --git a/easytier/src/common/acl_processor.rs b/easytier/src/common/acl_processor.rs index 51743a3f..3a86d98d 100644 --- a/easytier/src/common/acl_processor.rs +++ b/easytier/src/common/acl_processor.rs @@ -1100,7 +1100,7 @@ impl AclRuleBuilder { description: "Auto-generated inbound whitelist from CLI".to_string(), enabled: true, rules: vec![], - default_action: Action::Drop as i32, // Default deny + default_action: Action::Allow as i32, }; let mut rule_priority = self.whitelist_priority.unwrap_or(1000u32); @@ -1125,7 +1125,25 @@ impl AclRuleBuilder { source_groups: vec![], destination_groups: vec![], }; + let tcp_rule_deny_other = Rule { + name: "tcp_whitelist_deny_other".to_string(), + description: "Auto-generated TCP whitelist rule to deny other ports".to_string(), + priority: 0, + enabled: true, + protocol: Protocol::Tcp as i32, + ports: vec!["0-65535".to_string()], + source_ips: vec![], + destination_ips: vec![], + source_ports: vec![], + action: Action::Drop as i32, + rate_limit: 0, + burst_limit: 0, + stateful: false, + source_groups: vec![], + destination_groups: vec![], + }; inbound_chain.rules.push(tcp_rule); + inbound_chain.rules.push(tcp_rule_deny_other); rule_priority -= 1; } @@ -1149,7 +1167,25 @@ impl AclRuleBuilder { source_groups: vec![], destination_groups: vec![], }; + let udp_rule_deny_other = Rule { + name: "udp_whitelist_deny_other".to_string(), + description: "Auto-generated UDP whitelist rule to deny other ports".to_string(), + priority: 0, + enabled: true, + protocol: Protocol::Udp as i32, + ports: vec!["0-65535".to_string()], + source_ips: vec![], + destination_ips: vec![], + source_ports: vec![], + action: Action::Drop as i32, + rate_limit: 0, + burst_limit: 0, + stateful: false, + source_groups: vec![], + destination_groups: vec![], + }; inbound_chain.rules.push(udp_rule); + inbound_chain.rules.push(udp_rule_deny_other); } if self.acl.is_none() { diff --git a/easytier/src/tests/three_node.rs b/easytier/src/tests/three_node.rs index c9eb9780..9730b1f1 100644 --- a/easytier/src/tests/three_node.rs +++ b/easytier/src/tests/three_node.rs @@ -2465,6 +2465,100 @@ pub async fn acl_group_self_test( drop_insts(insts).await; } +#[rstest::rstest] +#[tokio::test] +#[serial_test::serial] +pub async fn whitelist_test(#[values("tcp", "udp")] protocol: &str) { + let port = 44553; + let insts = init_three_node_ex( + protocol, + move |cfg| { + if cfg.get_inst_name() == "inst3" { + if protocol == "tcp" { + cfg.set_tcp_whitelist(vec![format!("{}", port)]); + } else if protocol == "udp" { + cfg.set_udp_whitelist(vec![format!("{}", port)]); + } + } + cfg + }, + false, + ) + .await; + + use crate::tunnel::{ + common::tests::_tunnel_pingpong_netns_with_timeout, + tcp::{TcpTunnelConnector, TcpTunnelListener}, + udp::{UdpTunnelConnector, UdpTunnelListener}, + TunnelConnector, TunnelListener, + }; + use rand::Rng; + + let make_listener = + |protocol: &str, port: u16| -> Box { + match protocol { + "tcp" => Box::new(TcpTunnelListener::new( + format!("tcp://0.0.0.0:{}", port).parse().unwrap(), + )), + "udp" => Box::new(UdpTunnelListener::new( + format!("udp://0.0.0.0:{}", port).parse().unwrap(), + )), + _ => panic!("unsupported protocol: {}", protocol), + } + }; + + let make_connector = + |protocol: &str, port: u16| -> Box { + match protocol { + "tcp" => Box::new(TcpTunnelConnector::new( + format!("tcp://10.144.144.3:{}", port).parse().unwrap(), + )), + "udp" => Box::new(UdpTunnelConnector::new( + format!("udp://10.144.144.3:{}", port).parse().unwrap(), + )), + _ => panic!("unsupported protocol: {}", protocol), + } + }; + + let mut buf = vec![0; 32]; + rand::thread_rng().fill(&mut buf[..]); + + for p in &["tcp", "udp"] { + _tunnel_pingpong_netns_with_timeout( + make_listener(p, port), + make_connector(p, port), + NetNS::new(Some("net_c".into())), + NetNS::new(Some("net_a".into())), + buf.clone(), + std::time::Duration::from_millis(100), + ) + .await + .unwrap_or_else(|_| panic!("{} should be allowed", p)); + } + + // test other port + let other_port = port + 1; + for p in ["tcp", "udp"] { + let r = _tunnel_pingpong_netns_with_timeout( + make_listener(p, other_port), + make_connector(p, other_port), + NetNS::new(Some("net_c".into())), + NetNS::new(Some("net_a".into())), + buf.clone(), + std::time::Duration::from_millis(100), + ) + .await; + + if p != protocol { + assert!(r.is_ok(), "{} should be allowed", p); + } else { + assert!(r.is_err(), "{} should be blocked", p); + } + } + + drop_insts(insts).await; +} + #[rstest::rstest] #[tokio::test] #[serial_test::serial]