add support for unprivileged namespaces

This commit is contained in:
Remy D. Farley 2024-04-03 14:26:46 +00:00 committed by B. Blechschmidt
parent 5e99c9f874
commit d351b5031c
11 changed files with 615 additions and 48 deletions

View file

@ -131,11 +131,69 @@ pub async fn desktop_run_async(args: Args, shutdown_token: tokio_util::sync::Can
restore = Some(tproxy_config::tproxy_setup(&tproxy_args)?);
}
#[cfg(target_os = "linux")]
{
let run_ip_util = |args: String| {
tokio::process::Command::new("ip")
.args(args.split(' '))
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.spawn()
.ok();
};
if setup && !args.ipv6_enabled {
// Remove ipv6 connectivity if not explicitly required
// TODO: remove this when upstream will get updated
run_ip_util(format!("-6 route delete ::/1 dev {}", tproxy_args.tun_name));
run_ip_util(format!("-6 route delete 80::/1 dev {}", tproxy_args.tun_name));
}
if setup && args.unshare {
// New namespace doesn't have any other routing device by default
// So our `tun` device should act as such to make space for other proxies.
run_ip_util(format!("route delete 0.0.0.0/1 dev {}", tproxy_args.tun_name));
run_ip_util(format!("route delete 128.0.0.0/1 dev {}", tproxy_args.tun_name));
run_ip_util(format!("route add 0.0.0.0/0 dev {}", tproxy_args.tun_name));
if args.ipv6_enabled {
run_ip_util(format!("-6 route delete ::/1 dev {}", tproxy_args.tun_name));
run_ip_util(format!("-6 route delete 80::/1 dev {}", tproxy_args.tun_name));
run_ip_util(format!("-6 route add ::/0 dev {}", tproxy_args.tun_name));
}
}
}
let mut admin_command_args = args.admin_command.iter();
if let Some(command) = admin_command_args.next() {
let child = tokio::process::Command::new(command)
.args(admin_command_args)
.kill_on_drop(true)
.spawn();
match child {
Err(err) => {
log::warn!("Failed to start admin process: {err}");
}
Ok(mut child) => {
tokio::spawn(async move {
if let Err(err) = child.wait().await {
log::warn!("Admin process terminated: {err}");
}
});
}
};
}
let join_handle = tokio::spawn(crate::run(device, MTU, args, shutdown_token));
join_handle.await.map_err(std::io::Error::from)??;
#[cfg(any(target_os = "linux", target_os = "windows", target_os = "macos"))]
if setup {
// TODO: This probably should be handled by a destructor
// since otherwise removal is not guaranteed if anything above returns early.
tproxy_config::tproxy_remove(restore)?;
}