eibgrad

merlin-ovpn-kill-switch-74948.sh

Sep 28th, 2021 (edited)
1,117
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/sh
  2. # version: 1.1.0, 07-oct-2021, by eibgrad
  3. # href: https://tinyurl.com/crwtpkep
  4.  
  5. SCRIPTS_DIR="/jffs/scripts"
  6. SCRIPT="$SCRIPTS_DIR/firewall-start"
  7.  
  8. mkdir -p $SCRIPTS_DIR
  9.  
  10. create_script() {
  11. cat << "EOF" > $SCRIPT
  12. #!/bin/sh
  13. set -x # uncomment/comment to enable/disable debug mode
  14. {
  15. # ------------------------------ BEGIN OPTIONS ------------------------------- #
  16.  
  17. # openvpn clients that will participate in the kill switch (all by default)
  18. VPN_CLIENTS='1 2 3 4 5'
  19.  
  20. # uncomment/comment to enable/disable autostart checking
  21. VPN_AUTOSTART_ONLY= # only consider auto-started openvpn clients
  22.  
  23. # state checking: "state NEW" vs. no state
  24. #   state NEW:
  25. #     * any pre-existing LAN->WAN connections persist unless/until they
  26. #       timeout/close
  27. #     * remote access (WAN->LAN) is allowed (provided port forwarding is enabled)
  28. #     * more efficient (only LAN->WAN packets used to establish NEW connections
  29. #       are inspected)
  30. #   no state (default):
  31. #     * any pre-existing LAN->WAN connections are stopped/blocked
  32. #     * remote access (WAN->LAN) is denied (even if port forwarding is enabled)
  33. #     * less efficient (every LAN->WAN packet is inspected)
  34.  
  35. # uncomment/comment to enable/disable state checking
  36. #FW_STATE='-m state --state NEW'
  37.  
  38. # ------------------------------- END OPTIONS -------------------------------- #
  39.  
  40. # ---------------------- DO NOT CHANGE BELOW THIS LINE ----------------------- #
  41.  
  42. PBR_RULES="$(cat /jffs/openvpn/vpndirector_rulelist | sed 's/\s//g')"
  43. FW_CHAIN='ovpn_block_wan'
  44. WAN_IF="$(nvram get wan0_ifname)"
  45.  
  46. # function is_autostart_enabled( vpn-client-number )
  47. is_autostart_enabled() { nvram get vpn_clientx_eas | grep -q $1; }
  48.  
  49. # function is_kill_switch_participant( vpn-client-number )
  50. is_kill_switch_participant() { echo $VPN_CLIENTS | grep -q $1; }
  51.  
  52. # function is_redirect_all( vpn-client-number )
  53. is_redirect_all() { [ "$(nvram get vpn_client${1}_rgw)" == '1' ]; }
  54.  
  55. # cleanup from possible prior execution
  56. {
  57. iptables -D FORWARD -i br+ -o $WAN_IF $FW_STATE -j REJECT
  58. iptables -D FORWARD -i br+ -o $WAN_IF $FW_STATE -j $FW_CHAIN
  59. iptables -F $FW_CHAIN && iptables -X $FW_CHAIN
  60. } &>/dev/null
  61.  
  62. for i in $VPN_CLIENTS; do
  63.     # handle vpn client w/ "Yes(all)" routing policy
  64.     is_redirect_all $i || continue
  65.  
  66.     # prerequisite: vpn client has autostart enabled (when applicable)
  67.     [ ${VPN_AUTOSTART_ONLY+x} ] && ! is_autostart_enabled $i && continue
  68.  
  69.     # deny access to wan by *all* lan clients
  70.     iptables -I FORWARD -i br+ -o $WAN_IF $FW_STATE -j REJECT
  71.  
  72.     exit 0
  73. done
  74.  
  75. # create user-defined chain
  76. iptables -N $FW_CHAIN
  77.  
  78. # iterate over the pbr (policy based routing) rules
  79. for i in $(echo "$PBR_RULES" | tr '<' '\n'); do
  80.     # parse the rule into separate fields (ignore description field (#2))
  81.     for j in 1 3 4 5; do eval f$j="$(echo $i | cut -d'>' -f$j)"; done
  82.  
  83.     # prerequisite: enabled rule
  84.     [ "$f1" == '1' ] || continue
  85.  
  86.     # handle wan pbr rule
  87.     if echo $f5 | grep -q 'WAN'; then
  88.         # do NOT deny access to this local and/or remote ip/network
  89.         iptables -A $FW_CHAIN $([ "$f3" ] && echo "-s $f3") \
  90.             $([ "$f4" ] && echo "-d $f4") -j RETURN
  91.         continue
  92.     fi
  93.  
  94.     # handle vpn pbr rule
  95.     echo $f5 | grep -q 'OVPN' || continue
  96.  
  97.     # isolate vpn client number
  98.     f5="$(echo $f5 | grep -o [1-5])"
  99.  
  100.     # prerequisite: vpn client is kill switch participant
  101.     is_kill_switch_participant $f5 || continue
  102.  
  103.     # prerequisite: vpn client has autostart enabled (when applicable)
  104.     [ ${VPN_AUTOSTART_ONLY+x} ] && ! is_autostart_enabled $f5 && continue
  105.  
  106.     # deny access to wan for this local and/or remote ip/network
  107.     iptables -A $FW_CHAIN $([ "$f3" ] && echo "-s $f3") \
  108.         $([ "$f4" ] && echo "-d $f4") -j REJECT
  109. done
  110.  
  111. # force LAN->WAN traffic thru user-defined chain for inspection
  112. iptables -I FORWARD -i br+ -o $WAN_IF $FW_STATE -j $FW_CHAIN
  113.  
  114. exit 0
  115. #} >/tmp/$(basename $0).$$.log 2>&1
  116. } 2>&1 | logger -t $(basename $0)[$$]
  117. EOF
  118. chmod +x $SCRIPT
  119. }
  120.  
  121. if [ -f $SCRIPT ]; then
  122.     echo "error: $SCRIPT already exists; requires manual installation"
  123. else
  124.     create_script
  125.     echo 'Done.'
  126. fi
RAW Paste Data