You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
5.2 KiB

  1. #!/bin/sh
  2. # vpn switch for travelmate
  3. # Copyright (c) 2020 Dirk Brenken (dev@brenken.org)
  4. # This is free software, licensed under the GNU General Public License v3.
  5. # set (s)hellcheck exceptions
  6. # shellcheck disable=1091,2016,2039,2059,2086,2143,2181,2188
  7. # Please note: you have to setup the package 'wireguard' or 'openvpn' before using this script
  8. export LC_ALL=C
  9. export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
  10. set -o pipefail
  11. if [ "$(uci_get 2>/dev/null; printf "%u" "${?}")" = "127" ]
  12. then
  13. . "/lib/functions.sh"
  14. fi
  15. vpn_action="${1}"
  16. trm_vpnservice="$(uci_get travelmate global trm_vpnservice)"
  17. trm_vpniface="$(uci_get travelmate global trm_vpniface)"
  18. trm_landevice="$(uci_get travelmate global trm_landevice)"
  19. trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
  20. trm_captiveurl="$(uci_get travelmate global trm_captiveurl "http://captive.apple.com")"
  21. trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0")"
  22. trm_iptrule_accept="FORWARD -i ${trm_landevice} -p tcp --match multiport --dports 80,443 -j ACCEPT"
  23. trm_iptrule_drop="FORWARD -i ${trm_landevice} -j DROP"
  24. trm_iptables="$(command -v iptables)"
  25. trm_logger="$(command -v logger)"
  26. trm_fetch="$(command -v curl)"
  27. f_log()
  28. {
  29. local class="${1}" log_msg="${2}"
  30. if [ -x "${trm_logger}" ]
  31. then
  32. "${trm_logger}" -p "${class}" -t "trm-vpn [${$}]" "${log_msg}"
  33. else
  34. printf "%s %s %s\\n" "${class}" "trm-vpn [${$}]" "${log_msg}"
  35. fi
  36. }
  37. f_net()
  38. {
  39. local IFS json_raw json_rc result="net nok"
  40. json_raw="$(${trm_fetch} --user-agent "${trm_useragent}" --referer "http://www.example.com" --write-out "%{json}" --silent --show-error --connect-timeout $((trm_maxwait/10)) "${trm_captiveurl}" 2>/dev/null)"
  41. json_raw="${json_raw#*\{}"
  42. if [ -n "${json_raw}" ]
  43. then
  44. json_rc="$(printf "%s" "{${json_raw}" | jsonfilter -l1 -e '@.response_code' 2>/dev/null)"
  45. if [ "${json_rc}" = "200" ] || [ "${json_rc}" = "204" ]
  46. then
  47. result="net ok"
  48. fi
  49. fi
  50. printf "%s" "${result}"
  51. }
  52. if [ -n "${trm_vpnservice}" ] && [ -n "${trm_vpniface}" ] && [ -n "${trm_landevice}" ] && [ -f "/tmp/trm_runtime.json" ]
  53. then
  54. status="$(jsonfilter -i "/tmp/trm_runtime.json" -l1 -e '@.data.travelmate_status' 2>/dev/null)"
  55. vpn_status="$(ubus -S call network.interface."${trm_vpniface}" status 2>/dev/null | jsonfilter -l1 -e '@.up')"
  56. if [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]
  57. then
  58. if [ -n "$("${trm_iptables}" "-w $((trm_maxwait/6))" -C ${trm_iptrule_drop} 2>&1)" ] && \
  59. [ -n "$("${trm_iptables}" "-w $((trm_maxwait/6))" -C ${trm_iptrule_accept} 2>&1)" ]
  60. then
  61. "${trm_iptables}" "-w $((trm_maxwait/6))" -I ${trm_iptrule_drop} 2>&1
  62. f_log "info" "lan forward blocked for device '${trm_landevice}'"
  63. fi
  64. fi
  65. if [ "${vpn_action}" = "disable" ] && [ "${status%% (net cp *}" = "connected" ]
  66. then
  67. if [ -n "$("${trm_iptables}" "-w $((trm_maxwait/6))" -C ${trm_iptrule_accept} 2>&1)" ] && \
  68. [ -z "$("${trm_iptables}" "-w $((trm_maxwait/6))" -C ${trm_iptrule_drop} 2>&1)" ]
  69. then
  70. "${trm_iptables}" "-w $((trm_maxwait/6))" -I ${trm_iptrule_accept} 2>&1
  71. f_log "info" "lan forward on ports 80/443 freed for device '${trm_landevice}'"
  72. fi
  73. fi
  74. case "${trm_vpnservice}" in
  75. "wireguard")
  76. if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]
  77. then
  78. ubus call network.interface."${trm_vpniface}" up
  79. elif [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]
  80. then
  81. ubus call network.interface."${trm_vpniface}" down
  82. f_log "info" "${trm_vpnservice} client connection disabled"
  83. fi
  84. ;;
  85. "openvpn")
  86. if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]
  87. then
  88. ubus call network.interface."${trm_vpniface}" up
  89. /etc/init.d/openvpn restart >/dev/null 2>&1
  90. elif [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]
  91. then
  92. ubus call network.interface."${trm_vpniface}" down
  93. /etc/init.d/openvpn stop >/dev/null 2>&1
  94. f_log "info" "${trm_vpnservice} client connection disabled"
  95. fi
  96. ;;
  97. esac
  98. if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]
  99. then
  100. cnt=0
  101. while true
  102. do
  103. vpn_status="$(ubus -S call network.interface."${trm_vpniface}" status 2>/dev/null | jsonfilter -l1 -e '@.up')"
  104. if [ "${vpn_status}" = "true" ]
  105. then
  106. net_status="$(f_net)"
  107. if [ "${net_status}" = "net ok" ]
  108. then
  109. f_log "info" "${trm_vpnservice} client connection enabled"
  110. if [ -z "$("${trm_iptables}" "-w $((trm_maxwait/6))" -C ${trm_iptrule_drop} 2>&1)" ]
  111. then
  112. "${trm_iptables}" "-w $((trm_maxwait/6))" -D ${trm_iptrule_drop} 2>&1
  113. if [ -z "$("${trm_iptables}" "-w $((trm_maxwait/6))" -C ${trm_iptrule_accept} 2>&1)" ]
  114. then
  115. "${trm_iptables}" "-w $((trm_maxwait/6))" -D ${trm_iptrule_accept} 2>&1
  116. fi
  117. f_log "info" "lan forward freed for device '${trm_landevice}'"
  118. fi
  119. break
  120. fi
  121. fi
  122. if [ "${cnt}" -ge "$((trm_maxwait/6))" ]
  123. then
  124. f_log "info" "${trm_vpnservice} restart failed, lan forward for device '${trm_landevice}' still blocked"
  125. ubus call network.interface."${trm_vpniface}" down
  126. exit 2
  127. fi
  128. sleep 1
  129. cnt="$((cnt+1))"
  130. done
  131. fi
  132. if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" = "true" ]
  133. then
  134. if [ -f "/etc/init.d/sysntpd" ]
  135. then
  136. /etc/init.d/sysntpd restart >/dev/null 2>&1
  137. fi
  138. fi
  139. exit 0
  140. fi
  141. exit 1