Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Isolated OpenVPN routing table on Linux

Save the route script to /usr/local/lib/openvpn/route on the client. Make it executable with chmod +x.

Remove the push redirect-gateway option from the OpenVPN server config.

Add these options to the OpenVPN client config:

setenv OPENVPN_ROUTE_TABLE 94
route-noexec
route-up /usr/local/lib/openvpn/route
route 0.0.0.0 128.0.0.0
route 128.0.0.0 128.0.0.0

Run these commands as root on the client before starting OpenVPN, replacing VPN_SERVER_IP_ADDRESS as appropriate:

ip rule add table 94
ip rule add to VPN_SERVER_IP_ADDRESS unreachable
ip rule add to VPN_SERVER_IP_ADDRESS table main

echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6

These commands need only be run once per boot. The changes they make will be lost when the system reboots.

#!/bin/sh
#
# Environment variables that can be passed in via OpenVPN's --setenv:
# OPENVPN_ROUTE_TABLE - the routing table to which all routes are added
# OPENVPN_ROUTE_SOURCE - the source IP address for all routes
#
TABLE=$OPENVPN_ROUTE_TABLE
SOURCE=$OPENVPN_ROUTE_SOURCE
if [ -n "$TABLE" -o -n "$SOURCE" ]
then
# Replace existing routes for our interface with new routes with different table/src
if [ -n "$SOURCE" ]
then
src_arg="src $SOURCE"
else
src_arg=
fi
/sbin/ip route show dev $dev table main | while read route
do
/sbin/ip route delete $route dev $dev table main
/sbin/ip route add $route dev $dev $src_arg table ${TABLE:-main}
done
fi
if [ -n "$TABLE" ]
then
# Replace existing IPv6 routes for our interface with new routes with different table
/sbin/ip -6 route show dev $dev table main | while read route
do
/sbin/ip -6 route delete $route dev $dev table main
/sbin/ip -6 route add $route dev $dev table $TABLE
done
fi
# Add IPv4 routes
i=1
while true
do
network=`eval 'echo $route_network_'$i`
netmask=`eval 'echo $route_netmask_'$i`
gateway=`eval 'echo $route_gateway_'$i`
metric=`eval 'echo $route_metric_'$i`
if [ "$network" = "" ]
then
break
fi
command="/sbin/ip route add $network"
if [ "$netmask" != "" ]
then
command="$command/$netmask"
fi
if [ "$TABLE" != "" ]
then
command="$command table $TABLE"
fi
if [ "$metric" != "" ]
then
command="$command metric $metric"
fi
command="$command dev $dev via $gateway"
if [ "$SOURCE" != "" ]
then
command="$command src $SOURCE"
fi
$command
i=`expr $i + 1`
done
# Add IPv6 routes
i=1
while true
do
network=`eval 'echo $route_ipv6_network_'$i`
gateway=`eval 'echo $route_ipv6_gateway_'$i`
if [ "$network" = "" ]
then
break
fi
command="/sbin/ip -6 route add $network"
if [ "$TABLE" != "" ]
then
command="$command table $TABLE"
fi
command="$command dev $dev via $gateway"
$command
i=`expr $i + 1`
done
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.