Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/sh
- DEBUG=; set -x # uncomment/comment to enable/disable debug mode
- # name: tomato-ovpn-split-basic.sh
- # version: 2.0.0, 25-aug-2020, by eibgrad
- # purpose: redirect specific traffic over the WAN|VPN
- # script type: openvpn (route-up, route-pre-down)
- # installation:
- # 1. enable jffs (administration->jffs)
- # 2. enable syslog (status->logs->logging configuration->syslog)
- # 3. use shell (telnet/ssh) to execute one of the following commands:
- # curl -kLs bit.ly/tomato-installer|tr -d '\r'|sh -s -- --dir /jffs xEziw8Pq
- # or
- # wget -qO - bit.ly/tomato-installer|tr -d '\r'|sh -s -- --dir /jffs xEziw8Pq
- # 4. use vi editor to modify script w/ your rules:
- # vi /jffs/tomato-ovpn-split-basic.sh
- # 5. create symbolic links:
- # ln -sf /jffs/tomato-ovpn-split-basic.sh /jffs/route-up
- # ln -sf /jffs/tomato-ovpn-split-basic.sh /jffs/route-down
- # 6. add the following to openvpn client custom configuration:
- # script-security 2
- # route-up /jffs/route-up
- # route-pre-down /jffs/route-down
- # 7. optional: by default, the default gateway is changed to the VPN,
- # so the rules reroute over the WAN; to set/lockdown the default
- # gateway to the WAN and have the rules reroute to the VPN, add the
- # following directives to openvpn client custom configuration:
- # pull-filter ignore "redirect-gateway"
- # redirect-private def1
- # 8. disable policy based routing (vpn tunneling->openvpn client->
- # routing policy tab)
- # 9. reboot
- # limitations:
- # - this script is only compatible w/ freshtomato v2020.2 or later
- # - due to a known bug ( http://bit.ly/2nXMSjx ), this script WILL NOT
- # WORK w/ any arm-based freshtomato build that supports multi-wan,
- # even if multi-wan is NOT actively in use
- # - this script is limited to *one* active OpenVPN client at a time
- # - this script is NOT compatible w/ tomato policy based routing
- # - rules are limited to source ip/network/interface and destination
- # ip/network; split tunneling within any given source or destination
- # (protocol, port, etc.) is NOT supported
- # - rules do NOT support domain names (e.g., google.com)
- (
- add_rules() {
- # ----------------------------------- FYI ------------------------------------ #
- # * the order of rules doesn't matter (there is no order of precedence)
- # * if any rule matches, those packets bypass the current default gateway
- # ---------------------------------------------------------------------------- #
- # ------------------------------- BEGIN RULES -------------------------------- #
- # specify source ip(s)/network(s)/interface(s) to be rerouted
- #add_rule iif br1 # guest network
- #add_rule from 192.168.1.7 # mary's pc
- #add_rule from 192.168.2.0/24 # iot network
- # specify destination ip(s)/network(s) to be rerouted
- #add_rule to 4.79.142.0/24 # grc.com
- #add_rule to 172.217.6.142 # maps.google.com
- # specify source + destination to be rerouted
- #add_rule iif br2 to 121.121.121.121
- #add_rule from 192.168.1.10 to 122.122.122.122
- #add_rule from 192.168.2.0/24 to 133.133.133.0/24
- # -------------------------------- END RULES --------------------------------- #
- :;}
- # ---------------------- DO NOT CHANGE BELOW THIS LINE ----------------------- #
- CID="${dev:4:1}"
- ENV_VARS="/tmp/env_vars_${CID}"
- # make environment variables persistent across openvpn events
- [ "$script_type" == 'route-up' ] && env > $ENV_VARS
- # utility function for retrieving environment variable values
- env_get() { echo $(grep -Em1 "^$1=" $ENV_VARS | cut -d = -f2); }
- TID="20${CID}"
- OVPN_REDIRECT_GW="$(nvram get vpn_client${CID}_rgw)"
- add_rule() {
- # precede addition w/ deletion to avoid dupes
- ip rule del table $TID "$@" 2>/dev/null
- ip rule add table $TID "$@"
- }
- up() {
- # copy main routing table to alternate (exclude all default gateways)
- ip route show | grep -Ev '^default |^0.0.0.0/1 |^128.0.0.0/1 ' \
- | while read route; do
- ip route add $route table $TID
- done
- # test for presence of vpn gateway override in main routing table
- if ip route | grep -q "^0\.0\.0\.0/1 .*$(env_get dev)"; then
- # add WAN as default gateway to alternate routing table
- ip route add default via $(env_get route_net_gateway) table $TID
- else
- # add VPN as default gateway to alternate routing table
- ip route add default via $(env_get route_vpn_gateway) table $TID
- fi
- # start split tunnel
- add_rules
- # force routing system to recognize changes
- ip route flush cache
- }
- down() {
- # stop split tunnel
- while ip rule del from 0/0 to 0/0 table $TID 2>/dev/null; do :; done
- # delete alternate routing table
- ip route flush table $TID
- # force routing system to recognize changes
- ip route flush cache
- # cleanup
- rm -f $ENV_VARS
- }
- main() {
- # reject cli invocation; script only applicable to routed (tun) tunnels
- [[ -t 0 || "$(env_get dev_type)" != 'tun' ]] && return 1
- # tomato policy based routing can NOT be active at the same time
- if [[ "$OVPN_REDIRECT_GW" == '2' || "$OVPN_REDIRECT_GW" == '3' ]]; then
- echo 'error: tomato policy based routing is currently active'
- exit 1
- fi
- # trap event-driven callbacks by openvpn and take appropriate action(s)
- case "$script_type" in
- route-up) up;;
- route-pre-down) down;;
- *) echo "warning: unexpected invocation: $script_type";;
- esac
- return 0
- }
- main
- ) 2>&1 | logger -p user.$([ ${DEBUG+x} ] && echo 'debug' || echo 'notice') \
- -t $(echo $(basename $0) | grep -Eo '^.{0,23}')[$$]
Add Comment
Please, Sign In to add comment