try create tun device if not exist (#1131)
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:
Sijie.Sun
2025-07-19 22:56:19 +08:00
committed by GitHub
parent 50c6f5ae6c
commit 2660ed5fda
2 changed files with 133 additions and 12 deletions

View File

@@ -89,7 +89,7 @@ tun = { package = "tun-easytier", git="https://github.com/EasyTier/rust-tun", fe
"async",
], optional = true }
# for net ns
nix = { version = "0.29.0", features = ["sched", "socket", "ioctl", "net"] }
nix = { version = "0.29.0", features = ["sched", "socket", "ioctl", "net", "fs"] }
uuid = { version = "1.5.0", features = [
"v4",

View File

@@ -255,7 +255,10 @@ impl Drop for VirtualNic {
if let Some(ref ifname) = self.ifname {
// Try to clean up firewall rules, but don't panic in destructor
if let Err(e) = crate::arch::windows::remove_interface_firewall_rules(ifname) {
eprintln!("Warning: Failed to remove firewall rules for interface {}: {}", ifname, e);
eprintln!(
"Warning: Failed to remove firewall rules for interface {}: {}",
ifname, e
);
}
}
}
@@ -271,12 +274,113 @@ impl VirtualNic {
}
}
/// Check and create TUN device node if necessary on Linux systems
#[cfg(target_os = "linux")]
async fn ensure_tun_device_node() {
const TUN_DEV_PATH: &str = "/dev/net/tun";
const TUN_DIR_PATH: &str = "/dev/net";
// Check if /dev/net/tun already exists
if tokio::fs::metadata(TUN_DEV_PATH).await.is_ok() {
tracing::debug!("TUN device node {} already exists", TUN_DEV_PATH);
return;
}
tracing::info!(
"TUN device node {} not found, attempting to create",
TUN_DEV_PATH
);
// Check if TUN kernel module is available
let tun_module_available = tokio::fs::metadata("/proc/net/dev").await.is_ok()
&& (tokio::fs::read_to_string("/proc/modules").await)
.map(|content| content.contains("tun"))
.unwrap_or(false);
if !tun_module_available {
tracing::warn!("TUN kernel module may not be loaded");
println!("⚠ Warning: TUN kernel module may not be available.");
println!(" You may need to load it with: sudo modprobe tun");
}
// Try to create /dev/net directory if it doesn't exist
if tokio::fs::metadata(TUN_DIR_PATH).await.is_err() {
if let Err(e) = tokio::fs::create_dir_all(TUN_DIR_PATH).await {
tracing::warn!(
"Failed to create directory {}: {}. Continuing anyway.",
TUN_DIR_PATH,
e
);
println!(
"⚠ Warning: Failed to create directory {}. TUN device creation may fail.",
TUN_DIR_PATH
);
println!(
" You may need to run with root privileges or manually create the TUN device."
);
Self::print_troubleshooting_info();
return;
}
tracing::info!("Created directory {}", TUN_DIR_PATH);
}
// Try to create the TUN device node
// Major number 10, minor number 200 for /dev/net/tun
let dev_node = nix::sys::stat::makedev(10, 200);
match nix::sys::stat::mknod(
TUN_DEV_PATH,
nix::sys::stat::SFlag::S_IFCHR,
nix::sys::stat::Mode::from_bits(0o600).unwrap(),
dev_node,
) {
Ok(_) => {
tracing::info!("Successfully created TUN device node {}", TUN_DEV_PATH);
println!("✓ Created TUN device node {}", TUN_DEV_PATH);
}
Err(e) => {
tracing::warn!(
"Failed to create TUN device node {}: {}. Continuing anyway.",
TUN_DEV_PATH,
e
);
println!(
"⚠ Warning: Failed to create TUN device node {}.",
TUN_DEV_PATH
);
println!(" Error: {}", e);
Self::print_troubleshooting_info();
}
}
}
/// Print troubleshooting information for TUN device issues
#[cfg(target_os = "linux")]
fn print_troubleshooting_info() {
println!(" Possible solutions:");
println!(" 1. Run with root privileges: sudo ./easytier-core [options]");
println!(" 2. Manually create TUN device: sudo mkdir -p /dev/net && sudo mknod /dev/net/tun c 10 200");
println!(" 3. Load TUN kernel module: sudo modprobe tun");
println!(" 4. Use --no-tun flag if TUN functionality is not needed");
println!(" 5. Check if your system/container supports TUN devices");
println!(" Note: TUN functionality may still work if the kernel supports dynamic device creation.");
}
/// For non-Linux systems, this is a no-op
#[cfg(not(target_os = "linux"))]
async fn ensure_tun_device_node() -> Result<(), Error> {
Ok(())
}
async fn create_tun(&mut self) -> Result<tun::platform::Device, Error> {
let mut config = Configuration::default();
config.layer(Layer::L3);
#[cfg(target_os = "linux")]
{
// Check and create TUN device node if necessary (Linux only)
Self::ensure_tun_device_node().await;
let dev_name = self.global_ctx.get_flags().dev_name;
if !dev_name.is_empty() {
config.tun_name(format!("{}", dev_name));
@@ -434,15 +538,28 @@ impl VirtualNic {
// Add firewall rules for virtual NIC interface to allow all traffic
match crate::arch::windows::add_interface_to_firewall_allowlist(&ifname) {
Ok(_) => {
tracing::info!("Successfully configured Windows Firewall for interface: {}", ifname);
tracing::info!("All protocols (TCP/UDP/ICMP) are now allowed on interface: {}", ifname);
},
tracing::info!(
"Successfully configured Windows Firewall for interface: {}",
ifname
);
tracing::info!(
"All protocols (TCP/UDP/ICMP) are now allowed on interface: {}",
ifname
);
}
Err(e) => {
tracing::warn!("Failed to configure Windows Firewall for {}: {}", ifname, e);
println!("⚠ Warning: Failed to configure Windows Firewall for interface {}.", ifname);
println!(
"⚠ Warning: Failed to configure Windows Firewall for interface {}.",
ifname
);
println!(" This may cause connectivity issues with ping and other network functions.");
println!(" Please run as Administrator or manually configure Windows Firewall.");
println!(" Alternatively, you can disable Windows Firewall for testing purposes.");
println!(
" Please run as Administrator or manually configure Windows Firewall."
);
println!(
" Alternatively, you can disable Windows Firewall for testing purposes."
);
}
}
}
@@ -615,7 +732,7 @@ impl NicCtx {
if payload.is_empty() {
return;
}
match payload[0] >> 4 {
4 => Self::do_forward_nic_to_peers_ipv4(ret, mgr).await,
6 => Self::do_forward_nic_to_peers_ipv6(ret, mgr).await,
@@ -754,7 +871,11 @@ impl NicCtx {
Ok(())
}
pub async fn run(&mut self, ipv4_addr: Option<cidr::Ipv4Inet>, ipv6_addr: Option<cidr::Ipv6Inet>) -> Result<(), Error> {
pub async fn run(
&mut self,
ipv4_addr: Option<cidr::Ipv4Inet>,
ipv6_addr: Option<cidr::Ipv6Inet>,
) -> Result<(), Error> {
let tunnel = {
let mut nic = self.nic.lock().await;
match nic.create_dev().await {
@@ -795,12 +916,12 @@ impl NicCtx {
if let Some(ipv4_addr) = ipv4_addr {
self.assign_ipv4_to_tun_device(ipv4_addr).await?;
}
// Assign IPv6 address if provided
if let Some(ipv6_addr) = ipv6_addr {
self.assign_ipv6_to_tun_device(ipv6_addr).await?;
}
self.run_proxy_cidrs_route_updater().await?;
Ok(())