528 lines
15 KiB
Bash
Executable File
528 lines
15 KiB
Bash
Executable File
#!/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
|
||
|
||
|