2026-02-23 20:17:52 +07:00

528 lines
15 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# ABOUT softether vpn for zabbix
# author mikedmorto 2026 year
export LC_ALL=""
export LANG="en_US.UTF-8"
version="3.3"
. /etc/zabbix/scripts/sevpn3.cfg
JSON=""
##### PARAMETERS#####
METRIC="$1"
ITEM="$2"
API_URL="https://${URL}/api/"
CURL_OPTS="-s -k"
[ "$API_INSECURE" = "1" ] && CURL_OPTS="$CURL_OPTS -k"
api_call() {
local method=$1
local params=$2
[ -z "$params" ] && params="{}"
local id="1"
local data=$(cat <<EOF
{
"jsonrpc": "2.0",
"id": "$id",
"method": "$method",
"params": $params
}
EOF
)
curl $CURL_OPTS -X POST "$API_URL" \
-H "X-VPNADMIN-HUBNAME: " \
-H "X-VPNADMIN-PASSWORD: $PWD" \
-H "Content-Type: application/json" \
-d "$data" 2>/dev/null
}
case "$METRIC" in
discovery)
hubs_json=$(api_call "EnumHub")
# ... проверка ошибок
hubs=$(echo "$hubs_json" | jq -r '.result.HubList[].HubName_str' 2>/dev/null)
JSON='{"data":['
first_hub=1
for hub in $hubs; do
# Добавляем сам хаб
if [ $first_hub -eq 1 ]; then first_hub=0; else JSON="${JSON},"; fi
JSON="${JSON}{\"{#HUB_NAME}\":\"$hub\"}"
# Пользователи хаба
users_json=$(api_call "EnumUser" "{\"HubName_str\":\"$hub\"}")
if ! echo "$users_json" | jq -e '.error' >/dev/null 2>&1; then
users=$(echo "$users_json" | jq -r '.result.UserList[].Name_str' 2>/dev/null)
for user in $users; do
JSON="${JSON},{\"{#HUB_USER_NAME}\":\"$hub,$user\"}"
done
fi
# Каскады хаба
links_json=$(api_call "EnumLink" "{\"HubName_str\":\"$hub\"}")
if ! echo "$links_json" | jq -e '.error' >/dev/null 2>&1; then
links=$(echo "$links_json" | jq -r '.result.LinkList[].AccountName_utf' 2>/dev/null)
for link in $links; do
JSON="${JSON},{\"{#HUB_CASCADE_NAME}\":\"$hub,$link\"}"
done
fi
done
# --- Локальные мосты (один раз после цикла по хабам) ---
bridges_json=$(api_call "EnumLocalBridge")
if ! echo "$bridges_json" | jq -e '.error' >/dev/null 2>&1; then
while IFS= read -r bridge_entry; do
# bridge_entry имеет формат "hub,device"
JSON="${JSON},{\"{#HUB_BRIDGE_NAME}\":\"$bridge_entry\"}"
done < <(echo "$bridges_json" | jq -r '.result.LocalBridgeList[] | "\(.HubNameLB_str),\(.DeviceName_str)"' 2>/dev/null)
fi
JSON="${JSON}]}"
echo "$JSON"
;;
script.version)
echo ${version}
;;
srv.uptime)
resp=$(api_call "GetServerStatus")
# Проверка на ошибку API
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
# Извлекаем дату запуска из поля StartTime_dt
start_date_iso=$(echo "$resp" | jq -r '.result.StartTime_dt' 2>/dev/null)
if [ -z "$start_date_iso" ] || [ "$start_date_iso" = "null" ]; then
echo 0
exit 1
fi
# Преобразуем ISO8601 в timestamp
start_ts=$(date -d "$start_date_iso" +%s 2>/dev/null)
if [ -z "$start_ts" ]; then
echo 0
exit 1
fi
now=$(date +%s)
uptime=$((now - start_ts))
echo "$uptime"
;;
srv.number_of_users)
resp=$(api_call "GetServerStatus")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
# Извлекаем количество пользователей (поле Users)
users=$(echo "$resp" | jq -r '.result.NumUsers_u32' 2>/dev/null)
# Если поле отсутствует или null, выводим 0
if [ -z "$users" ] || [ "$users" = "null" ]; then
echo 0
else
echo "$users"
fi
;;
srv.number_of_ip_address_tables)
resp=$(api_call "GetServerStatus")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
echo "$resp" | jq -r '.result.NumIpTables_u32' 2>/dev/null || echo 0
;;
srv.number_of_mac_address_tables)
resp=$(api_call "GetServerStatus")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
echo "$resp" | jq -r '.result.NumMacTables_u32' 2>/dev/null || echo 0
;;
srv.number_of_sessions)
resp=$(api_call "GetServerStatus")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
echo "$resp" | jq -r '.result.NumSessionsTotal_u32' 2>/dev/null || echo 0
;;
srv.number_of_virtual_hubs)
resp=$(api_call "GetServerStatus")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
echo "$resp" | jq -r '.result.NumHubTotal_u32' 2>/dev/null || echo 0
;;
srv.number_of_active_sockets)
resp=$(api_call "GetServerStatus")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
echo "$resp" | jq -r '.result.NumTcpConnections_u32' 2>/dev/null || echo 0
;;
srv.l2tp_status)
echo `$VCMD /SERVER ${URL} /PASSWORD:${PWD} /CMD IPsecGet | grep "L2TP over IPsec Server Function Enabled" | awk -F"|" '{print $2}'`
;;
srv.openvpn_status)
echo `$VCMD /SERVER ${URL} /PASSWORD:${PWD} /CMD openvpnget | grep "OpenVPN Clone Server Enabled" | awk -F"|" '{print $2}'`
;;
srv.version)
resp=$(api_call "GetServerInfo")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
$VCMD /SERVER ${URL} /PASSWORD:${PWD} /CMD ServerStatusGet | awk 'FNR==3'
else
version=$(echo "$resp" | jq -r '.result.ServerVersionString_str' 2>/dev/null)
[ -n "$version" ] && [ "$version" != "null" ] && echo "$version" || $VCMD /SERVER ${URL} /PASSWORD:${PWD} /CMD ServerStatusGet | awk 'FNR==3'
fi
;;
# hub.if.out.broad
hub.if.out.broad)
resp=$(api_call "GetHubStatus" "{\"HubName_str\":\"$ITEM\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
val=$(echo "$resp" | jq -r '.result."Send.BroadcastBytes_u64"' 2>/dev/null)
if [ -z "$val" ] || [ "$val" = "null" ]; then
echo 0
else
echo "$val"
fi
;;
# hub.if.in.broad
hub.if.in.broad)
resp=$(api_call "GetHubStatus" "{\"HubName_str\":\"$ITEM\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
val=$(echo "$resp" | jq -r '.result."Recv.BroadcastBytes_u64"' 2>/dev/null)
if [ -z "$val" ] || [ "$val" = "null" ]; then
echo 0
else
echo "$val"
fi
;;
# hub.if.out.uni
hub.if.out.uni)
resp=$(api_call "GetHubStatus" "{\"HubName_str\":\"$ITEM\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
val=$(echo "$resp" | jq -r '.result."Send.UnicastBytes_u64"' 2>/dev/null)
if [ -z "$val" ] || [ "$val" = "null" ]; then
echo 0
else
echo "$val"
fi
;;
# hub.if.in.uni
hub.if.in.uni)
resp=$(api_call "GetHubStatus" "{\"HubName_str\":\"$ITEM\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
val=$(echo "$resp" | jq -r '.result."Recv.UnicastBytes_u64"' 2>/dev/null)
if [ -z "$val" ] || [ "$val" = "null" ]; then
echo 0
else
echo "$val"
fi
;;
# hub.sessions-bridge
hub.sessions-bridge)
resp=$(api_call "GetHubStatus" "{\"HubName_str\":\"$ITEM\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
val=$(echo "$resp" | jq -r '.result.NumSessionsBridge_u32' 2>/dev/null)
if [ -z "$val" ] || [ "$val" = "null" ]; then
echo 0
else
echo "$val"
fi
;;
# hub.sessions-client
hub.sessions-client)
resp=$(api_call "GetHubStatus" "{\"HubName_str\":\"$ITEM\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
val=$(echo "$resp" | jq -r '.result.NumSessionsClient_u32' 2>/dev/null)
if [ -z "$val" ] || [ "$val" = "null" ]; then
echo 0
else
echo "$val"
fi
;;
# hub.sessions-all
hub.sessions-all)
resp=$(api_call "GetHubStatus" "{\"HubName_str\":\"$ITEM\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
val=$(echo "$resp" | jq -r '.result.NumSessions_u32' 2>/dev/null)
if [ -z "$val" ] || [ "$val" = "null" ]; then
echo 0
else
echo "$val"
fi
;;
# hub.securenat
hub.securenat)
resp=$(api_call "GetHubStatus" "{\"HubName_str\":\"$ITEM\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo "false"
exit 1
fi
val=$(echo "$resp" | jq -r '.result.SecureNATEnabled_bool' 2>/dev/null)
if [ -z "$val" ] || [ "$val" = "null" ]; then
echo "false"
else
# Приводим к строке true/false (Zabbix ожидает строку)
echo "$val"
fi
;;
# hub.type
hub.type)
resp=$(api_call "GetHubStatus" "{\"HubName_str\":\"$ITEM\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
echo 0
exit 1
fi
val=$(echo "$resp" | jq -r '.result.HubType_u32' 2>/dev/null)
if [ -z "$val" ] || [ "$val" = "null" ]; then
echo 0
else
echo "$val"
fi
;;
cas.status)
HUB=${ITEM%,*}
CAS=${ITEM##*,}
resp=$(api_call "GetLinkStatus" "{\"HubName_Ex_str\":\"$HUB\",\"AccountName_utf\":\"$CAS\"}")
status=$(echo "$resp" | jq -r '.result.Connected_bool' 2>/dev/null)
if [ "$status" = "true" ]; then
echo "Connection Completed (Session Established)"
else
echo "offline"
fi
;;
cas.if.out.broad)
HUB=${ITEM%,*}
CAS=${ITEM##*,}
resp=$(api_call "GetLinkStatus" "{\"HubName_Ex_str\":\"$HUB\",\"AccountName_utf\":\"$CAS\"}")
val=$(echo "$resp" | jq -r '.result."Send.BroadcastBytes_u64"' 2>/dev/null)
echo "${val:-0}"
;;
cas.if.in.broad)
HUB=${ITEM%,*}
CAS=${ITEM##*,}
resp=$(api_call "GetLinkStatus" "{\"HubName_Ex_str\":\"$HUB\",\"AccountName_utf\":\"$CAS\"}")
val=$(echo "$resp" | jq -r '.result."Recv.BroadcastBytes_u64"' 2>/dev/null)
echo "${val:-0}"
;;
cas.if.out)
HUB=${ITEM%,*}
CAS=${ITEM##*,}
resp=$(api_call "GetLinkStatus" "{\"HubName_Ex_str\":\"$HUB\",\"AccountName_utf\":\"$CAS\"}")
val=$(echo "$resp" | jq -r '.result.TotalSendSize_u64' 2>/dev/null)
echo "${val:-0}"
;;
cas.if.in)
HUB=${ITEM%,*}
CAS=${ITEM##*,}
resp=$(api_call "GetLinkStatus" "{\"HubName_Ex_str\":\"$HUB\",\"AccountName_utf\":\"$CAS\"}")
val=$(echo "$resp" | jq -r '.result.TotalRecvSize_u64' 2>/dev/null)
echo "${val:-0}"
;;
cas.if.out.uni)
HUB=${ITEM%,*}
CAS=${ITEM##*,}
resp=$(api_call "GetLinkStatus" "{\"HubName_Ex_str\":\"$HUB\",\"AccountName_utf\":\"$CAS\"}")
val=$(echo "$resp" | jq -r '.result."Send.UnicastBytes_u64"' 2>/dev/null)
echo "${val:-0}"
;;
cas.if.in.uni)
HUB=${ITEM%,*}
CAS=${ITEM##*,}
resp=$(api_call "GetLinkStatus" "{\"HubName_Ex_str\":\"$HUB\",\"AccountName_utf\":\"$CAS\"}")
val=$(echo "$resp" | jq -r '.result."Recv.UnicastBytes_u64"' 2>/dev/null)
echo "${val:-0}"
;;
br.status)
HUB=${ITEM%,*}
BR=${ITEM##*,}
resp=$(api_call "EnumLocalBridge")
online=$(echo "$resp" | jq -r --arg hub "$HUB" --arg br "$BR" '.result.LocalBridgeList[] | select(.HubNameLB_str == $hub and .DeviceName_str == $br) | .Online_bool' 2>/dev/null | head -1)
if [ "$online" = "true" ]; then
echo "Operating"
else
echo "false"
fi
;;
usr.if.out.broad)
HUB=${ITEM%,*}
USER=${ITEM##*,}
resp=$(api_call "GetUser" "{\"HubName_str\":\"$HUB\",\"Name_str\":\"$USER\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
$VCMD /SERVER ${URL} /PASSWORD:${PWD} /adminhub:${HUB} /CMD UserGet ${USER} | grep "Outgoing Broadcast Total Size" | sed -e 's/[^0-9]//g'
else
val=$(echo "$resp" | jq -r '.result."Send.BroadcastBytes_u64"' 2>/dev/null)
echo "${val:-0}"
fi
;;
# usr.if.in.broad
usr.if.in.broad)
HUB=${ITEM%,*}
USER=${ITEM##*,}
resp=$(api_call "GetUser" "{\"HubName_str\":\"$HUB\",\"Name_str\":\"$USER\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
$VCMD /SERVER ${URL} /PASSWORD:${PWD} /adminhub:${HUB} /CMD UserGet ${USER} | grep "Incoming Broadcast Total Size" | sed -e 's/[^0-9]//g'
else
val=$(echo "$resp" | jq -r '.result."Recv.BroadcastBytes_u64"' 2>/dev/null)
echo "${val:-0}"
fi
;;
# usr.if.out.uni
usr.if.out.uni)
HUB=${ITEM%,*}
USER=${ITEM##*,}
resp=$(api_call "GetUser" "{\"HubName_str\":\"$HUB\",\"Name_str\":\"$USER\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
$VCMD /SERVER ${URL} /PASSWORD:${PWD} /adminhub:${HUB} /CMD UserGet ${USER} | grep "Outgoing Unicast Total Size" | sed -e 's/[^0-9]//g'
else
val=$(echo "$resp" | jq -r '.result."Send.UnicastBytes_u64"' 2>/dev/null)
echo "${val:-0}"
fi
;;
# usr.if.in.uni
usr.if.in.uni)
HUB=${ITEM%,*}
USER=${ITEM##*,}
resp=$(api_call "GetUser" "{\"HubName_str\":\"$HUB\",\"Name_str\":\"$USER\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
$VCMD /SERVER ${URL} /PASSWORD:${PWD} /adminhub:${HUB} /CMD UserGet ${USER} | grep "Incoming Unicast Total Size" | sed -e 's/[^0-9]//g'
else
val=$(echo "$resp" | jq -r '.result."Recv.UnicastBytes_u64"' 2>/dev/null)
echo "${val:-0}"
fi
;;
# usr.lastlogin
usr.lastlogin)
HUB=${ITEM%,*}
USER=${ITEM##*,}
resp=$(api_call "GetUser" "{\"HubName_str\":\"$HUB\",\"Name_str\":\"$USER\"}")
if echo "$resp" | jq -e '.error' >/dev/null 2>&1; then
$VCMD /SERVER ${URL} /adminhub:"$HUB" /PASSWORD:"${PWD}" /CMD UserGet "${USER}" | grep "Updated on" | awk -F"|" '{print $2}'
else
updated=$(echo "$resp" | jq -r '.result.UpdatedTime_dt' 2>/dev/null)
if [ -n "$updated" ] && [ "$updated" != "null" ]; then
# Преобразуем ISO дату в timestamp
ts=$(date -d "$updated" +%s 2>/dev/null)
echo "${ts:-0}"
else
echo 0
fi
fi
;;
help)
echo "please use these params
{
discovery
srv.uptime
srv.number_of_users
srv.number_of_ip_address_tables
srv.number_of_mac_address_tables
srv.number_of_sessions
srv.number_of_virtual_hubs
srv.number_of_active_sockets
srv.l2tp_status
srv.openvpn_status
srv.version
hub.if.out.broad
hub.if.in.broad
hub.if.out.uni
hub.if.in.uni
hub.sessions-bridge
hub.sessions-client
hub.sessions-all
hub.securenat
hub.type
cas.status
cas.if.in.broad
cas.if.out.broad
cas.if.out
cas.if.in
cas.if.in.uni
cas.if.out.uni
br.status
usr.lastlogin
usr.if.out.broad
usr.if.in.broad
usr.if.in.uni
usr.if.out.uni
script.version
}"
;;
*)
echo ""
;;
esac