mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-07 02:09:06 +00:00
try create tun device if not exist (#1131)
This commit is contained in:
+1
-1
@@ -89,7 +89,7 @@ tun = { package = "tun-easytier", git="https://github.com/EasyTier/rust-tun", fe
|
|||||||
"async",
|
"async",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
# for net ns
|
# 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 = [
|
uuid = { version = "1.5.0", features = [
|
||||||
"v4",
|
"v4",
|
||||||
|
|||||||
@@ -255,7 +255,10 @@ impl Drop for VirtualNic {
|
|||||||
if let Some(ref ifname) = self.ifname {
|
if let Some(ref ifname) = self.ifname {
|
||||||
// Try to clean up firewall rules, but don't panic in destructor
|
// Try to clean up firewall rules, but don't panic in destructor
|
||||||
if let Err(e) = crate::arch::windows::remove_interface_firewall_rules(ifname) {
|
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> {
|
async fn create_tun(&mut self) -> Result<tun::platform::Device, Error> {
|
||||||
let mut config = Configuration::default();
|
let mut config = Configuration::default();
|
||||||
config.layer(Layer::L3);
|
config.layer(Layer::L3);
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[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;
|
let dev_name = self.global_ctx.get_flags().dev_name;
|
||||||
if !dev_name.is_empty() {
|
if !dev_name.is_empty() {
|
||||||
config.tun_name(format!("{}", dev_name));
|
config.tun_name(format!("{}", dev_name));
|
||||||
@@ -434,15 +538,28 @@ impl VirtualNic {
|
|||||||
// Add firewall rules for virtual NIC interface to allow all traffic
|
// Add firewall rules for virtual NIC interface to allow all traffic
|
||||||
match crate::arch::windows::add_interface_to_firewall_allowlist(&ifname) {
|
match crate::arch::windows::add_interface_to_firewall_allowlist(&ifname) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
tracing::info!("Successfully configured Windows Firewall for interface: {}", ifname);
|
tracing::info!(
|
||||||
tracing::info!("All protocols (TCP/UDP/ICMP) are now allowed on interface: {}", ifname);
|
"Successfully configured Windows Firewall for interface: {}",
|
||||||
},
|
ifname
|
||||||
|
);
|
||||||
|
tracing::info!(
|
||||||
|
"All protocols (TCP/UDP/ICMP) are now allowed on interface: {}",
|
||||||
|
ifname
|
||||||
|
);
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::warn!("Failed to configure Windows Firewall for {}: {}", ifname, 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!(" This may cause connectivity issues with ping and other network functions.");
|
||||||
println!(" Please run as Administrator or manually configure Windows Firewall.");
|
println!(
|
||||||
println!(" Alternatively, you can disable Windows Firewall for testing purposes.");
|
" Please run as Administrator or manually configure Windows Firewall."
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
" Alternatively, you can disable Windows Firewall for testing purposes."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -754,7 +871,11 @@ impl NicCtx {
|
|||||||
Ok(())
|
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 tunnel = {
|
||||||
let mut nic = self.nic.lock().await;
|
let mut nic = self.nic.lock().await;
|
||||||
match nic.create_dev().await {
|
match nic.create_dev().await {
|
||||||
|
|||||||
Reference in New Issue
Block a user