mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-12 12:47:25 +08:00
cli for port forward and tcp whitelist (#1165)
This commit is contained in:
@@ -29,10 +29,7 @@ use easytier::{
|
||||
connector::create_connector_by_url,
|
||||
instance_manager::NetworkInstanceManager,
|
||||
launcher::{add_proxy_network_to_config, ConfigSource},
|
||||
proto::{
|
||||
acl::{Acl, AclV1, Action, Chain, ChainType, Protocol, Rule},
|
||||
common::{CompressionAlgoPb, NatType},
|
||||
},
|
||||
proto::common::{CompressionAlgoPb, NatType},
|
||||
tunnel::{IpVersion, PROTO_PORT_OFFSET},
|
||||
utils::{init_logger, setup_panic_handler},
|
||||
web_client,
|
||||
@@ -622,115 +619,6 @@ impl NetworkOptions {
|
||||
false
|
||||
}
|
||||
|
||||
fn parse_port_list(port_list: &[String]) -> anyhow::Result<Vec<String>> {
|
||||
let mut ports = Vec::new();
|
||||
|
||||
for port_spec in port_list {
|
||||
if port_spec.contains('-') {
|
||||
// Handle port range like "8000-9000"
|
||||
let parts: Vec<&str> = port_spec.split('-').collect();
|
||||
if parts.len() != 2 {
|
||||
return Err(anyhow::anyhow!("Invalid port range format: {}", port_spec));
|
||||
}
|
||||
|
||||
let start: u16 = parts[0]
|
||||
.parse()
|
||||
.with_context(|| format!("Invalid start port in range: {}", port_spec))?;
|
||||
let end: u16 = parts[1]
|
||||
.parse()
|
||||
.with_context(|| format!("Invalid end port in range: {}", port_spec))?;
|
||||
|
||||
if start > end {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Start port must be <= end port in range: {}",
|
||||
port_spec
|
||||
));
|
||||
}
|
||||
|
||||
// acl can handle port range
|
||||
ports.push(port_spec.clone());
|
||||
} else {
|
||||
// Handle single port
|
||||
let port: u16 = port_spec
|
||||
.parse()
|
||||
.with_context(|| format!("Invalid port number: {}", port_spec))?;
|
||||
ports.push(port.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ports)
|
||||
}
|
||||
|
||||
fn generate_acl_from_whitelists(&self) -> anyhow::Result<Option<Acl>> {
|
||||
if self.tcp_whitelist.is_empty() && self.udp_whitelist.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let mut acl = Acl {
|
||||
acl_v1: Some(AclV1 { chains: vec![] }),
|
||||
};
|
||||
|
||||
let acl_v1 = acl.acl_v1.as_mut().unwrap();
|
||||
|
||||
// Create inbound chain for whitelist rules
|
||||
let mut inbound_chain = Chain {
|
||||
name: "inbound_whitelist".to_string(),
|
||||
chain_type: ChainType::Inbound as i32,
|
||||
description: "Auto-generated inbound whitelist from CLI".to_string(),
|
||||
enabled: true,
|
||||
rules: vec![],
|
||||
default_action: Action::Drop as i32, // Default deny
|
||||
};
|
||||
|
||||
let mut rule_priority = 1000u32;
|
||||
|
||||
// Add TCP whitelist rules
|
||||
if !self.tcp_whitelist.is_empty() {
|
||||
let tcp_ports = Self::parse_port_list(&self.tcp_whitelist)?;
|
||||
let tcp_rule = Rule {
|
||||
name: "tcp_whitelist".to_string(),
|
||||
description: "Auto-generated TCP whitelist rule".to_string(),
|
||||
priority: rule_priority,
|
||||
enabled: true,
|
||||
protocol: Protocol::Tcp as i32,
|
||||
ports: tcp_ports,
|
||||
source_ips: vec![],
|
||||
destination_ips: vec![],
|
||||
source_ports: vec![],
|
||||
action: Action::Allow as i32,
|
||||
rate_limit: 0,
|
||||
burst_limit: 0,
|
||||
stateful: true,
|
||||
};
|
||||
inbound_chain.rules.push(tcp_rule);
|
||||
rule_priority -= 1;
|
||||
}
|
||||
|
||||
// Add UDP whitelist rules
|
||||
if !self.udp_whitelist.is_empty() {
|
||||
let udp_ports = Self::parse_port_list(&self.udp_whitelist)?;
|
||||
let udp_rule = Rule {
|
||||
name: "udp_whitelist".to_string(),
|
||||
description: "Auto-generated UDP whitelist rule".to_string(),
|
||||
priority: rule_priority,
|
||||
enabled: true,
|
||||
protocol: Protocol::Udp as i32,
|
||||
ports: udp_ports,
|
||||
source_ips: vec![],
|
||||
destination_ips: vec![],
|
||||
source_ports: vec![],
|
||||
action: Action::Allow as i32,
|
||||
rate_limit: 0,
|
||||
burst_limit: 0,
|
||||
stateful: false,
|
||||
};
|
||||
inbound_chain.rules.push(udp_rule);
|
||||
}
|
||||
|
||||
acl_v1.chains.push(inbound_chain);
|
||||
Ok(Some(acl))
|
||||
}
|
||||
|
||||
fn merge_into(&self, cfg: &mut TomlConfigLoader) -> anyhow::Result<()> {
|
||||
if self.hostname.is_some() {
|
||||
cfg.set_hostname(self.hostname.clone());
|
||||
@@ -988,10 +876,13 @@ impl NetworkOptions {
|
||||
cfg.set_exit_nodes(self.exit_nodes.clone());
|
||||
}
|
||||
|
||||
// Handle port whitelists by generating ACL configuration
|
||||
if let Some(acl) = self.generate_acl_from_whitelists()? {
|
||||
cfg.set_acl(Some(acl));
|
||||
}
|
||||
let mut old_tcp_whitelist = cfg.get_tcp_whitelist();
|
||||
old_tcp_whitelist.extend(self.tcp_whitelist.clone());
|
||||
cfg.set_tcp_whitelist(old_tcp_whitelist);
|
||||
|
||||
let mut old_udp_whitelist = cfg.get_udp_whitelist();
|
||||
old_udp_whitelist.extend(self.udp_whitelist.clone());
|
||||
cfg.set_udp_whitelist(old_udp_whitelist);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user