#!/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="${1}" vpn_action="${2}" vpn_service="${3}" vpn_iface="${4}" 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_logger="$(command -v logger)" trm_fetch="$(command -v curl)" f_net() { local 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 --output /dev/null "${trm_captiveurl}")" if [ "${json_rc}" = "200" ] || [ "${json_rc}" = "204" ]; then result="net ok" fi printf "%s" "${result}" } vpn_status="$(ubus -S call network.interface."${vpn_iface}" status 2>/dev/null | jsonfilter -q -l1 -e '@.up')" case "${vpn_service}" in "wireguard") if [ "${vpn_action}" = "enable" ] && [ "${vpn_status:-"false"}" != "true" ]; then ubus call network.interface."${vpn_iface}" up fi if { [ "${vpn}" = "0" ] && [ "${vpn_action}" = "enable" ]; } || { [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]; }; then ubus call network.interface."${vpn_iface}" down "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${vpn_service} client connection disabled" 2>/dev/null fi ;; "openvpn") if [ "${vpn_action}" = "enable" ] && [ "${vpn_status:-"false"}" != "true" ]; then ubus call network.interface."${vpn_iface}" up /etc/init.d/openvpn restart >/dev/null 2>&1 fi if { [ "${vpn}" = "0" ] && [ "${vpn_action}" = "enable" ]; } || { [ "${vpn_action}" = "disable" ] && [ "${vpn_status}" = "true" ]; }; then ubus call network.interface."${vpn_iface}" down /etc/init.d/openvpn stop >/dev/null 2>&1 "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${vpn_service} client connection disabled" 2>/dev/null fi ;; esac if [ "${vpn}" = "1" ] && [ "${vpn_action}" = "enable" ] && [ "${vpn_status:-"false"}" != "true" ]; then cnt=0 while true; do vpn_status="$(ubus -S call network.interface."${vpn_iface}" status 2>/dev/null | jsonfilter -q -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 [${$}]" "${vpn_service} client connection enabled" 2>/dev/null break fi fi if [ "${cnt}" -ge "$((trm_maxwait / 6))" ]; then "${trm_logger}" -p "info" -t "trm-vpn [${$}]" "${vpn_service} client connection can't be established" 2>/dev/null ubus call network.interface."${vpn_iface}" down exit 1 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