Skip to content

Instantly share code, notes, and snippets.

@OneOfOne
Last active May 2, 2021 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OneOfOne/6cee427b6901ee301ab490fcadceaa95 to your computer and use it in GitHub Desktop.
Save OneOfOne/6cee427b6901ee301ab490fcadceaa95 to your computer and use it in GitHub Desktop.
a script to run a vpn inside a network namespace with a shell
#!/bin/sh
set -uf
# set -x
# inspired by https://gist.github.com/dpino/6c0dca1742093346461e11aa8f608a99
NS="${NS-vpnns}"
if grep -q "$NS /sys" /proc/self/mounts; then
echo "already running inside the namespace"
exit 1
fi
if [ $USER != 'root' ]; then
sudo env REALUSER=$USER $0 "$@"
exit 0
fi
IFACE="$(ip route | grep default | awk '{ print $5 }')"
VETH="${VETH-veth1}"
VPEER="${VPEER-vpeer1}"
VETH_ADDR="10.200.${ADDR_IDX-1}.1"
VPEER_ADDR="10.200.${ADDR_IDX-1}.2"
VPNUPCMD="${VPNUPCMD-surfshark-vpn}"
VPNDOWNCMD="${VPNDOWNCMD-surfshark-vpn down}"
nsexec() {
ip netns exec $NS $*
}
cleanup() {
echo running cleanup
nsexec $VPNDOWNCMD &>/dev/null
ip li delete ${VETH} &>/dev/null
ip netns del $NS &>/dev/null
iptables -t nat -D POSTROUTING -s ${VETH_ADDR}/24 -o ${IFACE} -j MASQUERADE &>/dev/null
iptables -D FORWARD -i ${IFACE} -o ${VETH} -j ACCEPT &>/dev/null
iptables -D FORWARD -o ${IFACE} -i ${VETH} -j ACCEPT &>/dev/null
}
setup() {
ip netns add $NS
mkdir -p /etc/netns/$NS &>/dev/null
echo 'nameserver 1.1.1.1' >> /etc/netns/$NS/resolv.conf
ip link add ${VETH} type veth peer name ${VPEER}
ip link set ${VPEER} netns $NS
ip addr add ${VETH_ADDR}/24 dev ${VETH}
ip link set ${VETH} up
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s ${VETH_ADDR}/24 -o ${IFACE} -j MASQUERADE
iptables -A FORWARD -i ${IFACE} -o ${VETH} -j ACCEPT
iptables -A FORWARD -o ${IFACE} -i ${VETH} -j ACCEPT
nsexec bash <<WUT
ip addr add ${VPEER_ADDR}/24 dev ${VPEER}
ip link set ${VPEER} up
ip link set lo up
ip route add default via ${VETH_ADDR}
WUT
nsexec $VPNUPCMD
}
if ! ip netns list | grep -q $NS; then
echo running setup
setup || cleanup
fi
case "${1-none}" in
down)
cleanup;;
none)
nsexec sudo -u $REALUSER -i;;
*)
nsexec sudo -u $REALUSER "$@";;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment