diff --git a/Cargo.lock b/Cargo.lock index 58886be..07f26c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,7 +128,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chaos-tproxy" -version = "0.5.1" +version = "0.5.2" dependencies = [ "anyhow", "arp-toolkit", @@ -177,7 +177,7 @@ dependencies = [ [[package]] name = "chaos-tproxy-controller" -version = "0.5.1" +version = "0.5.2" dependencies = [ "anyhow", "arp-toolkit", @@ -226,7 +226,7 @@ dependencies = [ [[package]] name = "chaos-tproxy-proxy" -version = "0.5.1" +version = "0.5.2" dependencies = [ "anyhow", "arp-toolkit", diff --git a/Cargo.toml b/Cargo.toml index c536d8b..929a912 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ authors = ["Andrewmatilde ", "Hexilee "] edition = "2018" name = "chaos-tproxy" -version = "0.5.1" +version = "0.5.2" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/chaos-tproxy-controller/Cargo.toml b/chaos-tproxy-controller/Cargo.toml index 6ebbfba..9cbe868 100644 --- a/chaos-tproxy-controller/Cargo.toml +++ b/chaos-tproxy-controller/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chaos-tproxy-controller" -version = "0.5.1" +version = "0.5.2" edition = "2018" [[bin]] diff --git a/chaos-tproxy-controller/src/cmd/interactive/handler.rs b/chaos-tproxy-controller/src/cmd/interactive/handler.rs index 202ede2..f8891f7 100644 --- a/chaos-tproxy-controller/src/cmd/interactive/handler.rs +++ b/chaos-tproxy-controller/src/cmd/interactive/handler.rs @@ -1,5 +1,6 @@ use std::convert::TryInto; use std::future::Future; +use std::ops::DerefMut; use std::pin::Pin; use std::sync::Arc; use std::task::{Context, Poll}; @@ -131,6 +132,6 @@ impl Service> for ConfigService { #[inline] fn call(&mut self, request: Request) -> Self::Future { let handler = self.0.clone(); - Box::pin(async move { Self::handle(&mut *handler.lock().await, request).await }) + Box::pin(async move { Self::handle(handler.lock().await.deref_mut(), request).await }) } } diff --git a/chaos-tproxy-controller/src/proxy/net/bridge.rs b/chaos-tproxy-controller/src/proxy/net/bridge.rs index 85f524f..f25f55b 100644 --- a/chaos-tproxy-controller/src/proxy/net/bridge.rs +++ b/chaos-tproxy-controller/src/proxy/net/bridge.rs @@ -10,6 +10,7 @@ use rtnetlink::packet::RouteMessage; use rtnetlink::Handle; use uuid::Uuid; +use crate::proxy::net::iptables::clear_ebtables; use crate::proxy::net::routes::{del_routes_noblock, get_routes_noblock, load_routes}; #[derive(Debug, Clone)] @@ -126,6 +127,7 @@ impl NetEnv { let cmdvv = vec![ ip_address("add", &self.ip, &self.veth4), + arp_set(&gateway_ip_s, &gateway_mac_s, &self.veth1), arp_set(&gateway_ip_s, &gateway_mac_s, &self.veth4), ip_netns( &self.netns, @@ -235,6 +237,7 @@ impl NetEnv { ip_link_del_bridge(&self.bridge1), ip_address("add", &self.ip, &self.device), bash_c(restore_dns), + clear_ebtables(), ]; execute_all_with_log_error(cmdvv)?; @@ -260,6 +263,10 @@ impl NetEnv { ip_addr: gateway_ip, } = try_get_default_gateway()?; + if gateway_mac.octets().iter().all(|&i| i == 0) { + return Ok(()); + } + let gateway_ip = gateway_ip.to_string(); let gateway_mac = gateway_mac.to_string(); diff --git a/chaos-tproxy-controller/src/proxy/net/iptables.rs b/chaos-tproxy-controller/src/proxy/net/iptables.rs index 8d9a725..e47f62f 100644 --- a/chaos-tproxy-controller/src/proxy/net/iptables.rs +++ b/chaos-tproxy-controller/src/proxy/net/iptables.rs @@ -4,6 +4,7 @@ pub fn set_iptables<'a>( net_env: &'a NetEnv, proxy_ports: Option<&'a str>, listen_port: &'a str, + device_mac: &'a str, ) -> Vec> { let cmdv = match proxy_ports { Some(proxy_ports) => ip_netns( @@ -112,10 +113,25 @@ pub fn set_iptables<'a>( "DROP", ], ), + vec![ + "ebtables", + "-t", + "nat", + "-A", + "PREROUTING", + "-i", + &net_env.device, + "-j", + "dnat", + "--to-dst", + device_mac, + "--dnat-target", + "ACCEPT", + ], ] } -pub fn set_iptables_safe(net_env: &NetEnv) -> Vec> { +pub fn set_iptables_safe<'a>(net_env: &'a NetEnv, device_mac: &'a str) -> Vec> { vec![ ip_netns( &net_env.netns, @@ -189,5 +205,24 @@ pub fn set_iptables_safe(net_env: &NetEnv) -> Vec> { "ACCEPT", ], ), + vec![ + "ebtables", + "-t", + "nat", + "-A", + "PREROUTING", + "-i", + &net_env.device, + "-j", + "dnat", + "--to-dst", + device_mac, + "--dnat-target", + "ACCEPT", + ], ] } + +pub fn clear_ebtables() -> Vec<&'static str> { + vec!["ebtables", "-t", "nat", "-F"] +} diff --git a/chaos-tproxy-controller/src/proxy/net/set_net.rs b/chaos-tproxy-controller/src/proxy/net/set_net.rs index 2063e28..171cf52 100644 --- a/chaos-tproxy-controller/src/proxy/net/set_net.rs +++ b/chaos-tproxy-controller/src/proxy/net/set_net.rs @@ -5,7 +5,7 @@ use libarp::interfaces::Interface; use rtnetlink::Handle; use crate::proxy::net::arp::gratuitous_arp; -use crate::proxy::net::bridge::{bash_c, execute, execute_all, NetEnv}; +use crate::proxy::net::bridge::{bash_c, execute, execute_all, get_interface, NetEnv}; use crate::proxy::net::iptables::{set_iptables, set_iptables_safe}; use crate::proxy::net::ping::try_ping; @@ -20,6 +20,8 @@ pub async fn set_net( net_env.setenv_bridge(handle).await?; let port = listen_port.to_string(); let restore_dns = "cp /etc/resolv.conf.bak /etc/resolv.conf"; + let device_interface = get_interface(net_env.veth4.clone()).unwrap(); + let device_mac = device_interface.mac.unwrap().to_string(); let arp_interface = Interface::new_by_name(net_env.veth4.clone().as_str()).unwrap(); gratuitous_arp( @@ -29,13 +31,13 @@ pub async fn set_net( ); if let Some(ref proxy_ports) = proxy_ports { - execute_all(set_iptables(net_env, Some(proxy_ports), &port))?; + execute_all(set_iptables(net_env, Some(proxy_ports), &port, &device_mac))?; } else { - execute_all(set_iptables(net_env, None, &port))?; + execute_all(set_iptables(net_env, None, &port, &device_mac))?; } if safe { - execute_all(set_iptables_safe(net_env))?; + execute_all(set_iptables_safe(net_env, &device_mac))?; } let _ = execute(bash_c(restore_dns)); diff --git a/chaos-tproxy-proxy/Cargo.toml b/chaos-tproxy-proxy/Cargo.toml index d613b1a..f785d6e 100644 --- a/chaos-tproxy-proxy/Cargo.toml +++ b/chaos-tproxy-proxy/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "chaos-tproxy-proxy" -version = "0.5.1" +version = "0.5.2" edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html