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.

118 lines
5.3 KiB

  1. #!/bin/sh
  2. # vpn switch for travelmate
  3. # Copyright (c) 2020-2021 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,3040,3043
  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. # source function library if necessary
  12. #
  13. if [ -z "${_C}" ]; then
  14. . "/lib/functions.sh"
  15. fi
  16. vpn_action="${1}"
  17. trm_vpnservice="$(uci_get travelmate global trm_vpnservice)"
  18. trm_vpniface="$(uci_get travelmate global trm_vpniface)"
  19. trm_landevice="$(uci_get travelmate global trm_landevice)"
  20. trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
  21. trm_captiveurl="$(uci_get travelmate global trm_captiveurl "http://detectportal.firefox.com")"
  22. trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
  23. trm_iptrule_accept="FORWARD -i ${trm_landevice} -p tcp --match multiport --dports 80,443 -j ACCEPT"
  24. trm_iptrule_drop="FORWARD -i ${trm_landevice} -j DROP"
  25. trm_iptables="$(command -v iptables)"
  26. trm_logger="$(command -v logger)"
  27. trm_fetch="$(command -v curl)"
  28. f_net()
  29. {
  30. local IFS json_rc result="net nok"
  31. json_rc="$(${trm_fetch} --user-agent "${trm_useragent}" --referer "http://www.example.com" --connect-timeout $((trm_maxwait / 10)) --header "Cache-Control: no-cache, no-store, must-revalidate" --header "Pragma: no-cache" --header "Expires: 0" --write-out "%{response_code}" --silent --show-error --output /dev/null "${trm_captiveurl}")"
  32. if [ "${json_rc}" = "200" ] || [ "${json_rc}" = "204" ]; then
  33. result="net ok"
  34. fi
  35. printf "%s" "${result}"
  36. }
  37. if [ -n "${trm_vpnservice}" ] && [ -n "${trm_vpniface}" ] && [ -n "${trm_landevice}" ] && [ -f "/tmp/trm_runtime.json" ]; then
  38. status="$(jsonfilter -i "/tmp/trm_runtime.json" -l1 -e '@.data.travelmate_status' 2>/dev/null)"
  39. vpn_status="$(ubus -S call network.interface."${trm_vpniface}" status 2>/dev/null | jsonfilter -l1 -e '@.up')"
  40. if [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]; then
  41. if [ -n "$("${trm_iptables}" "-w $((trm_maxwait / 6))" -C "${trm_iptrule_drop}" 2>&1)" ] &&
  42. [ -n "$("${trm_iptables}" "-w $((trm_maxwait / 6))" -C "${trm_iptrule_accept}" 2>&1)" ]; then
  43. "${trm_iptables}" "-w $((trm_maxwait / 6))" -I "${trm_iptrule_drop}" 2>&1
  44. "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "lan forward blocked for device '${trm_landevice}'" 2>/dev/null
  45. fi
  46. fi
  47. if [ "${vpn_action}" = "disable" ] && [ "${status%% (net cp *}" = "connected" ]; then
  48. if [ -n "$("${trm_iptables}" "-w $((trm_maxwait / 6))" -C "${trm_iptrule_accept}" 2>&1)" ] &&
  49. [ -z "$("${trm_iptables}" "-w $((trm_maxwait / 6))" -C "${trm_iptrule_drop}" 2>&1)" ]; then
  50. "${trm_iptables}" "-w $((trm_maxwait / 6))" -I "${trm_iptrule_accept}" 2>&1
  51. "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "lan forward on ports 80/443 freed for device '${trm_landevice}'" 2>/dev/null
  52. fi
  53. fi
  54. case "${trm_vpnservice}" in
  55. "wireguard")
  56. if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]; then
  57. ubus call network.interface."${trm_vpniface}" up
  58. elif [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]; then
  59. ubus call network.interface."${trm_vpniface}" down
  60. "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${trm_vpnservice} client connection disabled" 2>/dev/null
  61. fi
  62. ;;
  63. "openvpn")
  64. if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]; then
  65. ubus call network.interface."${trm_vpniface}" up
  66. /etc/init.d/openvpn restart >/dev/null 2>&1
  67. elif [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]; then
  68. ubus call network.interface."${trm_vpniface}" down
  69. /etc/init.d/openvpn stop >/dev/null 2>&1
  70. "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${trm_vpnservice} client connection disabled" 2>/dev/null
  71. fi
  72. ;;
  73. esac
  74. if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]; then
  75. cnt=0
  76. while true; do
  77. vpn_status="$(ubus -S call network.interface."${trm_vpniface}" status 2>/dev/null | jsonfilter -l1 -e '@.up')"
  78. if [ "${vpn_status}" = "true" ]; then
  79. net_status="$(f_net)"
  80. if [ "${net_status}" = "net ok" ]; then
  81. "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${trm_vpnservice} client connection enabled" 2>/dev/null
  82. if [ -z "$("${trm_iptables}" "-w $((trm_maxwait / 6))" -C "${trm_iptrule_drop}" 2>&1)" ]; then
  83. "${trm_iptables}" "-w $((trm_maxwait / 6))" -D "${trm_iptrule_drop}" 2>&1
  84. if [ -z "$("${trm_iptables}" "-w $((trm_maxwait / 6))" -C "${trm_iptrule_accept}" 2>&1)" ]; then
  85. "${trm_iptables}" "-w $((trm_maxwait / 6))" -D "${trm_iptrule_accept}" 2>&1
  86. fi
  87. "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "lan forward freed for device '${trm_landevice}'" 2>/dev/null
  88. fi
  89. break
  90. fi
  91. fi
  92. if [ "${cnt}" -ge "$((trm_maxwait / 6))" ]; then
  93. "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${trm_vpnservice} restart failed, lan forward for device '${trm_landevice}' still blocked" 2>/dev/null
  94. ubus call network.interface."${trm_vpniface}" down
  95. exit 2
  96. fi
  97. sleep 1
  98. cnt="$((cnt + 1))"
  99. done
  100. fi
  101. if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" = "true" ]; then
  102. if [ -f "/etc/init.d/sysntpd" ]; then
  103. /etc/init.d/sysntpd restart >/dev/null 2>&1
  104. fi
  105. fi
  106. exit 0
  107. fi
  108. exit 1