vopono
vopono copied to clipboard
Use unshare, setns, netlink etc. to create and configure netns
Unshare: https://stackoverflow.com/questions/10730838/how-to-create-multiple-network-namespace-from-a-single-process-instance https://man7.org/linux/man-pages/man1/unshare.1.html https://crates.io/crates/unshare (does this support modifying current process, i.e. without spawn) https://stackoverflow.com/questions/10730838/how-to-create-multiple-network-namespace-from-a-single-process-instance https://stackoverflow.com/questions/30142799/how-to-add-a-name-to-namespace
setns: https://man7.org/linux/man-pages/man2/setns.2.html
Also in nix: https://docs.rs/nix/0.19.0/nix/sched/fn.setns.html https://docs.rs/nix/0.19.0/nix/sched/fn.unshare.html
Rust example: https://github.com/johnae/netns-exec/blob/master/src/main.rs
Bind mount (to keep netns alive): https://man7.org/linux/man-pages/man2/mount.2.html https://crates.io/crates/sys-mount
Plan:
- Call unshare on parent thread (now root, or with necessary capabilities - at least CAP_NET_ADMIN + possibly CAP_SYS_ADMIN)
- Do we need to fork/clone to get a separate network namespace such that we can swap back and forth? (i.e. spawn thread, unshare, bind mount and kill thread)
- bind mount file descriptor (from pid) to named namespace - i.e. https://stackoverflow.com/questions/10730838/how-to-create-multiple-network-namespace-from-a-single-process-instance and https://stackoverflow.com/questions/30142799/how-to-add-a-name-to-namespace
- Can then swap to and from using setns with /proc/self/ns/net and /proc/1/ns/net
Might be easier with separate thread anyway, to manage executions inside and outside the namespace.
exec (can probably just use std::Process): https://linux.die.net/man/3/execvpe
netlink (for ip link): http://ifeanyi.co/posts/linux-namespaces-part-4/ https://crates.io/crates/rtnetlink (routing) https://crates.io/crates/netlink-sys (netlink sockets)
libnftnl (for nftables): https://crates.io/crates/nftnl
libiptc (for iptables): https://crates.io/crates/libiptc-sys
wgctrl (Wireguard i.e. wg conf): https://crates.io/crates/wgctrl-rs
sysctl: https://crates.io/crates/sysctl
nmcli (Network Manager): https://crates.io/crates/networkmanager https://docs.rs/networkmanager/0.3.2/networkmanager/devices/trait.Any.html#tymethod.set_managed
sudo: https://crates.io/crates/sudo - use instead of just checking uid - but how to verify capabilities?
Some C examples: https://github.com/Intika-Linux-Namespace
Potentially relevant as well (just found it while looking for some other implementations: https://github.com/vishvananda/netns)