diff --git a/easytier-web/frontend-lib/src/components/Config.vue b/easytier-web/frontend-lib/src/components/Config.vue
index 5b4d1f7e..e38fa3ea 100644
--- a/easytier-web/frontend-lib/src/components/Config.vue
+++ b/easytier-web/frontend-lib/src/components/Config.vue
@@ -304,6 +304,15 @@ const bool_flags: BoolFlag[] = [
+
diff --git a/easytier-web/frontend-lib/src/locales/cn.yaml b/easytier-web/frontend-lib/src/locales/cn.yaml
index e0e16718..9c3d241a 100644
--- a/easytier-web/frontend-lib/src/locales/cn.yaml
+++ b/easytier-web/frontend-lib/src/locales/cn.yaml
@@ -18,6 +18,7 @@ advanced_settings: 高级设置
basic_settings: 基础设置
listener_urls: 监听地址
rpc_port: RPC端口
+rpc_portal_whitelists: RPC白名单
config_network: 配置网络
running: 运行中
error_msg: 错误信息
diff --git a/easytier-web/frontend-lib/src/locales/en.yaml b/easytier-web/frontend-lib/src/locales/en.yaml
index 1d6e167c..bf9629f9 100644
--- a/easytier-web/frontend-lib/src/locales/en.yaml
+++ b/easytier-web/frontend-lib/src/locales/en.yaml
@@ -18,6 +18,7 @@ advanced_settings: Advanced Settings
basic_settings: Basic Settings
listener_urls: Listener URLs
rpc_port: RPC Port
+rpc_portal_whitelists: RPC Whitelist
config_network: Config Network
running: Running
error_msg: Error Message
diff --git a/easytier-web/frontend-lib/src/types/network.ts b/easytier-web/frontend-lib/src/types/network.ts
index 6f1af40b..421d61f1 100644
--- a/easytier-web/frontend-lib/src/types/network.ts
+++ b/easytier-web/frontend-lib/src/types/network.ts
@@ -65,6 +65,8 @@ export interface NetworkConfig {
enable_magic_dns?: boolean
enable_private_mode?: boolean
+
+ rpc_portal_whitelists: string[]
}
export function DEFAULT_NETWORK_CONFIG(): NetworkConfig {
@@ -123,6 +125,7 @@ export function DEFAULT_NETWORK_CONFIG(): NetworkConfig {
mapped_listeners: [],
enable_magic_dns: false,
enable_private_mode: false,
+ rpc_portal_whitelists: [],
}
}
diff --git a/easytier/locales/app.yml b/easytier/locales/app.yml
index e68a0e94..e5377c3d 100644
--- a/easytier/locales/app.yml
+++ b/easytier/locales/app.yml
@@ -37,6 +37,9 @@ core_clap:
rpc_portal:
en: "rpc portal address to listen for management. 0 means random port, 12345 means listen on 12345 of localhost, 0.0.0.0:12345 means listen on 12345 of all interfaces. default is 0 and will try 15888 first"
zh-CN: "用于管理的RPC门户地址。0表示随机端口,12345表示在localhost的12345上监听,0.0.0.0:12345表示在所有接口的12345上监听。默认是0,首先尝试15888"
+ rpc_portal_whitelist:
+ en: "rpc portal whitelist, only allow these addresses to access rpc portal, e.g.: 127.0.0.1,127.0.0.0/8,::1/128"
+ zh-CN: "RPC门户白名单,仅允许这些地址访问RPC门户,例如:127.0.0.1/32,127.0.0.0/8,::1/128"
listeners:
en: |+
listeners to accept connections, allow format:
diff --git a/easytier/src/common/config.rs b/easytier/src/common/config.rs
index cdb8be68..9798b323 100644
--- a/easytier/src/common/config.rs
+++ b/easytier/src/common/config.rs
@@ -5,6 +5,7 @@ use std::{
};
use anyhow::Context;
+use cidr::IpCidr;
use serde::{Deserialize, Serialize};
use crate::{
@@ -87,6 +88,9 @@ pub trait ConfigLoader: Send + Sync {
fn get_rpc_portal(&self) -> Option;
fn set_rpc_portal(&self, addr: SocketAddr);
+ fn get_rpc_portal_whitelist(&self) -> Option>;
+ fn set_rpc_portal_whitelist(&self, whitelist: Option>);
+
fn get_vpn_portal_config(&self) -> Option;
fn set_vpn_portal_config(&self, config: VpnPortalConfig);
@@ -243,6 +247,7 @@ struct Config {
console_logger: Option,
rpc_portal: Option,
+ rpc_portal_whitelist: Option>,
vpn_portal_config: Option,
@@ -544,6 +549,14 @@ impl ConfigLoader for TomlConfigLoader {
self.config.lock().unwrap().rpc_portal = Some(addr);
}
+ fn get_rpc_portal_whitelist(&self) -> Option> {
+ self.config.lock().unwrap().rpc_portal_whitelist.clone()
+ }
+
+ fn set_rpc_portal_whitelist(&self, whitelist: Option>) {
+ self.config.lock().unwrap().rpc_portal_whitelist = whitelist;
+ }
+
fn get_vpn_portal_config(&self) -> Option {
self.config.lock().unwrap().vpn_portal_config.clone()
}
diff --git a/easytier/src/easytier-core.rs b/easytier/src/easytier-core.rs
index fa058e45..e209f37a 100644
--- a/easytier/src/easytier-core.rs
+++ b/easytier/src/easytier-core.rs
@@ -11,6 +11,7 @@ use std::{
};
use anyhow::Context;
+use cidr::IpCidr;
use clap::Parser;
use easytier::{
@@ -176,6 +177,14 @@ struct Cli {
)]
rpc_portal: Option,
+ #[arg(
+ long,
+ env = "ET_RPC_PORTAL_WHITELIST",
+ value_delimiter = ',',
+ help = t!("core_clap.rpc_portal_whitelist").to_string(),
+ )]
+ rpc_portal_whitelist: Option>,
+
#[arg(
short,
long,
@@ -616,6 +625,8 @@ impl TryFrom<&Cli> for TomlConfigLoader {
};
cfg.set_rpc_portal(rpc_portal);
+ cfg.set_rpc_portal_whitelist(cli.rpc_portal_whitelist.clone());
+
if let Some(external_nodes) = cli.external_node.as_ref() {
let mut old_peers = cfg.get_peers();
old_peers.push(PeerConfig {
diff --git a/easytier/src/instance/dns_server/server_instance.rs b/easytier/src/instance/dns_server/server_instance.rs
index f7695494..1e1f8f07 100644
--- a/easytier/src/instance/dns_server/server_instance.rs
+++ b/easytier/src/instance/dns_server/server_instance.rs
@@ -298,12 +298,13 @@ impl NicPacketFilter for MagicDnsServerInstanceData {
#[async_trait::async_trait]
impl RpcServerHook for MagicDnsServerInstanceData {
- async fn on_new_client(&self, tunnel_info: Option) {
- println!("New client connected: {:?}", tunnel_info);
+ async fn on_new_client(&self, tunnel_info: Option)-> Result