mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-13 05:07:23 +08:00
feat(acl): add group-based ACL rules and related structures (#1265)
* feat(acl): add group-based ACL rules and related structures * refactor(acl): optimize group handling with Arc and improve cache management * refactor(acl): clippy * feat(tests): add performance tests for generate_with_proof and verify methods * feat: update group_trust_map to use HashMap for more secure group proofs * refactor: refactor the logic of the trusted group getting and setting * feat(acl): support kcp/quic use group acl * feat(proxy): optimize group retrieval by IP in Kcp and Quic proxy handlers * feat(tests): add group-based ACL tree node test * always allow quic proxy traffic --------- Co-authored-by: Sijie.Sun <sunsijie@buaa.edu.cn> Co-authored-by: sijie.sun <sijie.sun@smartx.com>
This commit is contained in:
@@ -440,12 +440,13 @@ impl KcpProxyDst {
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(ret)]
|
||||
#[tracing::instrument(ret, skip(route))]
|
||||
async fn handle_one_in_stream(
|
||||
kcp_stream: KcpStream,
|
||||
global_ctx: ArcGlobalCtx,
|
||||
proxy_entries: Arc<DashMap<ConnId, TcpProxyEntry>>,
|
||||
cidr_set: Arc<CidrSet>,
|
||||
route: Arc<(dyn crate::peers::route_trait::Route + Send + Sync + 'static)>,
|
||||
) -> Result<()> {
|
||||
let mut conn_data = kcp_stream.conn_data().clone();
|
||||
let parsed_conn_data = KcpConnData::decode(&mut conn_data)
|
||||
@@ -481,6 +482,13 @@ impl KcpProxyDst {
|
||||
proxy_entries.remove(&conn_id);
|
||||
}
|
||||
|
||||
let src_ip = src_socket.ip();
|
||||
let dst_ip = dst_socket.ip();
|
||||
let (src_groups, dst_groups) = tokio::join!(
|
||||
route.get_peer_groups_by_ip(&src_ip),
|
||||
route.get_peer_groups_by_ip(&dst_ip)
|
||||
);
|
||||
|
||||
let send_to_self =
|
||||
Some(dst_socket.ip()) == global_ctx.get_ipv4().map(|ip| IpAddr::V4(ip.address()));
|
||||
|
||||
@@ -491,12 +499,14 @@ impl KcpProxyDst {
|
||||
let acl_handler = ProxyAclHandler {
|
||||
acl_filter: global_ctx.get_acl_filter().clone(),
|
||||
packet_info: PacketInfo {
|
||||
src_ip: src_socket.ip(),
|
||||
dst_ip: dst_socket.ip(),
|
||||
src_ip,
|
||||
dst_ip,
|
||||
src_port: Some(src_socket.port()),
|
||||
dst_port: Some(dst_socket.port()),
|
||||
protocol: Protocol::Tcp,
|
||||
packet_size: conn_data.len(),
|
||||
src_groups,
|
||||
dst_groups,
|
||||
},
|
||||
chain_type: if send_to_self {
|
||||
ChainType::Inbound
|
||||
@@ -530,6 +540,7 @@ impl KcpProxyDst {
|
||||
let global_ctx = self.peer_manager.get_global_ctx().clone();
|
||||
let proxy_entries = self.proxy_entries.clone();
|
||||
let cidr_set = self.cidr_set.clone();
|
||||
let route = Arc::new(self.peer_manager.get_route());
|
||||
self.tasks.spawn(async move {
|
||||
while let Ok(conn) = kcp_endpoint.accept().await {
|
||||
let stream = KcpStream::new(&kcp_endpoint, conn)
|
||||
@@ -539,9 +550,16 @@ impl KcpProxyDst {
|
||||
let global_ctx = global_ctx.clone();
|
||||
let proxy_entries = proxy_entries.clone();
|
||||
let cidr_set = cidr_set.clone();
|
||||
let route = route.clone();
|
||||
tokio::spawn(async move {
|
||||
let _ = Self::handle_one_in_stream(stream, global_ctx, proxy_entries, cidr_set)
|
||||
.await;
|
||||
let _ = Self::handle_one_in_stream(
|
||||
stream,
|
||||
global_ctx,
|
||||
proxy_entries,
|
||||
cidr_set,
|
||||
route,
|
||||
)
|
||||
.await;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -247,10 +247,14 @@ pub struct QUICProxyDst {
|
||||
endpoint: Arc<quinn::Endpoint>,
|
||||
proxy_entries: Arc<DashMap<SocketAddr, TcpProxyEntry>>,
|
||||
tasks: Arc<Mutex<JoinSet<()>>>,
|
||||
route: Arc<(dyn crate::peers::route_trait::Route + Send + Sync + 'static)>,
|
||||
}
|
||||
|
||||
impl QUICProxyDst {
|
||||
pub fn new(global_ctx: ArcGlobalCtx) -> Result<Self> {
|
||||
pub fn new(
|
||||
global_ctx: ArcGlobalCtx,
|
||||
route: Arc<(dyn crate::peers::route_trait::Route + Send + Sync + 'static)>,
|
||||
) -> Result<Self> {
|
||||
let _g = global_ctx.net_ns.guard();
|
||||
let (endpoint, _) = make_server_endpoint("0.0.0.0:0".parse().unwrap())
|
||||
.map_err(|e| anyhow::anyhow!("failed to create QUIC endpoint: {}", e))?;
|
||||
@@ -261,6 +265,7 @@ impl QUICProxyDst {
|
||||
endpoint: Arc::new(endpoint),
|
||||
proxy_entries: Arc::new(DashMap::new()),
|
||||
tasks,
|
||||
route,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -270,6 +275,7 @@ impl QUICProxyDst {
|
||||
let ctx = self.global_ctx.clone();
|
||||
let cidr_set = Arc::new(CidrSet::new(ctx.clone()));
|
||||
let proxy_entries = self.proxy_entries.clone();
|
||||
let route = self.route.clone();
|
||||
|
||||
let task = async move {
|
||||
loop {
|
||||
@@ -289,6 +295,7 @@ impl QUICProxyDst {
|
||||
ctx.clone(),
|
||||
cidr_set.clone(),
|
||||
proxy_entries.clone(),
|
||||
route.clone(),
|
||||
));
|
||||
}
|
||||
None => {
|
||||
@@ -312,6 +319,7 @@ impl QUICProxyDst {
|
||||
ctx: Arc<GlobalCtx>,
|
||||
cidr_set: Arc<CidrSet>,
|
||||
proxy_entries: Arc<DashMap<SocketAddr, TcpProxyEntry>>,
|
||||
route: Arc<(dyn crate::peers::route_trait::Route + Send + Sync + 'static)>,
|
||||
) {
|
||||
let remote_addr = conn.remote_address();
|
||||
defer!(
|
||||
@@ -319,7 +327,14 @@ impl QUICProxyDst {
|
||||
);
|
||||
let ret = timeout(
|
||||
std::time::Duration::from_secs(10),
|
||||
Self::handle_connection(conn, ctx, cidr_set, remote_addr, proxy_entries.clone()),
|
||||
Self::handle_connection(
|
||||
conn,
|
||||
ctx,
|
||||
cidr_set,
|
||||
remote_addr,
|
||||
proxy_entries.clone(),
|
||||
route,
|
||||
),
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -348,6 +363,7 @@ impl QUICProxyDst {
|
||||
cidr_set: Arc<CidrSet>,
|
||||
proxy_entry_key: SocketAddr,
|
||||
proxy_entries: Arc<DashMap<SocketAddr, TcpProxyEntry>>,
|
||||
route: Arc<(dyn crate::peers::route_trait::Route + Send + Sync + 'static)>,
|
||||
) -> Result<(QUICStream, TcpStream, ProxyAclHandler)> {
|
||||
let conn = incoming.await.with_context(|| "accept failed")?;
|
||||
let addr = conn.remote_address();
|
||||
@@ -379,6 +395,13 @@ impl QUICProxyDst {
|
||||
dst_socket.set_ip(real_ip);
|
||||
}
|
||||
|
||||
let src_ip = addr.ip();
|
||||
let dst_ip = *dst_socket.ip();
|
||||
let (src_groups, dst_groups) = tokio::join!(
|
||||
route.get_peer_groups_by_ip(&src_ip),
|
||||
route.get_peer_groups_by_ipv4(&dst_ip)
|
||||
);
|
||||
|
||||
let send_to_self = Some(*dst_socket.ip()) == ctx.get_ipv4().map(|ip| ip.address());
|
||||
if send_to_self && ctx.no_tun() {
|
||||
dst_socket = format!("127.0.0.1:{}", dst_socket.port()).parse().unwrap();
|
||||
@@ -398,12 +421,14 @@ impl QUICProxyDst {
|
||||
let acl_handler = ProxyAclHandler {
|
||||
acl_filter: ctx.get_acl_filter().clone(),
|
||||
packet_info: PacketInfo {
|
||||
src_ip: addr.ip(),
|
||||
dst_ip: (*dst_socket.ip()).into(),
|
||||
src_ip,
|
||||
dst_ip: dst_ip.into(),
|
||||
src_port: Some(addr.port()),
|
||||
dst_port: Some(dst_socket.port()),
|
||||
protocol: Protocol::Tcp,
|
||||
packet_size: len as usize,
|
||||
src_groups,
|
||||
dst_groups,
|
||||
},
|
||||
chain_type: if send_to_self {
|
||||
ChainType::Inbound
|
||||
|
||||
Reference in New Issue
Block a user