|
#!/bin/sh
|
|
# vpn switch for travelmate
|
|
# Copyright (c) 2020-2021 Dirk Brenken (dev@brenken.org)
|
|
# This is free software, licensed under the GNU General Public License v3.
|
|
|
|
# set (s)hellcheck exceptions
|
|
# shellcheck disable=1091,3040,3043
|
|
|
|
# Please note: you have to setup the package 'wireguard' or 'openvpn' before using this script
|
|
|
|
export LC_ALL=C
|
|
export PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
|
set -o pipefail
|
|
|
|
# source function library if necessary
|
|
#
|
|
if [ -z "${_C}" ]; then
|
|
. "/lib/functions.sh"
|
|
fi
|
|
|
|
vpn_action="${1}"
|
|
trm_vpnservice="$(uci_get travelmate global trm_vpnservice)"
|
|
trm_vpniface="$(uci_get travelmate global trm_vpniface)"
|
|
trm_landevice="$(uci_get travelmate global trm_landevice)"
|
|
trm_maxwait="$(uci_get travelmate global trm_maxwait "30")"
|
|
trm_captiveurl="$(uci_get travelmate global trm_captiveurl "http://detectportal.firefox.com")"
|
|
trm_useragent="$(uci_get travelmate global trm_useragent "Mozilla/5.0 (Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0")"
|
|
trm_iptrule_accept="FORWARD -i ${trm_landevice} -p tcp --match multiport --dports 80,443 -j ACCEPT"
|
|
trm_iptrule_drop="FORWARD -i ${trm_landevice} -j DROP"
|
|
trm_iptables="$(command -v iptables)"
|
|
trm_logger="$(command -v logger)"
|
|
trm_fetch="$(command -v curl)"
|
|
|
|
f_net()
|
|
{
|
|
local IFS json_rc result="net nok"
|
|
|
|
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}")"
|
|
if [ "${json_rc}" = "200" ] || [ "${json_rc}" = "204" ]; then
|
|
result="net ok"
|
|
fi
|
|
printf "%s" "${result}"
|
|
}
|
|
|
|
if [ -n "${trm_vpnservice}" ] && [ -n "${trm_vpniface}" ] && [ -n "${trm_landevice}" ] && [ -f "/tmp/trm_runtime.json" ]; then
|
|
status="$(jsonfilter -i "/tmp/trm_runtime.json" -l1 -e '@.data.travelmate_status' 2>/dev/null)"
|
|
vpn_status="$(ubus -S call network.interface."${trm_vpniface}" status 2>/dev/null | jsonfilter -l1 -e '@.up')"
|
|
if [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]; then
|
|
if [ -n "$("${trm_iptables}" "-w $((trm_maxwait / 6))" -C "${trm_iptrule_drop}" 2>&1)" ] &&
|
|
[ -n "$("${trm_iptables}" "-w $((trm_maxwait / 6))" -C "${trm_iptrule_accept}" 2>&1)" ]; then
|
|
"${trm_iptables}" "-w $((trm_maxwait / 6))" -I "${trm_iptrule_drop}" 2>&1
|
|
"${trm_logger}" -p "info" -t "trm-vpn [${$}]" "lan forward blocked for device '${trm_landevice}'" 2>/dev/null
|
|
fi
|
|
fi
|
|
if [ "${vpn_action}" = "disable" ] && [ "${status%% (net cp *}" = "connected" ]; then
|
|
if [ -n "$("${trm_iptables}" "-w $((trm_maxwait / 6))" -C "${trm_iptrule_accept}" 2>&1)" ] &&
|
|
[ -z "$("${trm_iptables}" "-w $((trm_maxwait / 6))" -C "${trm_iptrule_drop}" 2>&1)" ]; then
|
|
"${trm_iptables}" "-w $((trm_maxwait / 6))" -I "${trm_iptrule_accept}" 2>&1
|
|
"${trm_logger}" -p "info" -t "trm-vpn [${$}]" "lan forward on ports 80/443 freed for device '${trm_landevice}'" 2>/dev/null
|
|
fi
|
|
fi
|
|
|
|
case "${trm_vpnservice}" in
|
|
"wireguard")
|
|
if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]; then
|
|
ubus call network.interface."${trm_vpniface}" up
|
|
elif [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]; then
|
|
ubus call network.interface."${trm_vpniface}" down
|
|
"${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${trm_vpnservice} client connection disabled" 2>/dev/null
|
|
fi
|
|
;;
|
|
"openvpn")
|
|
if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]; then
|
|
ubus call network.interface."${trm_vpniface}" up
|
|
/etc/init.d/openvpn restart >/dev/null 2>&1
|
|
elif [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]; then
|
|
ubus call network.interface."${trm_vpniface}" down
|
|
/etc/init.d/openvpn stop >/dev/null 2>&1
|
|
"${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${trm_vpnservice} client connection disabled" 2>/dev/null
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" != "true" ]; then
|
|
cnt=0
|
|
while true; do
|
|
vpn_status="$(ubus -S call network.interface."${trm_vpniface}" status 2>/dev/null | jsonfilter -l1 -e '@.up')"
|
|
if [ "${vpn_status}" = "true" ]; then
|
|
net_status="$(f_net)"
|
|
if [ "${net_status}" = "net ok" ]; then
|
|
"${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${trm_vpnservice} client connection enabled" 2>/dev/null
|
|
if [ -z "$("${trm_iptables}" "-w $((trm_maxwait / 6))" -C "${trm_iptrule_drop}" 2>&1)" ]; then
|
|
"${trm_iptables}" "-w $((trm_maxwait / 6))" -D "${trm_iptrule_drop}" 2>&1
|
|
if [ -z "$("${trm_iptables}" "-w $((trm_maxwait / 6))" -C "${trm_iptrule_accept}" 2>&1)" ]; then
|
|
"${trm_iptables}" "-w $((trm_maxwait / 6))" -D "${trm_iptrule_accept}" 2>&1
|
|
fi
|
|
"${trm_logger}" -p "info" -t "trm-vpn [${$}]" "lan forward freed for device '${trm_landevice}'" 2>/dev/null
|
|
fi
|
|
break
|
|
fi
|
|
fi
|
|
if [ "${cnt}" -ge "$((trm_maxwait / 6))" ]; then
|
|
"${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${trm_vpnservice} restart failed, lan forward for device '${trm_landevice}' still blocked" 2>/dev/null
|
|
ubus call network.interface."${trm_vpniface}" down
|
|
exit 2
|
|
fi
|
|
sleep 1
|
|
cnt="$((cnt + 1))"
|
|
done
|
|
fi
|
|
if [ "${vpn_action}" = "enable" ] && [ "${vpn_status}" = "true" ]; then
|
|
if [ -f "/etc/init.d/sysntpd" ]; then
|
|
/etc/init.d/sysntpd restart >/dev/null 2>&1
|
|
fi
|
|
fi
|
|
exit 0
|
|
fi
|
|
exit 1
|