mirror of
https://github.com/EasyTier/EasyTier.git
synced 2025-09-27 04:56:07 +08:00
close peer conn if remote addr is from virtual network (#1123)
Some checks failed
EasyTier Core / pre_job (push) Has been cancelled
EasyTier Core / build_web (push) Has been cancelled
EasyTier Core / build (freebsd-13.2-x86_64, 13.2, ubuntu-22.04, x86_64-unknown-freebsd) (push) Has been cancelled
EasyTier Core / build (linux-aarch64, ubuntu-22.04, aarch64-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-arm, ubuntu-22.04, arm-unknown-linux-musleabi) (push) Has been cancelled
EasyTier Core / build (linux-armhf, ubuntu-22.04, arm-unknown-linux-musleabihf) (push) Has been cancelled
EasyTier Core / build (linux-armv7, ubuntu-22.04, armv7-unknown-linux-musleabi) (push) Has been cancelled
EasyTier Core / build (linux-armv7hf, ubuntu-22.04, armv7-unknown-linux-musleabihf) (push) Has been cancelled
EasyTier Core / build (linux-mips, ubuntu-22.04, mips-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-mipsel, ubuntu-22.04, mipsel-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-x86_64, ubuntu-22.04, x86_64-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (macos-aarch64, macos-latest, aarch64-apple-darwin) (push) Has been cancelled
EasyTier Core / build (macos-x86_64, macos-latest, x86_64-apple-darwin) (push) Has been cancelled
EasyTier Core / build (windows-arm64, windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
EasyTier Core / build (windows-i686, windows-latest, i686-pc-windows-msvc) (push) Has been cancelled
EasyTier Core / build (windows-x86_64, windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
EasyTier Core / core-result (push) Has been cancelled
EasyTier Core / magisk_build (push) Has been cancelled
EasyTier GUI / pre_job (push) Has been cancelled
EasyTier GUI / build-gui (linux-aarch64, aarch64-unknown-linux-gnu, ubuntu-22.04, aarch64-unknown-linux-musl) (push) Has been cancelled
EasyTier GUI / build-gui (linux-x86_64, x86_64-unknown-linux-gnu, ubuntu-22.04, x86_64-unknown-linux-musl) (push) Has been cancelled
EasyTier GUI / build-gui (macos-aarch64, aarch64-apple-darwin, macos-latest, aarch64-apple-darwin) (push) Has been cancelled
EasyTier GUI / build-gui (macos-x86_64, x86_64-apple-darwin, macos-latest, x86_64-apple-darwin) (push) Has been cancelled
EasyTier GUI / build-gui (windows-arm64, aarch64-pc-windows-msvc, windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
EasyTier GUI / build-gui (windows-i686, i686-pc-windows-msvc, windows-latest, i686-pc-windows-msvc) (push) Has been cancelled
EasyTier GUI / build-gui (windows-x86_64, x86_64-pc-windows-msvc, windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
EasyTier GUI / gui-result (push) Has been cancelled
EasyTier Mobile / pre_job (push) Has been cancelled
EasyTier Mobile / build-mobile (android, ubuntu-22.04, android) (push) Has been cancelled
EasyTier Mobile / mobile-result (push) Has been cancelled
EasyTier OHOS / pre_job (push) Has been cancelled
EasyTier OHOS / build-ohos (push) Has been cancelled
EasyTier Test / pre_job (push) Has been cancelled
EasyTier Test / test (push) Has been cancelled
Some checks failed
EasyTier Core / pre_job (push) Has been cancelled
EasyTier Core / build_web (push) Has been cancelled
EasyTier Core / build (freebsd-13.2-x86_64, 13.2, ubuntu-22.04, x86_64-unknown-freebsd) (push) Has been cancelled
EasyTier Core / build (linux-aarch64, ubuntu-22.04, aarch64-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-arm, ubuntu-22.04, arm-unknown-linux-musleabi) (push) Has been cancelled
EasyTier Core / build (linux-armhf, ubuntu-22.04, arm-unknown-linux-musleabihf) (push) Has been cancelled
EasyTier Core / build (linux-armv7, ubuntu-22.04, armv7-unknown-linux-musleabi) (push) Has been cancelled
EasyTier Core / build (linux-armv7hf, ubuntu-22.04, armv7-unknown-linux-musleabihf) (push) Has been cancelled
EasyTier Core / build (linux-mips, ubuntu-22.04, mips-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-mipsel, ubuntu-22.04, mipsel-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (linux-x86_64, ubuntu-22.04, x86_64-unknown-linux-musl) (push) Has been cancelled
EasyTier Core / build (macos-aarch64, macos-latest, aarch64-apple-darwin) (push) Has been cancelled
EasyTier Core / build (macos-x86_64, macos-latest, x86_64-apple-darwin) (push) Has been cancelled
EasyTier Core / build (windows-arm64, windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
EasyTier Core / build (windows-i686, windows-latest, i686-pc-windows-msvc) (push) Has been cancelled
EasyTier Core / build (windows-x86_64, windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
EasyTier Core / core-result (push) Has been cancelled
EasyTier Core / magisk_build (push) Has been cancelled
EasyTier GUI / pre_job (push) Has been cancelled
EasyTier GUI / build-gui (linux-aarch64, aarch64-unknown-linux-gnu, ubuntu-22.04, aarch64-unknown-linux-musl) (push) Has been cancelled
EasyTier GUI / build-gui (linux-x86_64, x86_64-unknown-linux-gnu, ubuntu-22.04, x86_64-unknown-linux-musl) (push) Has been cancelled
EasyTier GUI / build-gui (macos-aarch64, aarch64-apple-darwin, macos-latest, aarch64-apple-darwin) (push) Has been cancelled
EasyTier GUI / build-gui (macos-x86_64, x86_64-apple-darwin, macos-latest, x86_64-apple-darwin) (push) Has been cancelled
EasyTier GUI / build-gui (windows-arm64, aarch64-pc-windows-msvc, windows-latest, aarch64-pc-windows-msvc) (push) Has been cancelled
EasyTier GUI / build-gui (windows-i686, i686-pc-windows-msvc, windows-latest, i686-pc-windows-msvc) (push) Has been cancelled
EasyTier GUI / build-gui (windows-x86_64, x86_64-pc-windows-msvc, windows-latest, x86_64-pc-windows-msvc) (push) Has been cancelled
EasyTier GUI / gui-result (push) Has been cancelled
EasyTier Mobile / pre_job (push) Has been cancelled
EasyTier Mobile / build-mobile (android, ubuntu-22.04, android) (push) Has been cancelled
EasyTier Mobile / mobile-result (push) Has been cancelled
EasyTier OHOS / pre_job (push) Has been cancelled
EasyTier OHOS / build-ohos (push) Has been cancelled
EasyTier Test / pre_job (push) Has been cancelled
EasyTier Test / test (push) Has been cancelled
This commit is contained in:
@@ -31,8 +31,9 @@ use crate::peers::{create_packet_recv_chan, recv_packet_from_chan, PacketRecvCha
|
|||||||
use crate::proto::cli::VpnPortalRpc;
|
use crate::proto::cli::VpnPortalRpc;
|
||||||
use crate::proto::cli::{GetVpnPortalInfoRequest, GetVpnPortalInfoResponse, VpnPortalInfo};
|
use crate::proto::cli::{GetVpnPortalInfoRequest, GetVpnPortalInfoResponse, VpnPortalInfo};
|
||||||
use crate::proto::cli::{
|
use crate::proto::cli::{
|
||||||
MappedListenerManageRpc, MappedListener, ListMappedListenerRequest, ListMappedListenerResponse,
|
ListMappedListenerRequest, ListMappedListenerResponse, ManageMappedListenerRequest,
|
||||||
ManageMappedListenerRequest, MappedListenerManageAction, ManageMappedListenerResponse
|
ManageMappedListenerResponse, MappedListener, MappedListenerManageAction,
|
||||||
|
MappedListenerManageRpc,
|
||||||
};
|
};
|
||||||
use crate::proto::common::TunnelInfo;
|
use crate::proto::common::TunnelInfo;
|
||||||
use crate::proto::peer_rpc::PeerCenterRpcServer;
|
use crate::proto::peer_rpc::PeerCenterRpcServer;
|
||||||
@@ -271,6 +272,8 @@ impl Instance {
|
|||||||
peer_packet_sender.clone(),
|
peer_packet_sender.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
peer_manager.set_allow_loopback_tunnel(false);
|
||||||
|
|
||||||
let listener_manager = Arc::new(Mutex::new(ListenerManager::new(
|
let listener_manager = Arc::new(Mutex::new(ListenerManager::new(
|
||||||
global_ctx.clone(),
|
global_ctx.clone(),
|
||||||
peer_manager.clone(),
|
peer_manager.clone(),
|
||||||
@@ -719,7 +722,9 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_mapped_listener_manager_rpc_service(&self) -> impl MappedListenerManageRpc<Controller = BaseController> + Clone {
|
fn get_mapped_listener_manager_rpc_service(
|
||||||
|
&self,
|
||||||
|
) -> impl MappedListenerManageRpc<Controller = BaseController> + Clone {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MappedListenerManagerRpcService(Arc<GlobalCtx>);
|
pub struct MappedListenerManagerRpcService(Arc<GlobalCtx>);
|
||||||
|
|
||||||
@@ -736,7 +741,9 @@ impl Instance {
|
|||||||
let urls = self.0.config.get_mapped_listeners();
|
let urls = self.0.config.get_mapped_listeners();
|
||||||
let mapped_listeners: Vec<MappedListener> = urls
|
let mapped_listeners: Vec<MappedListener> = urls
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|u|MappedListener{url: Some(u.into())})
|
.map(|u| MappedListener {
|
||||||
|
url: Some(u.into()),
|
||||||
|
})
|
||||||
.collect();
|
.collect();
|
||||||
ret.mappedlisteners = mapped_listeners;
|
ret.mappedlisteners = mapped_listeners;
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
@@ -793,8 +800,10 @@ impl Instance {
|
|||||||
.register(PeerCenterRpcServer::new(peer_center.get_rpc_service()), "");
|
.register(PeerCenterRpcServer::new(peer_center.get_rpc_service()), "");
|
||||||
s.registry()
|
s.registry()
|
||||||
.register(VpnPortalRpcServer::new(vpn_portal_rpc), "");
|
.register(VpnPortalRpcServer::new(vpn_portal_rpc), "");
|
||||||
s.registry()
|
s.registry().register(
|
||||||
.register(MappedListenerManageRpcServer::new(mapped_listener_manager_rpc), "");
|
MappedListenerManageRpcServer::new(mapped_listener_manager_rpc),
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
|
||||||
if let Some(ip_proxy) = self.ip_proxy.as_ref() {
|
if let Some(ip_proxy) = self.ip_proxy.as_ref() {
|
||||||
s.registry().register(
|
s.registry().register(
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
use std::{
|
use std::{
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
net::{IpAddr, Ipv4Addr, Ipv6Addr},
|
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||||
sync::{Arc, Weak},
|
sync::{atomic::AtomicBool, Arc, Weak},
|
||||||
time::{Instant, SystemTime},
|
time::{Instant, SystemTime},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -143,6 +143,8 @@ pub struct PeerManager {
|
|||||||
exit_nodes: Vec<Ipv4Addr>,
|
exit_nodes: Vec<Ipv4Addr>,
|
||||||
|
|
||||||
reserved_my_peer_id_map: DashMap<String, PeerId>,
|
reserved_my_peer_id_map: DashMap<String, PeerId>,
|
||||||
|
|
||||||
|
allow_loopback_tunnel: AtomicBool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for PeerManager {
|
impl Debug for PeerManager {
|
||||||
@@ -271,9 +273,16 @@ impl PeerManager {
|
|||||||
exit_nodes,
|
exit_nodes,
|
||||||
|
|
||||||
reserved_my_peer_id_map: DashMap::new(),
|
reserved_my_peer_id_map: DashMap::new(),
|
||||||
|
|
||||||
|
allow_loopback_tunnel: AtomicBool::new(true),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_allow_loopback_tunnel(&self, allow_loopback_tunnel: bool) {
|
||||||
|
self.allow_loopback_tunnel
|
||||||
|
.store(allow_loopback_tunnel, std::sync::atomic::Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
fn build_foreign_network_manager_accessor(
|
fn build_foreign_network_manager_accessor(
|
||||||
peer_map: &Arc<PeerMap>,
|
peer_map: &Arc<PeerMap>,
|
||||||
) -> Box<dyn GlobalForeignNetworkAccessor> {
|
) -> Box<dyn GlobalForeignNetworkAccessor> {
|
||||||
@@ -356,6 +365,65 @@ impl PeerManager {
|
|||||||
self.add_client_tunnel(t, true).await
|
self.add_client_tunnel(t, true).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// avoid loop back to virtual network
|
||||||
|
fn check_remote_addr_not_from_virtual_network(
|
||||||
|
&self,
|
||||||
|
tunnel: &dyn Tunnel,
|
||||||
|
) -> Result<(), anyhow::Error> {
|
||||||
|
tracing::info!("check remote addr not from virtual network");
|
||||||
|
let Some(tunnel_info) = tunnel.info() else {
|
||||||
|
anyhow::bail!("tunnel info is not set");
|
||||||
|
};
|
||||||
|
let Some(src) = tunnel_info.remote_addr.map(url::Url::from) else {
|
||||||
|
anyhow::bail!("tunnel info remote addr is not set");
|
||||||
|
};
|
||||||
|
if src.scheme() == "ring" {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let src_host = match src.socket_addrs(|| Some(1)) {
|
||||||
|
Ok(addrs) => addrs,
|
||||||
|
Err(_) => {
|
||||||
|
// if the tunnel is not rely on ip address, skip check
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let virtual_ipv4 = self.global_ctx.get_ipv4().map(|ip| ip.network());
|
||||||
|
let virtual_ipv6 = self.global_ctx.get_ipv6().map(|ip| ip.network());
|
||||||
|
tracing::info!(
|
||||||
|
?virtual_ipv4,
|
||||||
|
?virtual_ipv6,
|
||||||
|
"check remote addr not from virtual network"
|
||||||
|
);
|
||||||
|
for addr in src_host {
|
||||||
|
// if no-tun is enabled, the src ip of packet in virtual network is converted to loopback address
|
||||||
|
if addr.ip().is_loopback()
|
||||||
|
&& !self
|
||||||
|
.allow_loopback_tunnel
|
||||||
|
.load(std::sync::atomic::Ordering::Relaxed)
|
||||||
|
{
|
||||||
|
anyhow::bail!("tunnel src host is loopback address");
|
||||||
|
}
|
||||||
|
|
||||||
|
match addr {
|
||||||
|
SocketAddr::V4(addr) => {
|
||||||
|
if let Some(virtual_ipv4) = virtual_ipv4 {
|
||||||
|
if virtual_ipv4.contains(&addr.ip()) {
|
||||||
|
anyhow::bail!("tunnel src host is from the virtual network (ignore this error please)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SocketAddr::V6(addr) => {
|
||||||
|
if let Some(virtual_ipv6) = virtual_ipv6 {
|
||||||
|
if virtual_ipv6.contains(&addr.ip()) {
|
||||||
|
anyhow::bail!("tunnel src host is from the virtual network (ignore this error please)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[tracing::instrument(ret)]
|
#[tracing::instrument(ret)]
|
||||||
pub async fn add_tunnel_as_server(
|
pub async fn add_tunnel_as_server(
|
||||||
&self,
|
&self,
|
||||||
@@ -363,6 +431,8 @@ impl PeerManager {
|
|||||||
is_directly_connected: bool,
|
is_directly_connected: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
tracing::info!("add tunnel as server start");
|
tracing::info!("add tunnel as server start");
|
||||||
|
self.check_remote_addr_not_from_virtual_network(&tunnel)?;
|
||||||
|
|
||||||
let mut conn = PeerConn::new(self.my_peer_id, self.global_ctx.clone(), tunnel);
|
let mut conn = PeerConn::new(self.my_peer_id, self.global_ctx.clone(), tunnel);
|
||||||
conn.do_handshake_as_server_ext(|peer, msg| {
|
conn.do_handshake_as_server_ext(|peer, msg| {
|
||||||
if msg.network_name
|
if msg.network_name
|
||||||
|
@@ -1307,3 +1307,24 @@ pub async fn relay_bps_limit_test(#[values(100, 200, 400, 800)] bps_limit: u64)
|
|||||||
|
|
||||||
drop_insts(insts).await;
|
drop_insts(insts).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn avoid_tunnel_loop_back_to_virtual_network() {
|
||||||
|
let insts = init_three_node("udp").await;
|
||||||
|
|
||||||
|
let tcp_connector = TcpTunnelConnector::new("tcp://10.144.144.2:11010".parse().unwrap());
|
||||||
|
insts[0]
|
||||||
|
.get_peer_manager()
|
||||||
|
.try_direct_connect(tcp_connector)
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
|
let udp_connector = UdpTunnelConnector::new("udp://10.144.144.3:11010".parse().unwrap());
|
||||||
|
insts[0]
|
||||||
|
.get_peer_manager()
|
||||||
|
.try_direct_connect(udp_connector)
|
||||||
|
.await
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
|
drop_insts(insts).await;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user