eibgrad

merlin-wol-port-forward.sh

Jan 7th, 2022 (edited)
1,476
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 6.07 KB | None | 0 0
  1. #!/bin/sh
  2. #DEBUG= # uncomment/comment to enable/disable debug mode
  3.  
  4. #          name: merlin-wol-port-forward.sh
  5. #       version: 2.1.0, 27-jul-2022, by eibgrad
  6. #       purpose: wol to target of port forwarding
  7. #       type(s): init-start, nat-start
  8. #          href: https://tinyurl.com/2hwea3y7
  9. #  installation:
  10. #    1. enable jffs custom scripts and configs (administration->system)
  11. #    2. ssh to router and copy/paste the following command:
  12. #         curl -kLs bit.ly/merlin-installer|tr -d '\r'|sh -s b7p6f102
  13. #    3. modify script w/ your preferred options using nano editor:
  14. #         nano /jffs/configs/merlin-wol-port-forward.options
  15. #    4. reboot
  16.  
  17. CONFIGS_DIR='/jffs/configs'
  18. CONFIG="$CONFIGS_DIR/merlin-wol-port-forward.options"
  19.  
  20. SCRIPTS_DIR='/jffs/scripts'
  21. SCRIPT1="$SCRIPTS_DIR/merlin-wol-port-forward.nat"
  22. SCRIPT2="$SCRIPTS_DIR/merlin-wol-port-forward.init"
  23. SCRIPT3="$SCRIPTS_DIR/nat-start"
  24. SCRIPT4="$SCRIPTS_DIR/init-start"
  25.  
  26. mkdir -p $CONFIGS_DIR $SCRIPTS_DIR
  27.  
  28. # ------------------ begin merlin-wol-port-forward.options ------------------- #
  29. cat << 'EOF' > $CONFIG
  30. # ------------------------------ BEGIN OPTIONS ------------------------------- #
  31.  
  32. # protocol (tcp|udp) of port forward
  33. PROTO='tcp'
  34.  
  35. # source ip(s)/network(s) of port forward (comma-separated)
  36. SOURCE='0.0.0.0/0'
  37.  
  38. # external port of port forward
  39. EXT_PORT='5900'
  40.  
  41. # internal ip of port forward
  42. INT_IP='192.168.1.100'
  43.  
  44. # internal port of port forward
  45. INT_PORT='5900'
  46.  
  47. # mac address of internal ip (unspecified = static lease search)
  48. MAC_ADDR='' # hexidecimal format: XX:XX:XX:XX:XX:XX
  49.  
  50. # broadcast interface of internal ip
  51. BCAST_IF='br0'
  52.  
  53. # how often (in secs) to check for new wol messages
  54. INTERVAL=10
  55.  
  56. # ------------------------------- END OPTIONS -------------------------------- #
  57. EOF
  58. echo "installed: $CONFIG"
  59. # ------------------- end merlin-wol-port-forward.options -------------------- #
  60.  
  61. # -------------------- begin merlin-wol-port-forward.nat --------------------- #
  62. cat << 'EOF' > $SCRIPT1
  63. #!/bin/sh
  64. #set -x # comment/uncomment to disable/enable debug mode
  65. {
  66. . $CONFIG
  67.  
  68. # create port forward
  69. iptables -t nat -I VSERVER -p $PROTO -s $SOURCE --dport $EXT_PORT \
  70.     -j DNAT --to $INT_IP:$INT_PORT
  71.  
  72. # record access of port forward to log
  73. iptables -t nat -I VSERVER -p $PROTO -s $SOURCE --dport $EXT_PORT \
  74.     -j LOG --log-prefix "WPF: DIP=$INT_IP "
  75.  
  76. exit 0
  77. } 2>&1 | logger -t $(basename $0)[$$]
  78. EOF
  79. [ ${DEBUG+x} ] && sed -ri '2 s/^#(set -x)/\1/' $SCRIPT1
  80. sed -i "s:\$CONFIG:$CONFIG:g" $SCRIPT1
  81. chmod +x $SCRIPT1
  82. echo "installed: $SCRIPT1"
  83. # --------------------- end merlin-wol-port-forward.nat ---------------------- #
  84.  
  85. # -------------------- begin merlin-wol-port-forward.init -------------------- #
  86. cat << 'EOF' > $SCRIPT2
  87. #!/bin/sh
  88. #set -x # comment/uncomment to disable/enable debug mode
  89. (
  90. . $CONFIG
  91.  
  92. # mask used for finding wol messages
  93. WOL_MSG_MASK="[W]PF: DIP=$INT_IP .* PROTO=$PROTO .* DPT=$INT_PORT "
  94.  
  95. # work files
  96. CURR_MSG="/tmp/tmp.$$.curr_msg"
  97. PREV_MSG="/tmp/tmp.$$.prev_msg"; > $PREV_MSG
  98.  
  99. # ignore any saved wol messages across a reboot
  100. if [ -f /jffs/syslog.log ]; then
  101.     grep "$WOL_MSG_MASK" /jffs/syslog.log > $PREV_MSG
  102. fi
  103.  
  104. # wait for *reliable* internet connection
  105. until ping -qc1 -W3 8.8.8.8 &>/dev/null; do sleep 10; done
  106.  
  107. # validate mac address
  108. if [ ! "$MAC_ADDR" ]; then
  109.     MAC_ADDR=$(get_mac $INT_IP)
  110.     if [ ! "$MAC_ADDR" ]; then
  111.         echo "fatal error: mac address not found: $INT_IP"
  112.         exit 1
  113.     fi
  114. else
  115.     if ! echo "$MAC_ADDR" | \
  116.             grep -qE '^([[:xdigit:]]{2}:){5}[[:xdigit:]]{2}$'; then
  117.         echo "fatal error: invalid/malformed mac address: $MAC_ADDR"
  118.         exit 1
  119.     fi
  120. fi
  121.  
  122. while sleep $INTERVAL; do
  123.     # extract all wol messages
  124.     grep "$WOL_MSG_MASK" /tmp/syslog.log > $CURR_MSG
  125.  
  126.     # if there are any new wol messages, then wol as necessary
  127.     if [ -s $CURR_MSG ] && ! ping -qc1 -W3 $INT_IP &>/dev/null; then
  128.         if [ ! -s $PREV_MSG ] || \
  129.                 grep -m1 -Fxvf $PREV_MSG $CURR_MSG >/dev/null; then
  130.  
  131.             # try up to three (3) times to wake the device
  132.             for i in 1 2 3; do
  133.                 echo "info: waking up $MAC_ADDR (attempt #${i}) ..."
  134.                 ether-wake -bi $BCAST_IF $MAC_ADDR && sleep 20 || break
  135.                 if ping -qc1 -W3 $INT_IP &>/dev/null; then
  136.                     echo "info: $MAC_ADDR is alive!"
  137.                     break
  138.                 fi
  139.                 [ $i -eq 3 ] && echo "warning: $MAC_ADDR did NOT respond :("
  140.             done
  141.         fi
  142.     fi
  143.  
  144.     # remember which wol messages have already been processed
  145.     mv $CURR_MSG $PREV_MSG
  146. done
  147. ) 2>&1 | logger -t $(basename $0)[$$] &
  148. EOF
  149. [ ${DEBUG+x} ] && sed -ri '2 s/^#(set -x)/\1/' $SCRIPT2
  150. sed -i "s:\$CONFIG:$CONFIG:g" $SCRIPT2
  151. chmod +x $SCRIPT2
  152. echo "installed: $SCRIPT2"
  153. # --------------------- end merlin-wol-port-forward.init --------------------- #
  154.  
  155. # ----------------------------- begin nat-start ------------------------------ #
  156. create_script() {
  157. cat << 'EOF' > $SCRIPT3
  158. #!/bin/sh
  159. #set -x # comment/uncomment to disable/enable debug mode
  160. {
  161. $SCRIPT1
  162. } 2>&1 | logger -t $(basename $0)[$$]
  163. EOF
  164. [ ${DEBUG+x} ] && sed -ri '2 s/^#(set -x)/\1/' $SCRIPT3
  165. sed -i "s:\$SCRIPT1:$SCRIPT1:g" $SCRIPT3
  166. chmod +x $SCRIPT3
  167. }
  168.  
  169. if [ -f $SCRIPT3 ]; then
  170.     echo "error: $SCRIPT3 already exists; requires manual installation"
  171. else
  172.     create_script
  173.     echo "installed: $SCRIPT3"
  174. fi
  175. # ------------------------------ end nat-start ------------------------------- #
  176.  
  177. # ----------------------------- begin init-start ----------------------------- #
  178. create_script() {
  179. cat << 'EOF' > $SCRIPT4
  180. #!/bin/sh
  181. #set -x # comment/uncomment to disable/enable debug mode
  182. {
  183. $SCRIPT2
  184. } 2>&1 | logger -t $(basename $0)[$$]
  185. EOF
  186. [ ${DEBUG+x} ] && sed -ri '2 s/^#(set -x)/\1/' $SCRIPT4
  187. sed -i "s:\$SCRIPT2:$SCRIPT2:g" $SCRIPT4
  188. chmod +x $SCRIPT4
  189. }
  190.  
  191. if [ -f $SCRIPT4 ]; then
  192.     echo "error: $SCRIPT4 already exists; requires manual installation"
  193. else
  194.     create_script
  195.     echo "installed: $SCRIPT4"
  196. fi
  197. # ------------------------------ end init-start ------------------------------ #
Add Comment
Please, Sign In to add comment