You are not logged in.

#1 2015-08-22 22:49:00

msalerno
Member
Registered: 2014-08-15
Posts: 32

Howto: OpenVPN client as network gateway - Looking for cirtique/review

I think this will make a good wiki article when it's complete, but it's not quite there yet.   It's working great in my house but there are still a few issues.   I'm also hoping that someone more experienced with iptables can tell me if the config I posted below is secure.

This configuration is heavily influenced from scripts used in the Merlin Router Firmware project.

TODO:  Have shell script (vpnroute.sh) add additional iptables rules for port forwarding based on VPN connection.
TODO:  Resolve routing loop
TODO:  Kill switch to prevent clients from routing out other gateway if VPN goes down. - Currently working due to route loop issue above.
Other TODO's are listed in the comments of the script.

Objective:
From my local LAN I want to be able to route to the internet using the following criteria:

  • Route entire LAN out to the internet through VPN

  • Route specific hosts on my LAN to the internet through VPN

  • Route specific destination IP or IP ranges to the internet through VPN

Network setup:

  • Network: 192.168.10.0/24

  • Internet Gateway: 192.168.10.1

  • VPN Client System: 192.168.10.2

  • Default route on all lan clients: 192.168.10.1

  • Route on Internet Gateway: 212.58.224.0/19 via 192.168.10.2

Summary of how it works:
Utilizing Linux Advanced routing through iproute2 I create a custom routing table per tun+ interface.   Also using iproute2 I setup rules based on source and or destination.  Iptables uses MASQUERADE to make everything work together.

Add the following script to the OpenVPN client configuration:


/etc/openvpn/<client>.conf:

script-security 2 system
route-up /etc/openvpn/vpnroute.sh 
route-pre-down /etc/openvpn/vpnroute.sh

Contents of: /etc/openvpn/vpnroute.sh

#!/bin/bash

##
## Define variables and paths to be used throuout the script
##

#
# Define the routing table ID base on the tun adapter
# -- I should probably check to see if the value is numeric
# -- I should probably check to see if the table is already in use.
#
# Ex. tun1 creates table 101
#     tun2 creates table 102
#
TABLE="10"${dev:3}

#
# Define the routing rules input filename
# -- I should clean this up as well.
#
# Ex. If your adapter is tun1 the filename is /etc/openvpn/iprules.101
#
iprulefile="/etc/openvpn/iprules.$TABLE"

##
## Cleanup routing table on route-pre-down event
##


#########
# CLEAN UP RULES in down
#########

if [ $script_type == "route-pre-down" ]; then
	ip route flush table $TABLE
	ip route flush cache

	#
	# Clean up the rules
	#

	while read -r line
	do
		ip rule del $line lookup $TABLE
	done < "$iprulefile"
	exit 0
fi

##
## Ensure that the kernel IP parameters are setup to allow routing
##

#
# Ensure ip forwarding is enabled on all interfaces
# -- I guess I could just specify the tun and eth? used but this works for now
#

for f in /proc/sys/net/ipv4/conf/*/forwarding ; do `echo 1 > $f` ; done

#
# Ensure that hosts on my local lan can use traceroute out the VPN
#

for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do
	echo 0 > $i
done

##
## Setup new routing
##

#
# Create Custom Table for VPN
#

ip route flush table $TABLE

#
# Read the iprule file and create the rules
#
while read -r line
do
	ip rule add $line lookup $TABLE
done < "$iprulefile"

#
# Copy the main routing table into the new routing table $TABLE
#

ip route show table main | while read ROUTE
do
	ip route add table $TABLE $ROUTE
done

#
# Clean up the main routing table of any VPN routes.
# The only remaining VPN route is the route to define the VPN nework
#

ip route show table main | while read -a line ; do
	if [ ${line[1]} = "via" ] && [ ${line[2]} == $route_vpn_gateway ] && [ ${line[3]} == "dev" ] && [ ${line[4]} == $dev ]; then
		ip route del ${line[0]} dev $dev
	fi
done

ip route flush cache

exit 0

Create a file that defines your routing rules.   Read the comments in the above script on how to name the file.  Below is an example from my system:
Reference 1
Reference 2
/etc/openvpn/iprules.102

from all to 212.58.224.0/19

Setup iptables so that your internal clients can route out to the internet.

/etc/iptables/iptables.rules

*nat
:PREROUTING ACCEPT [272:22256]
:INPUT ACCEPT [51:8773]
:OUTPUT ACCEPT [9:670]
:POSTROUTING ACCEPT [112:7007]
-A POSTROUTING -o tun+ -j MASQUERADE
COMMIT

*filter
:INPUT ACCEPT [3:201]
:FORWARD ACCEPT [105:6468]
:OUTPUT ACCEPT [637:71150]
-A INPUT -i tun+ -j ACCEPT
-A INPUT -i eth0 -j ACCEPT
-A FORWARD -i eth0 -o tun+ -j ACCEPT
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
COMMIT

Last edited by msalerno (2015-08-23 04:41:12)

Offline

Board footer

Powered by FluxBB