测试通过

main
阳光少年 1 year ago
parent a7188b94ff
commit d388e4e18b

@ -24,8 +24,6 @@ install:
cp images/* $(WORKSPACE)/images/ cp images/* $(WORKSPACE)/images/
chown -R rocker:rocker $(WORKSPACE) chown -R rocker:rocker $(WORKSPACE)
-sysctl net.ipv4.conf.all.forwarding=1
-iptables -t filter -P FORWARD ACCEPT
clean: clean:
-rocker --rm all -rocker --rm all
-rm -rf $(WORKSPACE)/* -rm -rf $(WORKSPACE)/*

@ -194,8 +194,8 @@ fn init_container_env(env: Option<&String>) -> Result<()>{
std::env::remove_var(k); std::env::remove_var(k);
} }
if let Some(env) = env { let env_vec = if let Some(env) = env {
let env_vec = if env.starts_with("./") || env.starts_with("/") { let mut env_vec = if env.starts_with("./") || env.starts_with("/") {
// 读取出路径指定的文件作为env // 读取出路径指定的文件作为env
let env_path = Path::new(env); let env_path = Path::new(env);
let mut env_file = fs::File::open(env_path)?; let mut env_file = fs::File::open(env_path)?;
@ -208,14 +208,17 @@ fn init_container_env(env: Option<&String>) -> Result<()>{
} else { } else {
env.split(",").map(String::from).collect::<Vec<String>>() env.split(",").map(String::from).collect::<Vec<String>>()
}; };
env_vec.push(r#"PS1=\u\h\W\$ "#.to_string());
for item_env in env_vec.iter() { env_vec
let item_env_v = item_env.split("=").collect::<Vec<&str>>(); } else {
if item_env_v.len() == 2 { vec![r#"PS1=\u\h\W\$ "#.to_string()]
std::env::set_var(item_env_v[0], item_env_v[1]) };
} else { for item_env in env_vec.iter() {
println!("env 格式不正确: {item_env}") let item_env_v = item_env.split("=").collect::<Vec<&str>>();
} if item_env_v.len() == 2 {
std::env::set_var(item_env_v[0], item_env_v[1])
} else {
println!("env 格式不正确: {item_env}")
} }
} }
Ok(()) Ok(())

@ -44,6 +44,56 @@ fn set_slave_ip(slave_veth_name: &str, addr: &str, pid: &str) {
} }
} }
fn set_snat(gateway_addr: &str, bridge_name: &str) {
// sudo iptables -t nat -A POSTROUTING -s 172.18.0.0/24 ! -o br0 -j MASQUERADE
let args = ["-t", "nat", "-A", "POSTROUTING", "-s", &format!("{gateway_addr}/24"), "!", "-o", bridge_name, "-j", "MASQUERADE"];
println!("set_snat: {args:?}");
let out = std::process::Command::new("iptables")
.args(args)
.output()
.unwrap();
if !out.status.success() {
panic!("{:?}", out);
}
}
fn set_iptables_forward() {
// sudo sysctl net.ipv4.conf.all.forwarding=1
let args = ["net.ipv4.conf.all.forwarding=1"];
println!("set_iptables_forward: {args:?}");
let out = std::process::Command::new("sysctl")
.args(args)
.output()
.unwrap();
if !out.status.success() {
panic!("{:?}", out);
}
// sudo iptables -t filter -P FORWARD ACCEPT
let args = ["-t", "filter", "-P", "FORWARD", "ACCEPT"];
println!("set_iptables_forward: {args:?}");
let out = std::process::Command::new("iptables")
.args(args)
.output()
.unwrap();
if !out.status.success() {
panic!("{:?}", out);
}
}
fn set_slave_route(slave_veth_name: &str, bridge_addr: &str, pid: &str) {
// sudo nsenter -t 1851 -n -- ip route add default via 172.18.0.1 dev veth3
let args = ["-t", pid, "-n", "--", "ip", "route", "add", "default", "via", bridge_addr, "dev", slave_veth_name];
println!("set_slave_route: {args:?}");
let out = std::process::Command::new("nsenter")
.args(args)
.output()
.unwrap();
if !out.status.success() {
panic!("{:?}", out);
}
}
fn set_net_up(bridge_name: &str, master_veth_name: &str, pid: &str, slave_veth_name: &str) { fn set_net_up(bridge_name: &str, master_veth_name: &str, pid: &str, slave_veth_name: &str) {
// sudo ip link set bridge_name up // sudo ip link set bridge_name up
let args = ["link", "set", bridge_name, "up"]; let args = ["link", "set", bridge_name, "up"];
@ -78,8 +128,16 @@ fn set_net_up(bridge_name: &str, master_veth_name: &str, pid: &str, slave_veth_n
println!("{:?}", out); println!("{:?}", out);
} }
// ip link set lo up
let args = ["-t", pid, "-n", "--", "ip", "link", "set", "lo", "up"];
println!("set_up: {args:?}");
let out = std::process::Command::new("nsenter")
.args(args)
.output()
.unwrap();
if !out.status.success() {
println!("{:?}", out);
}
} }
fn set_up(dev_name: &str) { fn set_up(dev_name: &str) {
@ -152,7 +210,7 @@ fn del_bridge(bridge_name: &str) {
fn create_veth_pair(master_veth_name: &str, slave_veth_name: &str) { fn create_veth_pair(master_veth_name: &str, slave_veth_name: &str) {
// sudo ip link add veth0 type veth peer name veth1 // sudo ip link add master_veth_name type veth peer name slave_veth_name
let args = ["link", "add", master_veth_name, "type", "veth", "peer", "name", slave_veth_name]; let args = ["link", "add", master_veth_name, "type", "veth", "peer", "name", slave_veth_name];
println!("create_veth_pair: {args:?}"); println!("create_veth_pair: {args:?}");
@ -172,9 +230,9 @@ struct NetWrok {
bridge_addr: String, // 192.168.124.1 bridge_addr: String, // 192.168.124.1
slave_addr: String, slave_addr: String,
bridge_name: String, // uuid[:8]_1 // ip 就是 192.168.124.1 bridge_name: String, // ro_uuid[:8]_1 // ip 就是 192.168.124.1
master_veth_name: String, // uuid[:8]_2 // 不分配ip 直接插到桥 master_veth_name: String, // ro_uuid[:8]_2 // 不分配ip 直接插到桥
slave_veth_name: String, // uuid[:8]_3 // ip 就是 192.168.124.3, 插在容器中 slave_veth_name: String, // ro_uuid[:8]_3 // ip 就是 192.168.124.3, 插在容器中
} }
fn get_all_network() -> Vec<NetWrok> { fn get_all_network() -> Vec<NetWrok> {
@ -226,15 +284,15 @@ fn create_network(uuid_name: &str, pid: i32) {
let network = loop { let network = loop {
// 生成一个随机桥ip // 生成一个随机桥ip
let base_addr = format!("{}.{}.{}", rg.gen_range(200..240), rg.gen_range(200..240), rg.gen_range(200..240)); let base_addr = format!("{}.{}.{}", rg.gen_range(150..190), rg.gen_range(150..190), rg.gen_range(150..190));
let gateway_addr = format!("{base_addr}.0"); let gateway_addr = format!("{base_addr}.0");
let bridge_addr = format!("{base_addr}.1"); let bridge_addr = format!("{base_addr}.1");
let slave_addr = format!("{base_addr}.3"); let slave_addr = format!("{base_addr}.3");
if all_network.iter().any(|n|n.bridge_addr == bridge_addr) == false { if all_network.iter().any(|n|n.bridge_addr == bridge_addr) == false {
let bridge_name = format!("{uuid_name}_1"); let bridge_name = format!("ro_{uuid_name}_1");
let master_veth_name = format!("{uuid_name}_2"); let master_veth_name = format!("ro_{uuid_name}_2");
let slave_veth_name = format!("{uuid_name}_3"); let slave_veth_name = format!("ro_{uuid_name}_3");
let net_work = NetWrok { let net_work = NetWrok {
gateway_addr, gateway_addr,
bridge_addr, bridge_addr,
@ -264,7 +322,30 @@ fn create_network(uuid_name: &str, pid: i32) {
set_slave_ip(&network.slave_veth_name, &network.slave_addr, pid.to_string().as_str()); set_slave_ip(&network.slave_veth_name, &network.slave_addr, pid.to_string().as_str());
// 激活 上线 // 激活 上线
set_net_up(&network.bridge_name, &network.master_veth_name, pid.to_string().as_str(), &&network.slave_veth_name); set_net_up(&network.bridge_name, &network.master_veth_name, pid.to_string().as_str(), &&network.slave_veth_name);
// 访问公网设置
// 配置路由 // 配置路由
set_slave_route(&network.slave_veth_name, &network.bridge_addr, pid.to_string().as_str());
// 设置转发规则
set_iptables_forward();
// 设置snat
set_snat(&network.gateway_addr, &network.bridge_name);
// // 创建veth pair
// create_veth_pair(&network.master_veth_name, &network.slave_veth_name);
// // 把从 pair 添加到容器内
// slave_join_bridge(&network.slave_veth_name, pid.to_string().as_str());
// // 系统中创建桥
// create_bridge_dev(&network.bridge_name);
// // 宿主机 主pair 连接桥
// master_join_bridge(&network.bridge_name, &network.master_veth_name);
// // 给桥分配ip
// set_bridge_ip(&network.bridge_name, &network.bridge_addr);
// // 给容器内 pair 分配ip
// set_slave_ip(&network.slave_veth_name, &network.slave_addr, pid.to_string().as_str());
// // 激活 上线
// set_net_up(&network.bridge_name, &network.master_veth_name, pid.to_string().as_str(), &&network.slave_veth_name);
// // 配置路由
@ -280,8 +361,8 @@ fn create_network(uuid_name: &str, pid: i32) {
fn main(){ fn main(){
// get_all_network(); // get_all_network();
let container_id = uuid::Uuid::new_v4().to_string()[0..3].to_string(); let container_id = uuid::Uuid::new_v4().to_string()[0..8].to_string();
create_network(&container_id, 28930); create_network(&container_id, 15992);
return; return;
let addr = "192.168.124.1"; let addr = "192.168.124.1";
@ -293,7 +374,8 @@ fn main(){
create_bridge_dev(&bridge_name); create_bridge_dev(&bridge_name);
set_bridge_ip(&bridge_name, &addr); set_bridge_ip(&bridge_name, &addr);
set_up(&bridge_name); set_up(&bridge_name);
// 我们在 set_bridge中补充了网段信息 /24 所以在 set_up的时候, 会自动配置路由表配置路由表 192.168.0.0/24 转发到这 bridge_name 的网络接口上 // 我们在 ip addr add 172.18.0.1/24 dev br0 的时候补全了网段信息 /24, 所以在 ip link set br0 up的时候,
// 会自动配置路由表配置路由表 192.168.0.0/24 转发到这 bridge_name 的网络接口上
// set_route(bridge_name, addr); // set_route(bridge_name, addr);
set_net(bridge_name, addr); set_net(bridge_name, addr);

Loading…
Cancel
Save