Running an OpenVPN tunnel inside a network namespace

Updated .

Linux network namespaces can be used to control which processes should be tunneled by OpenVPN.

Example

First create an --up and --down script for OpenVPN. This script will create the VPN tunnel interface inside a network namespace called vpn, instead of the default namespace.

cat > netns-script << 'EOF'
#!/bin/sh
case $script_type in
        up)
                ip netns add vpn
                ip netns exec vpn ip link set dev lo up
                ip link set dev "$1" up netns vpn mtu "$2"
                ip netns exec vpn ip addr add dev "$1" \
                        "$4/${ifconfig_netmask:-30}" \
                        ${ifconfig_broadcast:+broadcast "$ifconfig_broadcast"}
                if [ -n "$ifconfig_ipv6_local" ]; then
                        ip netns exec vpn ip addr add dev "$1" \
                                "$ifconfig_ipv6_local"/112
                fi
                ;;
        route-up)
                ip netns exec vpn ip route add default via "$route_vpn_gateway"
                if [ -n "$ifconfig_ipv6_remote" ]; then
                        ip netns exec vpn ip route add default via \
                                "$ifconfig_ipv6_remote"
                fi
                ;;
        down)
                ip netns delete vpn
                ;;
esac
EOF

Then start OpenVPN and tell it to use our --up and --down script instead of executing ifconfig and route.

openvpn --ifconfig-noexec --route-noexec --up netns-script --route-up netns-script --down netns-script

Now you can start programs to be tunneled like this:

ip netns exec vpn command