Skip to content

Instantly share code, notes, and snippets.

@PinkD
Last active January 20, 2025 17:35
Show Gist options
  • Save PinkD/44ddd6198c6c3f02733d15ae4c500731 to your computer and use it in GitHub Desktop.
Save PinkD/44ddd6198c6c3f02733d15ae4c500731 to your computer and use it in GitHub Desktop.
setup a netns and connect to host network with veth
#!/bin/bash
netns=proxy
veth=veth-proxy
host_addr="172.16.233.1/24"
ns_addr="172.16.233.2/24"
verbose=""
user=$(whoami)
help() {
cat <<EOF
setup a netns and connect to host network with veth.
you can add \`ip rule\` to proxy all the traffic in this netns.
usage:
$0 [option] command
options:
-h, --help show help
-n, --netns netns name
-i, --veth-interface veth interface name on host network
-u, --user username(default is current user)
--host-addr host interface address
--ns-addr netns interface address
commands:
setup, init setup netns
destroy destroy netns
enter, exec, run enter netns, will call setup if not setup
EOF
}
set -e
_netns_prompt() {
local _netns=$(ip netns identify)
if [[ -n "$_netns" ]]; then
echo -n "(netns/$_netns) "
fi
}
OPTS=$(getopt -n "$0" -o "hvn:i:u:-" -l "help,verbose,netns:,veth-interface:,user:,host-addr:,ns-addr:" -- "$@")
eval set -- "$OPTS"
while true; do
case $1 in
-n | --netns)
netns=$2
shift 2
;;
-i | --veth-interface)
veth=$2
shift 2
;;
-u | --user)
user=$2
shift 2
;;
--host-addr)
host_addr=$2
shift 2
;;
--ns-addr)
ns_addr=$2
shift 2
;;
-v | --verbose)
verbose="true"
shift
;;
-h | --help)
help
exit
;;
--)
# end of options
shift
break
;;
esac
done
_a=(${host_addr//// })
default_route=${_a[0]}
debug_msg() {
echo "netns: $netns"
echo "veth: $veth"
echo "whoami: $(whoami)"
echo "user: $user"
echo "host_addr: $host_addr"
echo "ns_addr: $ns_addr"
echo "default_route: $default_route"
echo "extra args: $@"
}
if [[ "$UID" -ne 0 ]]
then
extra_args="$@"
if [[ ! -z "$verbose" ]]
then
extra_args="-v $extra_args"
fi
# args sudo "$0" -u "$user" -i "$veth" -n "$netns" --host-addr "$host_addr" --ns-addr "$ns_addr" $extra_args
# don't quote `extra_args` because we need to expand it before passing to `exec`
exec sudo "$0" -u "$user" -i "$veth" -n "$netns" --host-addr "$host_addr" --ns-addr "$ns_addr" $extra_args
fi
if [[ ! -z "$verbose" ]]
then
debug_msg
fi
ip() {
echo "[#] ip" "$@"
command ip "$@"
}
ipns() {
ip -n "$netns" "$@"
}
ipnsexec() {
ip netns exec "$netns" "$@"
}
setup() {
[ -f "/run/netns/$netns" ] && exit
ip netns add "$netns"
ip link add "$veth" type veth peer name eth0 netns "$netns"
ip link set "$veth" up
ipns link set eth0 up
ip addr add "$host_addr" dev "$veth"
ipns addr add "$ns_addr" dev eth0
ipns route add default via "$default_route"
}
destroy() {
[ -f "/run/netns/$netns" ] && ip netns del "$netns"
}
enter() {
[ ! -f "/run/netns/$netns" ] && setup
# TODO: add venv note to PS1
# PS1='$(_netns_prompt)\[\e[0;31m\]\u\[\e[m\]@\h:\[\e[1;34m\]\w\[\e[m\] \[\e[0;31m\]\$ \[\e[m\]'
ipnsexec sudo -Es -u "$user"
}
case $1 in
setup | init)
setup
;;
destroy)
destroy
;;
enter | exec | run)
enter
;;
*)
help
exit
;;
esac
@PinkD
Copy link
Author

PinkD commented Jul 8, 2023

setup route, then all your traffic in this netns is under proxy:

# add proxy route table
ip route add default via PROXY_GATEWAY table TABLE_ID
# add proxy rule
ip rule add iif veth-proxy lookup TABLE_ID
# add iptables
iptables -t nat -A POSTROUTING -s NETNS_NETWORK -j MASQUERADE

@PinkD
Copy link
Author

PinkD commented Jan 20, 2025

updated 2025-01-21:

  • add -v/--verbose to output debug msg
  • fix long opt parsing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment