You are not logged in.
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