Skip to content

Instantly share code, notes, and snippets.

@Wysie
Last active February 3, 2023 02:10
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save Wysie/7487571 to your computer and use it in GitHub Desktop.
Save Wysie/7487571 to your computer and use it in GitHub Desktop.
Script to route traffic from home network through VPN selectively.Based off the discussion at http://www.smallnetbuilder.com/forums/showthread.php?t=9311The setup is a Roku box, a Home PC running Plex, and a Synology NAS with a torrent client running a web interface.The aim is to have all traffic from Roku go through the VPN, all traffic from th…
#!/bin/sh
# Script to route traffic from home network through VPN selectively.
# Based off the discussion at http://www.smallnetbuilder.com/forums/showthread.php?t=9311
# The setup is a Roku box, a Home PC running Plex, and a Synology NAS with a torrent client running a web interface.
# The aim is to have all traffic from Roku go through the VPN, all traffic from the Home PC (and all other devices) bypassing the VPN,
# and the Synology NAS using the VPN. There are however some exceptions. Since Plex uses port 32400, Roku has to bypass the VPN when
# using that port. In addition, port 9091 has to bypass the VPN as well in order to access the Synology torrent client.
#
# Requirements: Asuswrt-Merlin with OpenVPN already set up
logger -t "($(basename $0))" $$ ExpressVPN Selective Customization Starting... " $0${*:+ $*}."
PC_Home="192.168.1.50"
Synology_NAS="192.168.1.51"
Roku="192.168.1.52"
# SHELL COMMANDS FOR MAINTENANCE.
# DO NOT UNCOMMENT, THESE ARE INTENDED TO BE USED IN A SHELL COMMAND LINE
#
# List Contents by line number
# iptables -L PREROUTING -t mangle -n --line-numbers
#
# Delete rules from mangle by line number
# iptables -D PREROUTING type-line-number-here -t mangle
#
# To list the current rules on the router, issue the command:
# iptables -t mangle -L PREROUTING
#
# Flush/reset all the rules to default by issuing the command:
# iptables -t mangle -F PREROUTING
#
# Disable Reverse Path Filtering on all current and future network interfaces:
#
for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do
echo 0 > $i
done
#
# Delete table 100 and flush any existing rules if they exist.
#
ip route flush table 100
ip route del default table 100
ip rule del fwmark 1 table 100
ip route flush cache
iptables -t mangle -F PREROUTING
#
# Copy all non-default and non-VPN related routes from the main table into table 100.
# Then configure table 100 to route all traffic out the WAN gateway and assign it mark "1"
#
tun_if="tun11"
ip route show table main | grep -Ev ^default | grep -Ev $tun_if \
| while read ROUTE ; do
ip route add table 100 $ROUTE
logger -t "($(basename $0))" $$ ExpressVPN Table 100 added entry: $ROUTE
done
ip route add default table 100 via $(nvram get wan0_gateway)
ip rule add fwmark 1 table 100
ip route flush cache
# By default all traffic bypasses the VPN
iptables -t mangle -A PREROUTING -i br0 -j MARK --set-mark 1
logger -t "($(basename $0))" $$ Selective customisation for: "$"Roku $Roku
# By default Roku uses the VPN
iptables -t mangle -A PREROUTING -i br0 -m iprange --src-range $Roku -j MARK --set-mark 0
logger -t "($(basename $0))" $$ Selective customisation for: "$"Synology_NAS $Synology_NAS
# By default Synology uses the VPN, and FORCES the use of the VPN tunnel except for port 9091
iptables -t mangle -A PREROUTING -i br0 -m iprange --src-range $Synology_NAS -j MARK --set-mark 0
iptables -I FORWARD -i br0 -s $Synology_NAS -o eth0 -j DROP
iptables -I FORWARD -i br0 -s $Synology_NAS -o eth0 -p tcp -m multiport --port 9091 -j ACCEPT
# Ports 22 (SSH), 9091 (Torrent RPC/WebUI) and 32400 (Plex) will bypass the VPN
iptables -t mangle -A PREROUTING -i br0 -p tcp -m multiport --port 22,9091,32400 -j MARK --set-mark 1
logger -t "($(basename $0))" $$ ExpressVPN Selective Customization completed.
@cristobalvp
Copy link

I know that it is an old post, but I only wanted to thank you for your script. You can not imagine how many hours I spent to make it working in my router, and your script works just with a very little change. Thanks for sharing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment