Skip to content

Instantly share code, notes, and snippets.

@vphantom
Last active April 5, 2021 01:39
Show Gist options
  • Save vphantom/1e583650398a8eb66c4c8d6023fa23f3 to your computer and use it in GitHub Desktop.
Save vphantom/1e583650398a8eb66c4c8d6023fa23f3 to your computer and use it in GitHub Desktop.
OpenVPN inside a kernel namespace
#!/bin/bash
#
# Example wrapper script to run an application jailed inside the VPN.
# "myvpn" is the name of my namespace.
#
sudo -E ip netns exec myvpn sudo -E -u lis -- ~/bin/firefox.bin/firefox &
#!/bin/bash
exec 2>&1
PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
export PATH
#date
#set
# Inspired from http://www.naju.se/articles/openvpn-netns.html
# ...but it didn't work out of the box (interfaces set up but no I/O went through)
#
# He forgot to set $5 as the point-to-point remote end.
#
# DHCP DNS portion from https://github.com/masterkorp/openvpn-update-resolv-conf/blob/master/update-resolv-conf.sh
#
# The new netns will be called by the basename of your OpenVPN configuration file.
# (Watch out: renaming such a file on Debian requires running "systemctl daemon-reload"!)
NS=$(basename -s .conf $config)
NETNSDIR="/etc/netns/$NS"
RESOLVCONF="$NETNSDIR/resolv.conf"
case $script_type in
up)
echo "** UP: creating namespace '$NS'"
ip netns add $NS
ip netns exec $NS ip link set dev lo up
echo " ...making sure directory '$NETNSDIR' exists"
mkdir -p $NETNSDIR
echo -n >${RESOLVCONF}
for optionname in ${!foreign_option_*}; do
if [ "${!optionname:0:15}" = "dhcp-option DNS" ]; then
echo "nameserver ${!optionname#dhcp-option DNS }" >>${RESOLVCONF}
fi
done
# If it wasn't a leak risk, I'd add just in case:
# echo -e "nameserver 8.8.8.8\n8.8.4.4" >>${RESOLVCONF}
echo " ...set device '$1' to netns '$NS' and MTU '$2'"
ip link set dev "$1" up netns $NS mtu "$2"
echo " ...set IP '$4/${ifconfig_netmask:-30}' ${ifconfig_remote:+peer '$ifconfig_remote'} ${ifconfig_broadcast:+broadcast '$ifconfig_broadcast'}"
ip netns exec $NS ip addr add dev "$1" "$4/${ifconfig_netmask:-30}" ${ifconfig_remote:+peer "$ifconfig_remote"} ${ifconfig_broadcast:+broadcast "$ifconfig_broadcast"}
test -n "$ifconfig_ipv6_local" && ip netns exec $NS ip addr add dev "$1" "$ifconfig_ipv6_local"/112
;;
route-up)
echo "** ROUTE UP: adding default gateway '$route_vpn_gateway' to netns '$NS'"
ip netns exec $NS ip route add default via "$route_vpn_gateway"
test -n "$ifconfig_ipv6_remote" && ip netns exec $NS ip route add default via "$ifconfig_ipv6_remote"
;;
down)
echo "** DOWN: removing default route in netns '$NS'"
#ip netns delete $NS
ip netns exec $NS ip route del default
;;
*)
echo "** Ignoring unknown script_type '$script_type'"
;;
esac
exit 0
# Bits specific to this configuration
ifconfig-noexec
route-noexec
up /etc/openvpn/openvpn-namespace.sh
route-up /etc/openvpn/openvpn-namespace.sh
down /etc/openvpn/openvpn-namespace.sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment