eibgrad

tomato-ovpn-split-basic.sh

Feb 22nd, 2017 (edited)
2,298
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/sh
  2. DEBUG=; set -x # uncomment/comment to enable/disable debug mode
  3.  
  4. #          name: tomato-ovpn-split-basic.sh
  5. #       version: 2.0.0, 25-aug-2020, by eibgrad
  6. #       purpose: redirect specific traffic over the WAN|VPN
  7. #   script type: openvpn (route-up, route-pre-down)
  8. #  installation:
  9. #    1. enable jffs (administration->jffs)
  10. #    2. enable syslog (status->logs->logging configuration->syslog)
  11. #    3. use shell (telnet/ssh) to execute one of the following commands:
  12. #         curl -kLs bit.ly/tomato-installer|tr -d '\r'|sh -s -- --dir /jffs xEziw8Pq
  13. #       or
  14. #         wget -qO - bit.ly/tomato-installer|tr -d '\r'|sh -s -- --dir /jffs xEziw8Pq
  15. #    4. use vi editor to modify script w/ your rules:
  16. #         vi /jffs/tomato-ovpn-split-basic.sh
  17. #    5. create symbolic links:
  18. #         ln -sf /jffs/tomato-ovpn-split-basic.sh /jffs/route-up
  19. #         ln -sf /jffs/tomato-ovpn-split-basic.sh /jffs/route-down
  20. #    6. add the following to openvpn client custom configuration:
  21. #         script-security 2
  22. #         route-up /jffs/route-up
  23. #         route-pre-down /jffs/route-down
  24. #    7. optional: by default, the default gateway is changed to the VPN,
  25. #       so the rules reroute over the WAN; to set/lockdown the default
  26. #       gateway to the WAN and have the rules reroute to the VPN, add the
  27. #       following directives to openvpn client custom configuration:
  28. #         pull-filter ignore "redirect-gateway"
  29. #         redirect-private def1
  30. #    8. disable policy based routing (vpn tunneling->openvpn client->
  31. #       routing policy tab)
  32. #    9. reboot
  33. #   limitations:
  34. #     - this script is only compatible w/ freshtomato v2020.2 or later
  35. #     - due to a known bug ( http://bit.ly/2nXMSjx ), this script WILL NOT
  36. #       WORK w/ any arm-based freshtomato build that supports multi-wan,
  37. #       even if multi-wan is NOT actively in use
  38. #     - this script is limited to *one* active OpenVPN client at a time
  39. #     - this script is NOT compatible w/ tomato policy based routing
  40. #     - rules are limited to source ip/network/interface and destination
  41. #       ip/network; split tunneling within any given source or destination
  42. #       (protocol, port, etc.) is NOT supported
  43. #     - rules do NOT support domain names (e.g., google.com)
  44. (
  45. add_rules() {
  46. # ----------------------------------- FYI ------------------------------------ #
  47. # * the order of rules doesn't matter (there is no order of precedence)
  48. # * if any rule matches, those packets bypass the current default gateway
  49. # ---------------------------------------------------------------------------- #
  50.  
  51. # ------------------------------- BEGIN RULES -------------------------------- #
  52. # specify source ip(s)/network(s)/interface(s) to be rerouted
  53. #add_rule iif br1             # guest network
  54. #add_rule from 192.168.1.7    # mary's pc
  55. #add_rule from 192.168.2.0/24 # iot network
  56.  
  57. # specify destination ip(s)/network(s) to be rerouted
  58. #add_rule to 4.79.142.0/24    # grc.com
  59. #add_rule to 172.217.6.142    # maps.google.com
  60.  
  61. # specify source + destination to be rerouted
  62. #add_rule iif br2             to 121.121.121.121
  63. #add_rule from 192.168.1.10   to 122.122.122.122
  64. #add_rule from 192.168.2.0/24 to 133.133.133.0/24
  65. # -------------------------------- END RULES --------------------------------- #
  66. :;}
  67. # ---------------------- DO NOT CHANGE BELOW THIS LINE ----------------------- #
  68.  
  69. CID="${dev:4:1}"
  70.  
  71. ENV_VARS="/tmp/env_vars_${CID}"
  72.  
  73. # make environment variables persistent across openvpn events
  74. [ "$script_type" == 'route-up' ] && env > $ENV_VARS
  75.  
  76. # utility function for retrieving environment variable values
  77. env_get() { echo $(grep -Em1 "^$1=" $ENV_VARS | cut -d = -f2); }
  78.  
  79. TID="20${CID}"
  80. OVPN_REDIRECT_GW="$(nvram get vpn_client${CID}_rgw)"
  81.  
  82. add_rule() {
  83.     # precede addition w/ deletion to avoid dupes
  84.     ip rule del table $TID "$@" 2>/dev/null
  85.     ip rule add table $TID "$@"
  86. }
  87.  
  88. up() {
  89.     # copy main routing table to alternate (exclude all default gateways)
  90.     ip route show | grep -Ev '^default |^0.0.0.0/1 |^128.0.0.0/1 ' \
  91.       | while read route; do
  92.             ip route add $route table $TID
  93.         done
  94.  
  95.     # test for presence of vpn gateway override in main routing table
  96.     if ip route | grep -q "^0\.0\.0\.0/1 .*$(env_get dev)"; then
  97.         # add WAN as default gateway to alternate routing table
  98.         ip route add default via $(env_get route_net_gateway) table $TID
  99.     else
  100.         # add VPN as default gateway to alternate routing table
  101.         ip route add default via $(env_get route_vpn_gateway) table $TID
  102.     fi
  103.  
  104.     # start split tunnel
  105.     add_rules
  106.  
  107.     # force routing system to recognize changes
  108.     ip route flush cache
  109. }
  110.  
  111. down() {
  112.     # stop split tunnel
  113.     while ip rule del from 0/0 to 0/0 table $TID 2>/dev/null; do :; done
  114.  
  115.     # delete alternate routing table
  116.     ip route flush table $TID
  117.  
  118.     # force routing system to recognize changes
  119.     ip route flush cache
  120.  
  121.     # cleanup
  122.     rm -f $ENV_VARS
  123. }
  124.  
  125. main() {
  126.     # reject cli invocation; script only applicable to routed (tun) tunnels
  127.     [[ -t 0 || "$(env_get dev_type)" != 'tun' ]] && return 1
  128.  
  129.     # tomato policy based routing can NOT be active at the same time
  130.     if [[ "$OVPN_REDIRECT_GW" == '2' || "$OVPN_REDIRECT_GW" == '3' ]]; then
  131.         echo 'error: tomato policy based routing is currently active'
  132.         exit 1
  133.     fi
  134.  
  135.     # trap event-driven callbacks by openvpn and take appropriate action(s)
  136.     case "$script_type" in
  137.               route-up) up;;
  138.         route-pre-down) down;;
  139.                      *) echo "warning: unexpected invocation: $script_type";;
  140.     esac
  141.  
  142.     return 0
  143. }
  144.  
  145. main
  146.  
  147. ) 2>&1 | logger -p user.$([ ${DEBUG+x} ] && echo 'debug' || echo 'notice') \
  148.     -t $(echo $(basename $0) | grep -Eo '^.{0,23}')[$$]
RAW Paste Data