Skip to content

Instantly share code, notes, and snippets.

@transilluminate
Created March 22, 2023 15:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save transilluminate/7e4a2cf645cd69e81506d199555f1542 to your computer and use it in GitHub Desktop.
Save transilluminate/7e4a2cf645cd69e81506d199555f1542 to your computer and use it in GitHub Desktop.

Selectively route specific IP addresses through VPN tunnel

This is a method for setting up an OpenVPN tunnel on a Raspberry Pi router device, which does not route all traffic via the VPN, but selective IP address within the LAN.

Note 1: also uses the amazing sqm-scripts for traffic shaping, to reduce bufferbloat as much as possible.

Note 2: eth0 is our internal LAN, wlan0 is our external WAN

  1. Allow packet forwarding (on reboot)
  • $ sudo nano /etc/sysctl.conf, uncomment this line:
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
  1. Load a very permissive forwarding setup
  • $ sudo nano /etc/iptables_rules_ipv4, add:
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A FORWARD -i wlan0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -o wlan0 -j ACCEPT
-A FORWARD -i tun0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -o tun0 -j ACCEPT
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o wlan0 -j MASQUERADE
-A POSTROUTING -o tun0 -j MASQUERADE
COMMIT
  1. Load the ifb (intermediate functional block) interface for SQM:
  • $ sudo nano /etc/modules-load.d/modules.conf
  • add ifb numifbs=0 to the end
  1. Start SQM on boot, and load iptables rules:
  • $ sudo nano /etc/rc.local, add this (before the exit 0):
/usr/sbin/iptables-restore < /etc/iptables_rules_ipv4
/usr/bin/sqm start wlan0 # WAN gateway
  1. Modify your (working!) OpenVPN config to not set up a default route for all traffic:
  • $ sudo nano /etc/openvpn/pia.conf, add within the existing config:
route-nopull
up '/etc/openvpn/up.sh'
route-pre-down '/etc/openvpn/route-pre-down.sh'
  1. Add a VPN "up" script
  • $ sudo touch /etc/openvpn/up.sh
  • $ sudo chmod 700 /etc/openvpn/up.sh
  • $ sudo nano /etc/openvpn/up.sh, add:
#!/bin/bash
VPN_DEVICE=$1
VPN_GATEWAY=$4
TABLE="vpn"  # defined in /etc/iproute2/rt_tables
echo "OpenVPN -> up.sh"
/usr/bin/sqm start $VPN_DEVICE
ip route flush table $TABLE
ip route add default dev $VPN_DEVICE via $VPN_GATEWAY table $TABLE
# static IP addresses to use the VPN
ip rule add from 192.168.0.2/32 table $TABLE
  1. Add a VPN "down" script
  • $ sudo touch /etc/openvpn/route-pre-down.sh
  • $ sudo chmod 700 /etc/openvpn/route-pre-down.sh
  • $ sudo nano /etc/openvpn/route-pre-down.sh, add:
#!/bin/bash
VPN_DEVICE=$1
VPN_GATEWAY=$4
TABLE="vpn"
echo "OpenVPN -> route-pre-down.sh"
/usr/bin/sqm stop $VPN_DEVICE
ip rule flush table $TABLE
  1. Define the VPN routing table:
  • $ sudo nano /etc/iproute2/rt_tables, add:
1       vpn
  1. Configure your /etc/sqm/.iface.conf scripts, see sqm-scripts for details...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment