eibgrad

ddwrt-ovpn-remote-access.sh

Mar 11th, 2018 (edited)
1,112
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/sh
  2. #DEBUG=; set -x # comment/uncomment to disable/enable debug mode
  3.  
  4. #         name: ddwrt-ovpn-remote-access.sh
  5. #      version: 2.0.0, 25-aug-2020, by eibgrad
  6. #      purpose: enable remote access over wan w/ active openvpn client
  7. #  script type: startup (autostart)
  8. #  installation:
  9. #    1. enable jffs2 (administration->jffs2)
  10. #    2. enable syslogd (services->services->system log)
  11. #    3. use shell (telnet/ssh) to execute one of the following commands:
  12. #         curl -kLs bit.ly/ddwrt-installer|tr -d '\r'|sh -s gnxtZuqg startup
  13. #       or
  14. #         wget -qO - bit.ly/ddwrt-installer|tr -d '\r'|sh -s gnxtZuqg startup
  15. #    4. modify options (minimally DDNS_DOMAIN_NAMES) using vi editor:
  16. #         vi /jffs/etc/config/ddwrt-ovpn-remote-access.startup
  17. #    5. reboot
  18. #
  19. #  WARNING: this script will NOT work as intended if you use the pbr (policy
  20. #    based routing) field of the openvpn client gui, and the target of
  21. #    remote access is specified in that field, unless you also install the
  22. #    "table 10 fix" as described in the following dd-wrt bug report:
  23. #
  24. #    http://svn.dd-wrt.com/ticket/5690
  25. #
  26. #  UPDATE (23-jul-2020): the above requirement for cases where pbr is active
  27. #    with the openvpn client is no longer required *provided* you use a
  28. #    dd-wrt build as of the date of this notice or later.
  29. {
  30. # ------------------------------ BEGIN OPTIONS ------------------------------- #
  31.  
  32. # "roaming" ddns domain name(s)
  33. DDNS_DOMAIN_NAMES='
  34. myhostname.duckdns.org
  35. #myhostname2.duckdns.org
  36. #myhostname3.duckdns.org
  37. '
  38.  
  39. # time (in secs) between checks for ddns updates
  40. UPDATE_INTERVAL=300
  41.  
  42. # optional: well-known static routes
  43. STATIC_ROUTES='
  44. #171.190.59.0/24 # workplace
  45. #230.139.191.67 # vacation home
  46. #215.126.219.216 # local wifi cafe
  47. '
  48.  
  49. # optional: some servers may update faster and/or more reliably than others
  50. #DNS_SERVER='1.1.1.1' # cloudflare
  51. #DNS_SERVER='8.8.8.8' # google
  52. #DNS_SERVER='9.9.9.9' # quad9
  53. #DNS_SERVER='duckdns.org' # recommended when using duckdns ddns
  54.  
  55. # ------------------------------- END OPTIONS -------------------------------- #
  56.  
  57. # ---------------------- DO NOT CHANGE BELOW THIS LINE ----------------------- #
  58.  
  59. TID='10'
  60.  
  61. # function get_ip( domain-name [server] )
  62. get_ip() {
  63.     nslookup $1 $2 2> /dev/null | \
  64.         awk '/^Name:/,0 {if (/^Addr[^:]*: [0-9]{1,3}\./) print $3}'
  65. }
  66.  
  67. # wait for wan availability
  68. while ! ping -qc1 -w3 8.8.8.8 > /dev/null 2>&1; do sleep 10; done
  69.  
  70. # periodically update routing table
  71. while :; do
  72.     gateway_ip="$(ip route | awk '/^default/{print $3}')"
  73.     static_ip_list=''
  74.     curr_ddns_ip_list=''
  75.     routing_change=false
  76.  
  77.     # set internal field separator to newline
  78.     OIFS="$IFS"; IFS=$'\n'
  79.  
  80.     # add well-known static route(s)
  81.     for ip in $STATIC_ROUTES; do
  82.         # skip comments and blank lines
  83.         echo $ip | grep -Eq '^[[:space:]]*(#|$)' && continue
  84.  
  85.         # isolate ip address (treat the rest as comments)
  86.         ip="$(echo $ip | awk '{print $1}')"
  87.  
  88.         # track static ips
  89.         static_ip_list="$ip $static_ip_list"
  90.  
  91.         if ! ip route | grep -q "^$ip "; then
  92.             if ip route add $ip via $gateway_ip; then
  93.                 routing_change=true
  94.                 echo "info: route added (main): $ip"
  95.             fi
  96.         fi
  97.  
  98.         if [ "$(ip route show table $TID)" ]; then
  99.             if ! ip route show table $TID | grep -q "^$ip "; then
  100.                 if ip route add $ip via $gateway_ip table $TID; then
  101.                     routing_change=true
  102.                     echo "info: route added (pbr): $ip"
  103.                 fi
  104.             fi
  105.         fi
  106.     done
  107.  
  108.     # add current ddns static route(s)
  109.     for dom in $DDNS_DOMAIN_NAMES; do
  110.         # skip comments and blank lines
  111.         echo $dom | grep -Eq '^[[:space:]]*(#|$)' && continue
  112.  
  113.         # determine public ip (if any) bound to domain name
  114.         ip="$(get_ip $dom $(echo $DNS_SERVER | awk '{print $1}'))"
  115.  
  116.         [ $ip ] || { echo "error: cannot resolve $dom"; continue; }
  117.  
  118.         # skip duplicates
  119.         echo "$curr_ddns_ip_list" | grep -q "$ip " && continue
  120.  
  121.         # track ddns ips
  122.         curr_ddns_ip_list="$ip $curr_ddns_ip_list"
  123.  
  124.         if ! ip route | grep -q "^$ip "; then
  125.             if ip route add $ip via $gateway_ip; then
  126.                 routing_change=true
  127.                 echo "info: route added (main): $ip"
  128.             fi
  129.         fi
  130.  
  131.         if [ "$(ip route show table $TID)" ]; then
  132.             if ! ip route show table $TID | grep -q "^$ip "; then
  133.                 if ip route add $ip via $gateway_ip table $TID; then
  134.                     routing_change=true
  135.                     echo "info: route added (pbr): $ip"
  136.                 fi
  137.             fi
  138.         fi
  139.     done
  140.  
  141.     # reset internal field separator
  142.     IFS="$OIFS"
  143.  
  144.     # delete previous ddns static route(s)
  145.     for ip in $prev_ddns_ip_list; do
  146.         if ! echo "$static_ip_list" | grep -q "$ip "; then
  147.             if ! echo "$curr_ddns_ip_list" | grep -q "$ip "; then
  148.                 if ip route | grep -q "^$ip "; then
  149.                     if ip route del $ip via $gateway_ip; then
  150.                         routing_change=true
  151.                         echo "info: route deleted (main): $ip"
  152.                     fi
  153.                 fi
  154.                 if [ "$(ip route show table $TID)" ]; then
  155.                     if ip route show table $TID | grep -q "^$ip "; then
  156.                         if ip route del $ip via $gateway_ip table $TID; then
  157.                             routing_change=true
  158.                             echo "info: route deleted (pbr): $ip"
  159.                         fi
  160.                     fi
  161.                 fi
  162.             fi
  163.         fi
  164.     done
  165.  
  166.     # force routing system to recognize changes
  167.     [[ $routing_change == true ]] && ip route flush cache
  168.  
  169.     # save current ddns ips
  170.     prev_ddns_ip_list="$curr_ddns_ip_list"
  171.  
  172.     # wait awhile and repeat
  173.     sleep $UPDATE_INTERVAL
  174. done
  175.  
  176. } 2>&1 | logger $([ ${DEBUG+x} ] && echo '-p user.debug') \
  177.     -t $(echo $(basename $0) | grep -Eo '^.{0,23}')[$$] &
RAW Paste Data