#!/bin/sh # start openvpn tunnel in terminal inside Linux network namespace # # adapted from : # https://gist.github.com/nehaljwani/f6e9d12102157161bfceb7eea80c319f # # itself, is a fork of schnouki's script, see original blog post # https://schnouki.net/posts/2014/12/12/openvpn-for-a-single-application-on-linux/ # # original script can be found here # https://gist.github.com/Schnouki/fd171bcb2d8c556e8fdf # dont forget to enable IP forwarding : # sudo su # echo 1 > /proc/sys/net/ipv4/ip_forward # exit # ------------ adjust values below ------------ # network namespace NS_NAME=vpn # user for starting openvpn REGULAR_USER=newubu # network interface (put your own, use "ifconfig" or "ip link show" to get it) #NET_ITF=enp7s0 NET_ITF=enp33s0 #NET_ITF=wlx001d7e04f411 #NET_ITF=enp3s0 VPN_CREDENTIALS_PATH=/home/newubu/MyInstall/vpn/config # path to VPN config VPN_INSTALL_PATH=/etc/openvpn # path to openvpn install (set for Ubuntu 18.04/16.04) TEST_HOST_NAME=saltp7-l # test host name on the VPN TEST_HOST_IP=172.20.10.126 # test host IP on the VPN # --------------------------------------------- # execute network command in network namespace NS_EXEC="ip netns exec ${NS_NAME}" # non zero if iptables are defined IPTABLES_DEF=0 # set exit options set -u # exit on unbound variable set -e # exit on error #set -o pipefail # trace option #set -x if [ $USER != "root" ]; then echo "This must be run as root." exit 1 fi start_vpn() { echo "Add network interface" # Create the network namespace ip netns add ${NS_NAME} # Start the loopback interface in the namespace #${NS_EXEC} ip addr add 127.0.0.1/8 dev lo ${NS_EXEC} ip link set dev lo up #${NS_EXEC} ping -c 3 127.0.0.1 # Create virtual network interfaces that will let OpenVPN (in the # namespace) access the real network, and configure the interface in the # namespace (vpn1) to use the interface out of the namespace (vpn0) as its # default gateway ip link add vpn0 type veth peer name vpn1 ip link set vpn0 up ip link set vpn1 netns ${NS_NAME} up ${NS_EXEC} ip link set vpn1 up ip addr add 10.20.20.1/24 dev vpn0 ${NS_EXEC} ip addr add 10.20.20.2/24 dev vpn1 ${NS_EXEC} ip link set dev vpn1 mtu 2000 # 1492 ${NS_EXEC} ip route add default via 10.20.20.1 dev vpn1 ${NS_EXEC} ip link show ${NS_EXEC} ip route # Configure the nameserver to use inside the namespace # TODO use VPN-provided DNS servers in order to prevent leaks # here we use 8.8.8.8 as Internet DNS mkdir -p /etc/netns/${NS_NAME} cat >/etc/netns/${NS_NAME}/resolv.conf </dev/null 2>&1 ; do sleep .5 ; done echo "... tunnel interface is up" } stop_vpn() { echo "Stopping VPN" ip netns pids ${NS_NAME} | xargs -rd'\n' kill # TODO wait for terminate # clear NAT echo "iptables ${IPTABLES_DEF}" if [ ${IPTABLES_DEF} -gt 0 ]; then echo "Delete network iptables" iptables -t nat -D POSTROUTING -o ${NET_ITF} -m mark --mark 0x29a -j MASQUERADE iptables -t mangle -D PREROUTING -i vpn0 -j MARK --set-xmark 0x29a/0xffffffff IPTABLES_DEF=0 fi echo "Delete network interface" rm -rf /etc/netns/${NS_NAME} ip netns delete ${NS_NAME} ip link delete vpn0 echo "iptables ${IPTABLES_DEF}" } # stop VPN on exit (even when error occured) trap stop_vpn EXIT # start VPN start_vpn # start a the command line interface that will be executed on vpn ${NS_EXEC} ${VPN_INSTALL_PATH}/post-update-resolv-conf # test if IP access is ok echo "test IP access ..." ${NS_EXEC} ping -c 3 ${TEST_HOST_IP} # test if host names are resolved by DNS echo "test if host names are resolved by DNS ..." ${NS_EXEC} ping -c 3 ${TEST_HOST_NAME} echo "you are now on vpn is this terminal ... type CTRL-D or exit to leave" ${NS_EXEC} sudo -u $REGULAR_USER /bin/bash # clean end ... hopefully echo "bye"