1788 lines
99 KiB
Bash
Executable File
1788 lines
99 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# 读取设置文件
|
||
function get_config(){
|
||
while [[ "$*" != "" ]]; do
|
||
eval ${1}='`uci get wechatpush.config.$1`' 2>/dev/null
|
||
shift
|
||
done
|
||
}
|
||
|
||
# 后台读取 json 中的变量
|
||
read_json() {
|
||
local json_key="$1"
|
||
local json_path="$2"
|
||
local output_file="$output_dir/${json_key}"
|
||
jq -r ."$json_key" "$json_path" > "$output_file" &
|
||
}
|
||
|
||
# 遍历输出目录,将文件内容保存到对应的变量
|
||
wait_and_cat() {
|
||
[ $(ls -A "$output_dir" | wc -l) -eq 0 ] && return
|
||
wait
|
||
for file in "$output_dir"/*; do
|
||
local variable_name=$(basename "$file")
|
||
local variable_value=$(cat "$file")
|
||
eval "${variable_name}='${variable_value}'"
|
||
done
|
||
rm "$output_dir"/*
|
||
}
|
||
|
||
# 初始化设置信息
|
||
function read_config(){
|
||
get_config \
|
||
"enable" "lite_enable" "device_name" "sleeptime" "oui_data" "reset_regularly" "debuglevel" \
|
||
"jsonpath" "sckey" "corpid" "userid" "agentid" "corpsecret" "mediapath" "wxpusher_apptoken" "wxpusher_uids" "wxpusher_topicIds" "pushplus_token" "tg_token" "chat_id" \
|
||
"get_ipv4_mode" "ipv4_interface" "get_ipv6_mode" "ipv6_interface" "auto_update_ip_list" \
|
||
"device_notification" "cpu_notification" "cpu_load_threshold" "temperature_threshold" \
|
||
"client_usage" "client_usage_max" "client_usage_disturb" "client_usage_whitelist" \
|
||
"login_notification" "login_max_num" "login_web_black" "login_ip_black_timeout" "login_ip_white_list" "port_knocking_enable" "login_ip_white_timeout" "login_port_white" "login_port_forward_list" \
|
||
"crontab_regular_time" "crontab_interval_time" \
|
||
"do_not_disturb_mode" "do_not_disturb_starttime" "do_not_disturb_endtime" "up_down_push_whitelist" "up_down_push_blacklist" "up_down_push_interface" "mac_online_list" "mac_offline_list" "login_disturb" "login_notification_delay" "login_log_enable" \
|
||
"up_timeout" "down_timeout" "timeout_retry_count" "only_timeout_push" "passive_mode" "thread_num" "soc_code" "server_host" "server_port" \
|
||
"unattended_enable" "zerotier_helper" "unattended_only_on_disturb_time" "unattended_device_aliases" "network_disconnect_event" "unattended_autoreboot_mode" "autoreboot_system_uptime" "autoreboot_network_uptime" \
|
||
"device_info_helper" "gateway_host_url" "gateway_info_url" "gateway_logout_url" "gateway_username_id" "gateway_password_id" "gateway_username" "gateway_password" "scan_ip_range" "device_info_helper_sleeptime"
|
||
|
||
( echo "$device_notification"|grep -q "online" ) && notification_online="true"
|
||
( echo "$device_notification"|grep -q "offline" ) && notification_offline="true"
|
||
( echo "$cpu_notification"|grep -q "load" ) && notification_load="true"
|
||
( echo "$cpu_notification"|grep -q "temp" ) && notification_temp="true"
|
||
( echo "$login_notification"|grep -q "web_logged" ) && web_logged="true"
|
||
( echo "$login_notification"|grep -q "ssh_logged" ) && ssh_logged="true"
|
||
( echo "$login_notification"|grep -q "web_login_failed" ) && web_login_failed="true"
|
||
( echo "$login_notification"|grep -q "ssh_login_failed" ) && ssh_login_failed="true"
|
||
( echo "$device_info_helper"|grep -q "gateway_info" ) && gateway_info_enable="true"
|
||
for str_version in "wrtbwmon" "iputils-arping" "curl" "iw"; do
|
||
eval `echo ${str_version:0:2}"_version"`=`opkg list-installed|grep -w ^${str_version}|awk '{print $3}'` 2>/dev/null
|
||
done
|
||
( opkg list-installed|grep -w -q ^firewall4 ) && nftables_version="true"
|
||
dir="/tmp/wechatpush/" && mkdir -p ${dir} && mkdir -p ${dir}/client
|
||
tempjsonpath="${dir}temp.json"
|
||
ip_blacklist_path="/usr/share/wechatpush/api/ip_blacklist"
|
||
oui_base="${dir}oui_base.txt"
|
||
debuglevel=`echo "$debuglevel"` && [ -z "$debuglevel" ] && logfile="/dev/null" || logfile="${dir}wechatpush.log"
|
||
login_port_forward_list=`echo "$login_port_forward_list"|sed 's/ /\n/g'` 2>/dev/null
|
||
up_down_push_blacklist=`echo "$up_down_push_blacklist"|sed 's/ /\n/g'` 2>/dev/null
|
||
up_down_push_whitelist=`echo "$up_down_push_whitelist"|sed 's/ /\n/g'` 2>/dev/null
|
||
device_aliases=`cat /usr/share/wechatpush/api/device_aliases.list` 2>/dev/null
|
||
unattended_device_aliases=`echo "$unattended_device_aliases"|sed 's/ /\n/g'` 2>/dev/null
|
||
client_usage_whitelist=`echo "$client_usage_whitelist"|sed 's/ /\n/g'` 2>/dev/null
|
||
login_ip_white_list=`echo "$login_ip_white_list"|sed 's/ /\n/g'` 2>/dev/null
|
||
mark_mac_list="${mac_online_list} ${mac_offline_list}"
|
||
mark_mac_list=`echo "$mark_mac_list"|sed 's/ /\n/g'|sed 's/-/ /'` 2>/dev/null
|
||
ipv4_urllist=`cat /usr/share/wechatpush/api/ipv4.list` 2>/dev/null
|
||
ipv6_urllist=`cat /usr/share/wechatpush/api/ipv6.list` 2>/dev/null
|
||
User_Agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.58"
|
||
[ -z "$get_ipv4_mode" ] && get_ipv4_mode=0
|
||
[ -z "$get_ipv6_mode" ] && get_ipv6_mode=0
|
||
[ -z "$sleeptime" ] && sleeptime="60"
|
||
[ -z "$login_ip_black_timeout" ] && login_ip_black_timeout="86400"
|
||
[ -z "$login_ip_white_timeout" ] && login_ip_white_timeout="600"
|
||
[ "$iw_version" ] && wlan_interface=`iw dev 2>/dev/null|grep Interface|awk '{print $2}'` >/dev/null 2>&1
|
||
[ -z "$server_port" ] && server_port="22"
|
||
output_dir="${dir}json_output"
|
||
mkdir -p "$output_dir"
|
||
if ( echo "$lite_enable"|grep -q "content" ); then
|
||
str_title_start="" && str_title_end="" && str_splitline="" && str_linefeed="" && str_tab=""
|
||
else
|
||
read_json "str_title_start" "$jsonpath"
|
||
read_json "str_title_end" "$jsonpath"
|
||
read_json "str_linefeed" "$jsonpath"
|
||
read_json "str_splitline" "$jsonpath"
|
||
read_json "str_space" "$jsonpath"
|
||
read_json "str_tab" "$jsonpath"
|
||
read_json "_api" "$jsonpath"
|
||
fi
|
||
wait_and_cat
|
||
disturb_text=$_api
|
||
deltemp
|
||
cron
|
||
}
|
||
|
||
# 初始化
|
||
function init(){
|
||
enable_detection
|
||
echo "---------------------------------------------------------------------------------------" >> ${logfile}
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】start running..." >> ${logfile}
|
||
if [ -f "/usr/share/wechatpush/errlog" ]; then
|
||
cat /usr/share/wechatpush/errlog > ${logfile}
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】载入上次重启前日志" >> ${logfile}
|
||
fi
|
||
/usr/libexec/wechatpush-call "down_oui"
|
||
|
||
rm -f ${dir}fd1 ${dir}sheep_usage ${dir}old_sheep_usage ${dir}client_usage_aliases ${dir}old_client_usage_aliases /usr/share/wechatpush/errlog >/dev/null 2>&1
|
||
[ ! -f "/usr/sbin/wrtbwmon" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【info】未安装 wrtbwmon ,流量统计不可用" >> ${logfile}
|
||
[ -z "$ip_version" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】无法获取依赖项 iputils-arping 版本号,请确认插件是否正常运行" >> ${logfile}
|
||
[ -z "$cu_version" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】无法获取依赖项 curl 版本号,请确认插件是否正常运行" >> ${logfile}
|
||
[ -z "${sckey}${tg_token}${pushplus_token}${corpid}${wxpusher_apptoken}${wxpusher_uids}${wxpusher_topicIds}" -a "${jsonpath}" != "/usr/share/wechatpush/api/diy.json" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】请填写正确的 key " >> ${logfile} && return 1
|
||
local interfacelist=`getinterfacelist` && [ -z "$interfacelist" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】存在多个接口或配置错误,可能无法获取接口在线时间等信息,请确认插件是否正常运行" >> ${logfile}
|
||
[ -n "$notification_temp" ] && [ -n "$temperature_threshold" ] && local cpu_temp=`soc_temp` || local cpu_temp="null"
|
||
[ -z "$cpu_temp" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】无法读取设备温度,请检查命令" >> ${logfile}
|
||
[ -n "$notification_load" ] && [ -n "$cpu_load_threshold" ] && local cpu_fuzai=`cat /proc/loadavg|awk '{print $1}'` 2>/dev/null || local cpu_fuzai="null"
|
||
[ -z "$cpu_fuzai" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】无法读取设备负载,请检查命令" >> ${logfile}
|
||
|
||
[ -n "$login_web_black" ] && [ "$login_web_black" -eq "1" ] && init_ip_black "ipv4"
|
||
[ -n "$login_web_black" ] && [ "$login_web_black" -eq "1" ] && init_ip_black "ipv6"
|
||
[ -n "$port_knocking_enable" ] && [ "$port_knocking_enable" -eq "1" ] && init_ip_white "ipv4"
|
||
[ -n "$port_knocking_enable" ] && [ "$port_knocking_enable" -eq "1" ] && init_ip_white "ipv6"
|
||
|
||
tmp_ip_list=`echo "$login_ip_white_list"|grep -v "^$"|sort -u`
|
||
while IFS= read -r tmp_ip; do
|
||
[ -n "$tmp_ip" ] && add_ip_white "$tmp_ip" "0"
|
||
done <<< "$tmp_ip_list"
|
||
set_ip_black
|
||
return 0
|
||
}
|
||
|
||
# 推送
|
||
function diy_send(){
|
||
( ! echo "$lite_enable"|grep -q "content" ) && ( ! echo "$lite_enable"|grep -q "nowtime" ) && local nowtime=`date "+%Y-%m-%d %H:%M:%S"`
|
||
! jq -r '.' ${3} >/dev/null 2>&1 && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】json 文件格式错误,这不是一个标准的 json 文件,请检查 ${3} 文件是否有特殊符号未转义或语法错误" >> ${logfile} && return 1
|
||
local diyurl=`jq -r .url ${3}` && local diyurl=`eval echo ${diyurl}`
|
||
local type=`jq -r '.type' ${3}` && local type=`eval echo ${type}`
|
||
local data=`jq -r '.data' ${3}` && local data=`eval echo ${data}`
|
||
local content_type=`jq -r '.content_type' ${3}`
|
||
! jq "$type" ${3} > ${tempjsonpath} && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】type:{ } 字段转义变量后格式错误,请检查 type:{ } 字段内是否有特殊符号未转义或语法错误" >> ${logfile} && return 1
|
||
|
||
[ $4 ] && echo '{"url":"'${diyurl}'","content_type":"'${content_type}'","type":'`jq "$type" ${3}`'}' > ${dir}debug_send_json
|
||
[ $4 ] && echo -e "${send_title}" "${send_content}" > ${dir}debug_send_content
|
||
[ $4 ] && cat ${tempjsonpath} > ${dir}debug_send_data
|
||
[ $4 ] && ! jq -r '.' ${dir}debug_send_json && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】转义变量后格式错误,请检查 ${dir}debug_send_json 字段内是否有特殊符号未转义或语法错误" >> ${logfile}
|
||
[ $4 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【debug】json 文件已保存至:${dir}debug_send_json" >> ${logfile}
|
||
[ $4 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【debug】推送内容预览文件保存至:${dir}debug_send_content" >> ${logfile}
|
||
[ $4 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【debug】如果收不到信息,请检查 ${dir}debug_send_data 文件,或使用下列命令手动测试返回值 (可能需要关闭日志自动刷新方便选中)" >> ${logfile}
|
||
[ $4 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【debug】"'curl -X POST -H "'$content_type'" -d "@'${dir}debug_send_data'" "'${diyurl}'" ' >> ${logfile}
|
||
|
||
curl --connect-timeout 30 -m 60 -X POST -H "$content_type" -d "$data" "${diyurl}"
|
||
local RETVAL=$?
|
||
[ $RETVAL -ne "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】网络错误或 URL 错误,推送失败,curl 返回值为 ${RETVAL}" >> ${logfile} && return 1 || return 0
|
||
}
|
||
|
||
# 清理临时文件
|
||
function deltemp(){
|
||
unset title content ipAddress_logrow online_list online_mac mac_online_status gateway_iplist
|
||
rm -f ${dir}title ${dir}content ${dir}tmp_downlist ${dir}send_enable.lock ${tempjsonpath} ${dir}cookies.txt ${dir}tmp_sort_file >/dev/null 2>&1
|
||
[ ! -f ${dir}ipAddress ] && rm -f ${dir}client/* >/dev/null 2>&1
|
||
LockFile unlock
|
||
[ -f ${logfile} ] && local logrow=$(grep -c "" ${logfile}) || local logrow="0"
|
||
[ $logrow -gt 500 ] && sed -i '1,100d' ${logfile} && echo "`date "+%Y-%m-%d %H:%M:%S"` 【清理】日志超出上限,删除前 100 条" >> ${logfile}
|
||
}
|
||
|
||
# 检测程序开关
|
||
function enable_detection(){
|
||
[ ! "$1" ] && local time_n=1
|
||
for i in `seq 1 $time_n`; do
|
||
get_config enable;[ -z "$enable" ] || [ "$enable" -eq "0" ] && exit || sleep 1
|
||
done
|
||
}
|
||
|
||
# 获取 ip
|
||
function getip(){
|
||
[ ! "$1" ] && return
|
||
|
||
# 从接口获取 IPv4
|
||
if [ $1 == "wanipv4" ] ;then
|
||
[ ! -z "$ipv4_interface" ] && local wanIP=$(/sbin/ifconfig ${ipv4_interface}|awk '/inet addr/ {print $2}'|awk -F: '{print $2}'|grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
|
||
[ -z "$ipv4_interface" ] && local wanIP=$(getinterfacelist|grep '\"address\"'|grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
|
||
echo "$wanIP"
|
||
|
||
# 从 URL 获取 IPv4
|
||
elif [ $1 == "hostipv4" ] ;then
|
||
local url_number=`echo "$ipv4_urllist"|wc -l`
|
||
local rand_number=`rand 1 $url_number`
|
||
function get_hostipv4()
|
||
{
|
||
local ipv4_URL=`echo "$ipv4_urllist"| sed -n "${1}p"|sed -e 's/\r//g'`
|
||
[ ! -z "$ipv4_interface" ] && local tmp_hostIP=$(eval "curl -k -s -4 --interface ${ipv4_interface} -m 5 ${ipv4_URL}") || local tmp_hostIP=$(eval "curl -k -s -4 -m 5 ${ipv4_URL}")
|
||
[ -z "$tmp_hostIP" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【info】IP 获取失败,当前使用的 API 为 $ipv4_URL,接口为:${ipv4_interface}" >> ${logfile}
|
||
local tmp_hostIP=`echo $tmp_hostIP|grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'|head -n1`
|
||
echo "{\"IP\":\"${tmp_hostIP}\", \"URL\":\"${ipv4_URL}\"}"
|
||
}
|
||
local hostIP=`get_hostipv4 ${rand_number}`
|
||
[ -z `echo $hostIP|jq -r '.IP'` ] && local rand_number=`expr $rand_number + 1` && [ $rand_number -gt $url_number ] && local rand_number=1;[ -z `echo $hostIP|jq -r '.IP'` ] && local hostIP=`get_hostipv4 ${rand_number}`
|
||
[ -z `echo $hostIP|jq -r '.IP'` ] && local rand_number=`expr $rand_number + 1` && [ $rand_number -gt $url_number ] && local rand_number=1;[ -z `echo $hostIP|jq -r '.IP'` ] && local hostIP=`get_hostipv4 ${rand_number}`
|
||
[ -n "$list_auto_up" ] && [ "$list_auto_up" -eq "1" ] && [ -z `echo $hostIP|jq -r '.IP'` ] && /usr/libexec/wechatpush-call "auto_update_ip_list" "ipv4"
|
||
[ -z `echo $hostIP|jq -r '.IP'` ] && ipv4_urllist=`cat /usr/share/wechatpush/api/ipv4.list` 2>/dev/null
|
||
echo $hostIP
|
||
|
||
# 从接口获取 IPv6
|
||
elif [ $1 == "wanipv6" ] ;then
|
||
[ ! -z "$ipv6_interface" ] && local wanIPv6=$(ip -6 addr show dev ${ipv6_interface}|grep "inet6"|grep "global dynamic noprefixroute"|awk '{print $2, $4}'|sort -k3 -n|head -n 1|awk '{print $1}'|grep -oE "([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}")
|
||
[ -z "$ipv6_interface" ] && local wanIPv6=$(ip -6 addr show|grep "inet6"|grep "global dynamic noprefixroute"|awk '{print $2, $4}'|sort -k3 -n|head -n 1|awk '{print $1}'|grep -oE "([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}")
|
||
echo "$wanIPv6"
|
||
|
||
# 从 URL 获取 IPv6
|
||
elif [ $1 == "hostipv6" ] ;then
|
||
local urlv6_number=`echo "$ipv6_urllist"|wc -l`
|
||
local rand_numberv6=`rand 1 $urlv6_number`
|
||
function get_hostipv6()
|
||
{
|
||
local ipv6_URL=`echo "$ipv6_urllist"| sed -n "${1}p"|sed -e 's/\r//g'`
|
||
[ ! -z "$ipv6_interface" ] && local tmp_hostIPv6=$(eval "curl -k -s -6 --interface ${ipv6_interface} -m 5 ${ipv6_URL}") || local tmp_hostIPv6=$(eval "curl -k -s -6 -m 5 ${ipv6_URL}")
|
||
[ -z "$tmp_hostIPv6" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【info】IP 获取失败,当前使用的 API 为 $ipv6_URL,接口为:${ipv6_interface}" >> ${logfile}
|
||
local tmp_hostIPv6=`echo $tmp_hostIPv6|grep -oE "([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}"|head -n1`
|
||
echo "{\"IP\":\"${tmp_hostIPv6}\", \"URL\":\"${ipv6_URL}\"}"
|
||
}
|
||
local hostIPv6=`get_hostipv6 ${rand_numberv6}`
|
||
[ -z `echo $hostIPv6|jq -r '.IP'` ] && local rand_numberv6=`expr $rand_numberv6 + 1` && [ $rand_numberv6 -gt $urlv6_number ] && local rand_numberv6=1;[ -z `echo $hostIPv6|jq -r '.IP'` ] && local hostIPv6=`get_hostipv6 ${rand_numberv6}`
|
||
[ -z `echo $hostIPv6|jq -r '.IP'` ] && local rand_numberv6=`expr $rand_numberv6 + 1` && [ $rand_numberv6 -gt $urlv6_number ] && local rand_numberv6=1;[ -z `echo $hostIPv6|jq -r '.IP'` ] && local hostIPv6=`get_hostipv6 ${rand_numberv6}`
|
||
[ -n "$list_auto_up" ] && [ "$list_auto_up" -eq "1" ] && [ -z `echo $hostIP|jq -r '.IP'` ] && /usr/libexec/wechatpush-call "auto_update_ip_list" "ipv6"
|
||
[ -z `echo $hostIPv6|jq -r '.IP'` ] && ipv4_urllist=`cat /usr/share/wechatpush/api/ipv6.list` 2>/dev/null
|
||
echo $hostIPv6
|
||
fi
|
||
}
|
||
|
||
# 获取接口信息
|
||
function getinterfacelist(){
|
||
[ `ubus list|grep -w -i "network.interface.wan"|wc -l` -ge "1" ] && ubus call network.interface.wan status && return
|
||
[ ! -z "$ipv4_interface" ] && local device_name=$ipv4_interface || [ ! -z "$ipv6_interface" ] && local device_name=$ipv6_interface
|
||
[ ! -z "$device_name" ] && local interface_name=`ubus call network.interface dump | jq -r --arg intf "$device_name" '.interface[] | select(.device == $intf and (.interface | endswith("6") | not)) | .interface'`
|
||
[ -z "$interface_name" ] && local interface_name=`ubus list | grep -i "network.interface." | grep -v "loopback" | grep -v -i "wan6" | grep -v -i "lan6" | grep -v -i "ipsec.*" | grep -v -i "VPN.*" | grep -v -i "DOCKER.*" | awk -F '.' '{print $3}'`
|
||
[ `echo "${interface_name}" |wc -l` -eq "1" ] && ubus call network.interface.${interface_name} status && return
|
||
}
|
||
|
||
# 获取接口在线时间
|
||
function getinterfaceuptime(){
|
||
getinterfacelist|awk -F'\"uptime\": ' '/uptime/ { gsub(/,/, "", $2); print $2 }'
|
||
}
|
||
|
||
# 查询 MAC 地址
|
||
function getmac(){
|
||
# 已保存的 MAC
|
||
[ -f "${dir}ipAddress" ] && local tmp_mac=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $2}'|grep -v "^$"`
|
||
( echo "$tmp_mac"|grep -q "unknown" ) && unset tmp_mac # 为 unknown 时重新读取
|
||
[ -n "$tmp_mac" ] && [ "$(grep -w -i "${tmp_mac}" "${dir}ipAddress" | wc -l)" -gt "1" ] && unset tmp_mac # 某些路由器中继模式,会进行 MAC 克隆,重复值重新读取
|
||
[ -f "${dir}tmp_downlist" ] && [ -z "$tmp_mac" ] && local tmp_mac=`cat ${dir}tmp_downlist|grep -w ${1}|awk '{print $2}'|grep -v "^$"|sort -u|head -n1`
|
||
# DHCP
|
||
( echo "$tmp_mac"|grep -q "unknown" ) && unset tmp_mac # 为 unknown 时重新读取
|
||
[ -f "/tmp/dhcp.leases" ] && [ -z "$tmp_mac" ] && local tmp_mac=`cat /tmp/dhcp.leases|grep -w ${1}|awk '{print $2}'|grep -v "^$"|sort -u|head -n1`
|
||
# arp
|
||
[ -z "$tmp_mac" ] && local tmp_mac=`cat /proc/net/arp|grep "0x2\|0x6"|grep -w ${1}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1`
|
||
|
||
[ -z "$tmp_mac" ] && local tmp_mac="unknown"
|
||
echo $tmp_mac |tr -d '\n\r'
|
||
}
|
||
|
||
# 查询主机名
|
||
function getname(){
|
||
# 自定义备注
|
||
local tmp_name=`echo "$device_aliases"|grep -i -w "^${1}\|^${2}"|awk '{ for(i=2; i<=NF; i++) printf $i " "; print "" }'|grep -v "^$"|sort -u|head -n1`
|
||
[ -n "$tmp_name" ] && echo "$tmp_name" | tr -d '\n\r' | awk '$1=$1' | sed 's/_/ /g' | sort -u | head -n1 && return
|
||
echo "$2" | grep -q -w "unknown\|*" && echo "unknown" && return # 当 MAC 获取失败时先不要尝试获取主机名
|
||
# 已保存的 主机名
|
||
[ -f "${dir}ipAddress" ] && [ -z "$tmp_name" ] && local tmp_name=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $3}'|grep -v "^$"|sort -u|head -n1`
|
||
echo "$tmp_name" | grep -q -w "unknown\|*" && unset tmp_name # 为unknown时重新读取
|
||
[ -z "$tmp_name" ] && [ -f "${dir}tmp_downlist" ] && local tmp_name=`cat ${dir}tmp_downlist|grep -w ${1}|awk '{print $3}'|grep -v "^$"|sort -u|head -n1`
|
||
# 静态地址备注名
|
||
echo "$tmp_name" | grep -q -w "unknown\|*" && unset tmp_name # 为unknown时重新读取
|
||
[ -z "$tmp_name" ] && dhcp_config=`uci show dhcp|grep "ip\|mac\|name"`
|
||
if [ -n "$dhcp_config" ]; then
|
||
dhcp_ip_n=$(echo "$dhcp_config" | grep -w ^dhcp.@${dhcp_config_str}.*ip=.${1} | sed -nr 's#^dhcp.(.*).ip.*#\1#gp' 2>/dev/null)
|
||
[ ! -z "$dhcp_ip_n" ] && [ -z "$tmp_name" ] && tmp_name=$(uci get dhcp.${dhcp_ip_n}.name 2>/dev/null)
|
||
[ -z "$tmp_name" ] && dhcp_mac_n=$(echo "$dhcp_config" | grep -i ^dhcp.@${dhcp_config_str}.*mac=.${2} | sed -nr 's#^dhcp.(.*).mac.*#\1#gp' 2>/dev/null)
|
||
[ ! -z "$dhcp_mac_n" ] && [ -z "$tmp_name" ] && tmp_name=$(uci get dhcp.${dhcp_mac_n}.name 2>/dev/null)
|
||
fi
|
||
# DHCP
|
||
echo "$tmp_name" | grep -q -w "unknown\|*" && unset tmp_name # 为unknown时重新读取
|
||
[ -z "$tmp_name" ] && [ -f "/tmp/dhcp.leases" ] && local tmp_name=`cat /tmp/dhcp.leases|grep -w ${1}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1`
|
||
# 光猫
|
||
echo "$tmp_name" | grep -q -w "unknown\|*" && unset tmp_name # 为unknown时重新读取
|
||
[ -z "$tmp_name" ] && [ -f "${dir}gateway_info" ] && gatewayinfo=`cat ${dir}gateway_info` && local tmp_name=$(cut_str "$(echo "$gatewayinfo"|grep -w ${1}|awk '{print $2}'|sort -u|head -n1)" "30")
|
||
# MAC设备信息数据库
|
||
echo "$tmp_name" | grep -q -w "unknown\|*" && unset tmp_name # 为unknown时重新读取
|
||
[ -z "$tmp_name" ] && [ -f "$oui_base" ] && local tmp_name=$(cat $oui_base|grep -i $(echo "$2"|cut -c 1,2,4,5,7,8)|sed -nr 's#^.*16)..(.*)#\1#gp')
|
||
[ -z "$tmp_name" ] && [ ! -z "$oui_data" ] && [ "$oui_data" -eq "4" ] && local tmp_name=$(curl -sS "https://standards-oui.ieee.org/oui/oui.txt"|grep -i $(echo "$2"|cut -c 1,2,4,5,7,8)|sed -nr 's#^.*16)..(.*)#\1#gp')
|
||
|
||
[ -z "$tmp_name" ] && local tmp_name="unknown"
|
||
echo "$tmp_name" | tr -d '\n\r' | awk '$1=$1' | sed 's/_/ /g' | sort -u | head -n1
|
||
}
|
||
|
||
# 从光猫处获取设备信息
|
||
function getgateway(){
|
||
[ -z "$gateway_info_enable" ] && return
|
||
last_getgateway_time=$(date -r ${dir}gateway_info +%s 2>/dev/null) || last_getgateway_time=0
|
||
[ "$1" ] && [ "$1" == "reboot" ] && last_getgateway_time=0
|
||
if [ `expr $(date +%s) - $last_getgateway_time` -gt "$device_info_helper_sleeptime" ]; then
|
||
# 登录
|
||
local loginfo=`curl -s -L "${gateway_host_url}" -c ${dir}cookies.txt -d "${gateway_username_id}=${gateway_username}&${gateway_password_id}=${gateway_password}"` 2>/dev/null
|
||
[ ! -z "$loginfo" ] && local mytoken=$(echo $loginfo |sed 's/{/\n/g' | grep token |awk '/realRestart/{print $2}'| sed $'s/\'//g')
|
||
# 获取
|
||
[ ! -z "$mytoken" ] && local get_gateway=`curl -s -b ${dir}cookies.txt "${gateway_info_url}" -d 'token='$mytoken | jq '.[] | iterables| "\(.ip) \(.devName) \(.model)"'|sed 's/unknown//g'|sed 's/ / /g'|sed 's/ /_/g'|sed 's/_/ /'|sed 's/\"//g'`
|
||
# 重启
|
||
[ "$1" ] && [ "$1" == "reboot" ] && curl -s -b ${dir}/cookies.txt "${gateway_host_url}/admin/reboot" -d "token=$mytoken" >/dev/null 2>&1
|
||
# 注销
|
||
[ ! -z "$get_gateway" ] && [ ! -z "$gateway_logout_url" ] && curl -s -b ${dir}cookies.txt "${gateway_logout_url}" -d 'token='$mytoken 2>/dev/null
|
||
[ -z "$get_gateway" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【info】获取光猫信息失败,可能当前用户未注销或设置错误" >> ${logfile}
|
||
# 保存信息
|
||
[ ! -z "$get_gateway" ] && echo "$get_gateway" > ${dir}gateway_info
|
||
gateway_iplist=`echo "${get_gateway}"|awk '{print $1}'`
|
||
else
|
||
unset gateway_iplist
|
||
fi
|
||
}
|
||
|
||
# 扫描范围内 IP
|
||
function scanlocalip(){
|
||
[ -z "$scan_ip_range" ] && return
|
||
[ -z "$last_scan_ip_time" ] && last_scan_ip_time=0
|
||
if [ `expr $(date +%s) - $last_scan_ip_time` -gt "$device_info_helper_sleeptime" ]; then
|
||
start_ip=$(echo "$scan_ip_range" | cut -d "-" -f 1)
|
||
end_ip=$(echo "$scan_ip_range" | cut -d "-" -f 2)
|
||
|
||
i=$(echo "$start_ip" | awk -F '.' '{print $NF}')
|
||
end_i=$(echo "$end_ip" | awk -F '.' '{print $NF}')
|
||
while [ "$i" -le "$end_i" ]; do
|
||
if ping -c 1 "${start_ip%.*}.$i" > /dev/null 2>&1 & then
|
||
echo "${start_ip%.*}.$i" >> "${dir}scan_info"
|
||
fi
|
||
i=$((i + 1))
|
||
done
|
||
scan_iplist=`cat ${dir}scan_info`
|
||
else
|
||
unset scan_iplist
|
||
fi
|
||
}
|
||
|
||
# 查询设备接口
|
||
function getinterface(){
|
||
[ -z "${1}" ] && return
|
||
[ "${1}" == "unknown" ] && return
|
||
|
||
[ -f "${dir}ipAddress" ] && local ip_interface=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $5}'|grep -v "^$"|sort -u|head -n1`
|
||
[ -f "${dir}tmp_downlist" ] && [ -z "$ip_interface" ] && local ip_interface=`cat ${dir}tmp_downlist|grep -w ${1}|awk '{print $5}'|grep -v "^$"|sort -u|head -n1`
|
||
if [ -z "$ip_interface" ] && [ ! -z "$wlan_interface" ]; then
|
||
for interface in $wlan_interface; do
|
||
local ip_interface=`iw dev $interface station dump 2>/dev/null|grep Station|grep -i -w ${1}|sed -nr 's#^.*on (.*))#\1#gp'` >/dev/null 2>&1
|
||
[ ! -z "$ip_interface" ] && echo "$ip_interface" && return
|
||
done
|
||
fi
|
||
[ -z "$ip_interface" ] && local ip_interface=`cat /proc/net/arp|grep "0x2\|0x6"|grep -i -w ${1}|awk '{print $6}'|grep -v "^$"|sort -u|head -n1`
|
||
echo $ip_interface |tr -d '\n\r'
|
||
}
|
||
|
||
# ping
|
||
function getping(){
|
||
ip_interface=`getinterface ${2}`
|
||
[ "$iw_version" ] && [ "$ip_interface" ] && wlan_online=`iw dev ${ip_interface} station dump 2>/dev/null|grep -i -w ${2}|grep Station` >/dev/null 2>&1
|
||
[ "$wlan_online" ] && return 0
|
||
arplist=$(cat /proc/net/arp)
|
||
for i in `seq 1 ${4}`; do
|
||
[ "$(echo "$arplist"|grep -i -w "${2}"|wc -l)" -eq 1 ] && interface=$(echo "$arplist"|grep -w ${1}|awk '{print $6}'|grep -v "^$"|sort -u|head -n1) && [ ! -z "$interface" ] && ip_ms=`arping -I ${interface} -c 20 -f -w ${3} ${1}` 2>/dev/null
|
||
( ! echo "$ip_ms"|grep -q "ms" ) && ip_ms=`ping -c 5 -w ${3} ${1}|grep -v '100% packet loss'` 2>/dev/null
|
||
( ! echo "$ip_ms"|grep -q "ms" ) && sleep 1
|
||
done
|
||
echo "$ip_ms"|grep -q "ms"
|
||
}
|
||
|
||
# CPU 占用率
|
||
function getcpu(){
|
||
local AT=$(cat /proc/stat|grep "^cpu "|awk '{print $2+$3+$4+$5+$6+$7+$8 " " $2+$3+$4+$7+$8}')
|
||
sleep 1
|
||
local BT=$(cat /proc/stat|grep "^cpu "|awk '{print $2+$3+$4+$5+$6+$7+$8 " " $2+$3+$4+$7+$8}')
|
||
printf "%.01f%%" $(echo ${AT} ${BT}|awk '{print (($4-$2)/($3-$1))*100}')
|
||
}
|
||
|
||
# 获取SOC温度 (取所有传感器温度最大值)
|
||
function soc_temp(){
|
||
[ ! -z "$soc_code" ] && eval `echo "$soc_code"` 2>/dev/null && return 0
|
||
getsensors() {
|
||
# Intel
|
||
local sensor_field1='["coretemp-isa-0000"]["Package id 0"]["temp1_input"]'
|
||
# AMD
|
||
local sensor_field2='["zenpower-pci-00c3"]["Tctl"]["temp1_input"]'
|
||
local sensor_field3='["k10temp-pci-00c3"]["Tctl"]["temp1_input"]'
|
||
eval "${1} sensors -j 2>/dev/null" | jq -r "
|
||
if .${sensor_field1} != null then
|
||
.${sensor_field1}
|
||
elif .${sensor_field2} != null then
|
||
.${sensor_field2}
|
||
elif .${sensor_field3} != null then
|
||
.${sensor_field3}
|
||
else
|
||
null
|
||
end // \"\"
|
||
"
|
||
}
|
||
|
||
[ ! -z "$server_host" ] && ssh_command="ssh -o StrictHostKeyChecking=yes -o BatchMode=yes -i /root/.ssh/id_rsa root@${server_host} -p ${server_port}"
|
||
temperature=$(getsensors "$ssh_command" 2>/dev/null)
|
||
# 通用(只能取最高温度,不一定是 CPU,特殊设备自行修改)
|
||
# 将 grep °C 改为温度所在行的特别字符串,如 grep Core 0 等,就可以指定设备了
|
||
[ -z "$temperature" ] && temperature=$(sensors 2>/dev/null|grep °C|sed -nr 's#^.*:.*\+(.*)°C .*#\1#gp'|sort -nr|head -n1)
|
||
# 将 thermal_zone* 改为 thermal_zone0 thermal_zone1 等,就可以指定设备了
|
||
[ -z "$temperature" ] && temperature=$(cat /sys/class/thermal/thermal_zone*/temp 2>/dev/null|sort -nr|head -n1|cut -c-2)
|
||
printf "%.1f" "$temperature"
|
||
}
|
||
# 流量数据
|
||
function usage(){
|
||
[ ! -f "/usr/sbin/wrtbwmon" ] || [ ! "$1" ] && return
|
||
# 更新
|
||
if [ $1 == "update" ] ;then
|
||
function version_le() { test "$(echo "$@"|tr " " "\n"|sort -n|head -n 1)" == "$1"; }
|
||
function version_ge() { test "$(echo "$@"|tr " " "\n"|sort -r|head -n 1)" == "$1"; }
|
||
[ ! -z "$wr_version" ] && ( version_ge "${wr_version}" "1.2.0" ) && wrtbwmon -f ${dir}usage.db 2>/dev/null && return
|
||
[ ! -z "$wr_version" ] && ( version_le "${wr_version}" "1.0.0" ) || [ -z "$wr_version" ] && wrtbwmon update ${dir}usage.db 2>/dev/null && return
|
||
# 获取
|
||
elif [ $1 == "get" ] ;then
|
||
[ ! -f "${dir}usage.db" ] && [ ! "$3" ] && echo `bytes_for_humans 0` && return
|
||
[ ! -f "${dir}usage.db" ] && [ "$3" ] && echo 0 && return
|
||
[ -z "$total_n" ] && total_n=`cat ${dir}usage.db|head -n1|grep "total"|sed 's/,/\n/g'|awk '/total/{print NR}'` 2>/dev/null
|
||
[ -z "$total_n" ] && total_n="6"
|
||
[ "$2" ] && local tmptotal=`cat ${dir}usage.db|sed 's/,,,/,0,0,/g'|sed 's/,,/,0,/g'|sed 's/,/ /g'|grep -i -w ${2}|awk "{print "'$'$total_n"}"|grep -v "^$"|sort -u|head -n1` 2>/dev/null
|
||
[ -z "$tmptotal" ] && local tmptotal="0"
|
||
[ ! "$3" ] && echo `bytes_for_humans ${tmptotal}` || echo $tmptotal
|
||
# 剔除
|
||
elif [ $1 == "down" ] ;then
|
||
[ "$2" ] && sed -i "/,${2},/d" ${dir}usage.db 2>/dev/null
|
||
fi
|
||
}
|
||
|
||
# 流量数据单位换算
|
||
function bytes_for_humans {
|
||
[ ! "$1" ] && return
|
||
[ "$1" -gt 1073741824 ] && echo "`awk 'BEGIN{printf "%.2f\n",'$1'/'1073741824'}'` GB" && return
|
||
[ "$1" -gt 1048576 ] && echo "`awk 'BEGIN{printf "%.2f\n",'$1'/'1048576'}'` MB" && return
|
||
[ "$1" -gt 1024 ] && echo "`awk 'BEGIN{printf "%.2f\n",'$1'/'1024'}'` KB" && return
|
||
echo "${1} bytes"
|
||
}
|
||
|
||
# 设备异常流量检测
|
||
function get_client_usage(){
|
||
[ -z "$client_usage" ] && return
|
||
[ "$client_usage" -ne "1" ] && return
|
||
[ -z "$client_usage_max" ] && return
|
||
|
||
[ -z "$get_client_usage_time" ] && get_client_usage_time=`date +%s`
|
||
( echo $client_usage_max|sed -r 's/.*(.)$/\1/'|grep -q "K\|k" ) && client_usage_max=`expr ${client_usage_max%?} \* 1024`
|
||
( echo $client_usage_max|sed -r 's/.*(.)$/\1/'|grep -q "M\|m" ) && client_usage_max=`expr ${client_usage_max%?} \* 1048576`
|
||
( echo $client_usage_max|sed -r 's/.*(.)$/\1/'|grep -q "G\|g" ) && client_usage_max=`expr ${client_usage_max%?} \* 1073741824`
|
||
[ -z "$client_usage_disturb" ] && client_usage_disturb="0"
|
||
[ "$client_usage_disturb" -eq "0" ] && [ -f "${dir}ipAddress" ] && local MACLIST=`cat ${dir}ipAddress|awk '{print $2}'|grep -v "^$"|sort -u`
|
||
[ "$client_usage_disturb" -eq "1" ] && [ ! -z "$client_usage_whitelist" ] && local MACLIST=`echo "$client_usage_whitelist"`
|
||
[ -z "$MACLIST" ] && return
|
||
|
||
if [ "$((`date +%s`-$get_client_usage_time))" -ge "60" ]; then
|
||
> ${dir}client_usage_aliases
|
||
for mac in $MACLIST; do
|
||
( ! cat ${dir}ipAddress|grep -q -i -w $mac|grep -v "^$"|sort -u|head -n1 ) && continue
|
||
echo "$mac" `usage get ${mac} bytes` >> ${dir}client_usage_aliases
|
||
[ -f "${dir}old_client_usage_aliases" ] && get_client_usage_bytes=`cat ${dir}old_client_usage_aliases|grep -i -w $mac|awk '{print $2}'|grep -v "^$"|sort -u|head -n1` || continue
|
||
[ -z "$get_client_usage_bytes" ] && get_client_usage_bytes="0"
|
||
if [ "$((`usage get ${mac} bytes`-$get_client_usage_bytes))" -ge "$client_usage_max" ]; then
|
||
local ip=`cat ${dir}ipAddress|grep -i -w $mac|awk '{print $1}'|grep -v "^$"|sort -u|head -n1`
|
||
local ip_name=`getname ${ip} ${mac}`
|
||
local tmp_usage=$(bytes_for_humans $(expr `usage get ${mac} bytes` - ${get_client_usage_bytes}))
|
||
local time_up=`cat ${dir}ipAddress|grep -w ${ip}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1`
|
||
local ip_total=`usage get $mac` && [ ! -z "$ip_total" ] && local ip_total="${str_linefeed}${str_tab}总计流量: ${str_space}${str_space}${str_space}${str_space}${ip_total}"
|
||
local time1=`date +%s`
|
||
local time1=$(time_for_humans `expr ${time1} - ${time_up}`)
|
||
if [ -z "$title" ]; then
|
||
title="${ip_name} 流量异常"
|
||
content="${content}${str_splitline}${str_title_start} 设备流量异常${str_title_end}${str_linefeed}${str_tab}客户端名:${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP: ${str_space}${str_space}${str_space}${str_space}${ip}${str_linefeed}${str_tab}客户端MAC:${str_space}${str_space}${str_space}${str_space}${mac}$ip_total${str_linefeed}${str_tab}一分钟内流量: ${str_space}${str_space}${tmp_usage}${str_linefeed}${str_tab}在线时间: ${str_space}${str_space}${str_space}${str_space}${time1}"
|
||
elif ( echo "$title"|grep -q "流量异常" ); then
|
||
title="${ip_name} ${title}"
|
||
content="${content}${str_splitline}${str_tab}客户端名:${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP: ${str_space}${str_space}${str_space}${str_space}${ip}${str_linefeed}${str_tab}客户端MAC:${str_space}${str_space}${str_space}${str_space}${mac}$ip_total${str_linefeed}${str_tab}一分钟内流量: ${str_space}${str_space}${str_space}${tmp_usage}${str_linefeed}${str_tab}在线时间: ${str_space}${str_space}${str_space}${str_space}${time1}"
|
||
else
|
||
title="设备状态变化"
|
||
content="${content}${str_splitline}${str_title_start} 设备流量异常${str_title_end}${str_linefeed}${str_tab}客户端名:${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP: ${str_space}${str_space}${str_space}${str_space}${ip}${str_linefeed}${str_tab}客户端MAC:${str_space}${str_space}${str_space}${str_space}${mac}$ip_total${str_linefeed}${str_tab}一分钟内流量: ${str_space}${str_space}${str_space}${tmp_usage}${str_linefeed}${str_tab}在线时间: ${str_space}${str_space}${str_space}${str_space}${time1}"
|
||
fi
|
||
fi
|
||
done
|
||
cat ${dir}client_usage_aliases > ${dir}old_client_usage_aliases
|
||
get_client_usage_time=`date +%s`
|
||
fi
|
||
}
|
||
|
||
# 时间单位换算
|
||
function time_for_humans {
|
||
[ ! "$1" ] && return
|
||
|
||
if [ "$1" -lt 60 ]; then
|
||
echo "${1} 秒"
|
||
elif [ "$1" -lt 3600 ]; then
|
||
local usetime_min=`expr $1 / 60`
|
||
local usetime_sec=`expr $usetime_min \* 60`
|
||
local usetime_sec=`expr $1 - $usetime_sec`
|
||
echo "${usetime_min} 分 ${usetime_sec} 秒"
|
||
elif [ "$1" -lt 86400 ]; then
|
||
local usetime_hour=`expr $1 / 3600`
|
||
local usetime_min=`expr $usetime_hour \* 3600`
|
||
local usetime_min=`expr $1 - $usetime_min`
|
||
local usetime_min=`expr $usetime_min / 60`
|
||
echo "${usetime_hour} 小时 ${usetime_min} 分"
|
||
else
|
||
local usetime_day=`expr $1 / 86400`
|
||
local usetime_hour=`expr $usetime_day \* 86400`
|
||
local usetime_hour=`expr $1 - $usetime_hour`
|
||
local usetime_hour=`expr $usetime_hour / 3600`
|
||
echo "${usetime_day} 天 ${usetime_hour} 小时"
|
||
fi
|
||
}
|
||
|
||
# 计算字符显示宽度
|
||
function length_str {
|
||
[ ! "$1" ] && return
|
||
|
||
local length_zh=`echo "$1"|awk '{print gensub(/[\u4e00-\u9FA5A-Za-z0-9_]/,"","g",$0)}'|awk -F "" '{print NF}'`
|
||
local length_en=`echo "$1"|awk '{print gensub(/[^\u4e00-\u9FA5A-Za-z0-9_]/,"","g",$0)}'|awk -F "" '{print NF}'`
|
||
|
||
echo $((length_zh / 3 * 2 + length_en))
|
||
}
|
||
|
||
function cut_str {
|
||
[ ! "$1" ] && return
|
||
[ ! "$2" ] && return
|
||
|
||
if [ $(length_str "$1") -le "$2" ]; then
|
||
echo -n "$1" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
|
||
return
|
||
fi
|
||
|
||
local columns=$(echo "$1" | awk '{print NF}')
|
||
if [ "$columns" -gt 1 ]; then
|
||
local max_length=0
|
||
local max_column=1
|
||
for i in $(seq 1 $columns); do
|
||
local length=$(echo "$1"|awk '{print gensub(/[\u4e00-\u9FA5A-Za-z0-9_]/,"","g",$0)}'|awk -F "" '{print NF}')
|
||
if [ "$length" -gt "$max_length" ]; then
|
||
max_length=$length
|
||
max_column=$i
|
||
fi
|
||
done
|
||
local text=$(echo -n "$1" | cut -d ' ' -f $max_column)
|
||
if [ $(length_str "$text") -le "$2" ]; then
|
||
echo "$text" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
|
||
return
|
||
fi
|
||
fi
|
||
|
||
local temp_length=$2
|
||
while [ $(length_str "$(echo -n "$1" | cut -c -$temp_length)") -lt "$2" ]; do
|
||
temp_length=$(expr $temp_length + 1)
|
||
done
|
||
while [ $(printf "%d" \'$(echo -n "$1" | cut -c $temp_length)) -ge "128" ] && [ $(printf "%d" \'$(echo -n "$1" | cut -c $temp_length)) -lt "224" ]; do
|
||
temp_length=$(expr $temp_length + 1)
|
||
done
|
||
temp_length=$(expr $temp_length - 1)
|
||
|
||
echo "$(echo -n "$1" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | cut -c -$temp_length).."
|
||
}
|
||
|
||
|
||
|
||
# 随机数
|
||
function rand(){
|
||
local min=$1
|
||
local max=$(($2- $min + 1))
|
||
local num=$(date +%s%N)
|
||
echo $(($num % $max + $min))
|
||
}
|
||
|
||
# 在线设备列表
|
||
function first(){
|
||
[ -f "${dir}ipAddress" ] && local IPLIST_ipAddress=`cat ${dir}ipAddress|awk '{print $1}'|grep -v "^$"|sort -u`
|
||
getgateway
|
||
scanlocalip;last_scan_ip_time=$(date +%s)
|
||
for ip in $IPLIST_ipAddress; do
|
||
[ ! -z "$passive_mode" ] && [ "$passive_mode" -eq "1" ] && break
|
||
read -u 5
|
||
{
|
||
down $ip
|
||
echo "" >&5
|
||
}&
|
||
done
|
||
wait
|
||
|
||
local IPLIST=`cat /proc/net/arp|grep "0x2\|0x6"|awk '{print $1}'|grep -v "^169.254."|grep -v "^$"|sort -u|grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'`
|
||
local IPLIST=`echo -e "${IPLIST}\n${gateway_iplist}\n${scan_iplist}"|grep -v "^$"|sort -u`
|
||
for ip in $IPLIST; do
|
||
[ ! -z "$passive_mode" ] && [ "$passive_mode" -eq "1" ] && break
|
||
read -u 5
|
||
{
|
||
up $ip
|
||
echo "" >&5
|
||
}&
|
||
done
|
||
wait
|
||
|
||
[ -z "$passive_mode" ] && return
|
||
[ "$passive_mode" -ne "1" ] && return
|
||
for ip in $IPLIST; do
|
||
if ( ! echo "$IPLIST_ipAddress"|grep -q -i -w $ip ); then
|
||
ip_mac=`getmac $ip`
|
||
ip_name=`getname ${ip} ${ip_mac}`
|
||
ip_interface=`getinterface ${ip_mac}`
|
||
echo "{'ip': '${ip}','mac': '${ip_mac}','name': '${ip_name}','uptime': '0秒','interface': '${ip_interface}','usage': ''}" > ${dir}client/${ip}
|
||
usage down ${ip}
|
||
echo "${ip} ${ip_mac} ${ip_name// /_} `date +%s` ${ip_interface}" >> ${dir}ipAddress
|
||
fi
|
||
done
|
||
for ip in $IPLIST_ipAddress; do
|
||
if ( echo "$IPLIST"|grep -q -i -w $ip ); then
|
||
ip_mac=`getmac $ip`
|
||
ip_name=`getname ${ip} ${ip_mac}`
|
||
ip_interface=`getinterface ${ip_mac}`
|
||
time_up=`cat ${dir}ipAddress|grep -w ${ip}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1`
|
||
time1=`date +%s`
|
||
time1=$(time_for_humans `expr ${time1} - ${time_up}`)
|
||
echo "{'ip': '${ip}','mac': '${ip_mac}','name': '${ip_name}','uptime': '${time1}','interface': '${ip_interface}','usage': '`usage get $ip_mac`'}" > ${dir}client/${ip}
|
||
else
|
||
sed -i "/^${ip} /d" ${dir}ipAddress
|
||
rm -f ${dir}client/${ip} >/dev/null 2>&1
|
||
fi
|
||
done
|
||
}
|
||
|
||
# 创建计划任务
|
||
function cron(){
|
||
function del_cron(){
|
||
( echo `crontab -l 2>/dev/null`|grep -q "wechatpush" ) && crontab -l > conf && sed -i "/wechatpush/d" conf && crontab conf && rm -f conf >/dev/null 2>&1
|
||
}
|
||
function re_cron(){
|
||
/etc/init.d/cron stop
|
||
/etc/init.d/cron start
|
||
}
|
||
del_cron
|
||
if [ -z "$enable" ]; then
|
||
re_cron
|
||
return
|
||
fi
|
||
|
||
# 重置流量
|
||
if [ ! -z "$reset_regularly" ] && [ "$reset_regularly" -eq "1" ]; then
|
||
crontab -l 2>/dev/null > conf && echo -e "0 0 * * * rm ${dir}usage.db >/dev/null 2>&1" >> conf && crontab conf && rm -f conf >/dev/null 2>&1
|
||
crontab -l 2>/dev/null > conf && echo -e "0 0 * * * rm ${dir}usage6.db >/dev/null 2>&1" >> conf && crontab conf && rm -f conf >/dev/null 2>&1
|
||
fi
|
||
|
||
# 定时发送
|
||
if [ -n "$crontab_regular_time" ]; then
|
||
crontab_regular_time=`echo $crontab_regular_time|sed 's/ /,/g'` 2>/dev/null
|
||
crontab -l 2>/dev/null > conf && echo -e "0 $crontab_regular_time * * * /usr/share/wechatpush/wechatpush send &" >> conf && crontab conf && rm -f conf >/dev/null 2>&1
|
||
# 间隔发送
|
||
elif [ -n "$crontab_interval_time" ]; then
|
||
crontab -l 2>/dev/null > conf && echo -e "0 */$crontab_interval_time * * * /usr/share/wechatpush/wechatpush send &" >> conf && crontab conf && rm -f conf >/dev/null 2>&1
|
||
fi
|
||
|
||
re_cron
|
||
}
|
||
|
||
# 免打扰检测
|
||
function disturb(){
|
||
[ -z "$do_not_disturb_mode" ] || [ -z "$do_not_disturb_starttime" ] || [ -z "$do_not_disturb_endtime" ] && return 0
|
||
|
||
# 非免打扰时间
|
||
if [ `date +%H` -ge $do_not_disturb_endtime -a $do_not_disturb_starttime -lt $do_not_disturb_endtime ] || [ `date +%H` -lt $do_not_disturb_starttime -a $do_not_disturb_starttime -lt $do_not_disturb_endtime ] || [ `date +%H` -lt $do_not_disturb_starttime -a `date +%H` -ge $do_not_disturb_endtime -a $do_not_disturb_starttime -gt $do_not_disturb_endtime ]; then
|
||
unset sheep_starttime
|
||
rm -f ${dir}sheep_usage ${dir}old_sheep_usage 2>/dev/null
|
||
disturb_text=`jq -r '._api' ${jsonpath}`
|
||
return 0
|
||
# 免打扰
|
||
else
|
||
[ -z "$sheep_starttime" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【免打扰】夜深了,该休息了" >> ${logfile} && sheep_starttime=`date +%s`
|
||
# 挂起
|
||
if [ "$do_not_disturb_mode" -eq "1" ] ;then
|
||
while [ `date +%H` -lt "$do_not_disturb_endtime" ]; do
|
||
enable_detection
|
||
sleep $sleeptime
|
||
done
|
||
# 静默
|
||
elif [ "$do_not_disturb_mode" -eq "2" ] ;then
|
||
disturb_text="【免打扰】"
|
||
return 1
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# 文件锁
|
||
function LockFile(){
|
||
if [ $1 = "lock" ] ;then
|
||
[ ! -f "${dir}wechatpush.lock" ] && > ${dir}wechatpush.lock && return
|
||
while [ -f "${dir}wechatpush.lock" ]; do
|
||
enable_detection 1
|
||
done
|
||
LockFile lock
|
||
fi
|
||
[ $1 = "unlock" ] && rm -f ${dir}wechatpush.lock >/dev/null 2>&1
|
||
return 0
|
||
}
|
||
|
||
# 检测黑白名单
|
||
function blackwhitelist(){
|
||
[ ! "$1" ] && return 1
|
||
|
||
[ -z "$up_down_push_whitelist" ] && [ -z "$up_down_push_blacklist" ] && [ -z "$up_down_push_interface" ] && [ -z "$mac_online_list" ] && [ -z "$mac_offline_list" ] && return 0
|
||
[ ! -z "$up_down_push_whitelist" ] && ( echo "$up_down_push_whitelist"|grep -q -i -w $1 ) && return 1
|
||
[ ! -z "$up_down_push_blacklist" ] && ( ! echo "$up_down_push_blacklist"|grep -q -i -w $1 ) && return 1
|
||
[ ! -z "$up_down_push_interface" ] && ( ! echo `getinterface ${1}`|grep -q -i -w $up_down_push_interface ) && return 1
|
||
[ ! -z "$mac_online_list" ] && [ ! -z "$mac_online_status" ] && return 1
|
||
[ ! -z "$mac_online_list" ] && ( echo "$mac_online_list"|grep -q -i -w $1 ) && return 1
|
||
[ ! -z "$mac_offline_list" ] && [ -z "$mac_online_status" ] && return 1
|
||
|
||
return 0
|
||
}
|
||
|
||
# 重启网络服务
|
||
function network_restart(){
|
||
cat>${dir}network_restart<<EOF
|
||
#!/bin/sh
|
||
/etc/init.d/network restart >/dev/null 2>&1 &
|
||
/etc/init.d/firewall restart >/dev/null 2>&1 &
|
||
/etc/init.d/dnsmasq restart >/dev/null 2>&1 &
|
||
EOF
|
||
chmod 0755 ${dir}network_restart && ${dir}network_restart
|
||
rm -f ${dir}network_restart >/dev/null 2>&1
|
||
}
|
||
|
||
# 查看无人值守任务设备是否在线
|
||
function geterrdevicealiases(){
|
||
[ -z "$unattended_device_aliases" ] && return
|
||
[ -f ${dir}ipAddress ] && local logrow=$(grep -c "" ${dir}ipAddress) || local logrow="0";[ $logrow -eq "0" ] && return
|
||
|
||
local MACLIST=`cat ${dir}ipAddress|awk '{print $2}'|grep -v "^$"|sort -u`
|
||
for mac in $MACLIST; do
|
||
[ -z "$unattended_mac" ] && [ ! -z "$mac" ] && local unattended_mac=`echo "$unattended_device_aliases"|grep -i $mac|grep -v "^$"|sort -u|head -n1`
|
||
done
|
||
# 进入免打扰时间已经超过一小时
|
||
if [ ! -z "$sheep_starttime" ] && [ "$((`date +%s`-$sheep_starttime))" -ge "3600" ]; then
|
||
> ${dir}sheep_usage
|
||
local MACLIST=`echo "$unattended_device_aliases"|grep -v "^$"|sort -u`
|
||
while IFS= read -r mac; do
|
||
[ ! -z "$mac" ] && local tmptotal=`usage get ${mac} bytes`
|
||
[ ! -z "$tmptotal" ] && awk 'BEGIN{printf "%.0f\n",'$tmptotal'/'204800'}' 2>/dev/null >> ${dir}sheep_usage
|
||
done <<< "$MACLIST"
|
||
old_sheep_usage=`cat ${dir}old_sheep_usage` 2>/dev/null
|
||
sheep_usage=`cat ${dir}sheep_usage` 2>/dev/null
|
||
[ "$old_sheep_usage" == "$sheep_usage" ] && [ -z "$sheep_nousage_starttime" ] && sheep_nousage_starttime=`date +%s`
|
||
[ "$old_sheep_usage" != "$sheep_usage" ] && unset sheep_nousage_starttime && cat ${dir}sheep_usage 2>/dev/null > ${dir}old_sheep_usage
|
||
[ ! -z "$sheep_nousage_starttime" ] && [ "$((`date +%s`-$sheep_nousage_starttime))" -ge "300" ] && unset unattended_mac
|
||
fi
|
||
[ -z "$unattended_mac" ]
|
||
}
|
||
|
||
# 无人值守任务
|
||
function unattended(){
|
||
[ -z "$unattended_enable" ] || [ "$unattended_enable" -ne "1" ] && return
|
||
[ ! -z "$unattended_only_on_disturb_time" ] && [ "$unattended_only_on_disturb_time" -eq "1" ] && [ -z "$sheep_starttime" ] && return
|
||
geterrdevicealiases;[ $? -eq "1" ] && return
|
||
|
||
if [ ! -z "$unattended_autoreboot_mode" ]; then
|
||
local interfaceuptime=`getinterfaceuptime`
|
||
if [ ! -z "$autoreboot_system_uptime" ] && [ `cat /proc/uptime|awk -F. '{run_hour=$1/3600;printf("%d",run_hour)}'` -ge "$autoreboot_system_uptime" ] && [ "$unattended_autoreboot_mode" -eq "1" ]; then
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` 【无人值守任务】重启路由器咯" >> ${logfile}
|
||
cat ${logfile} > /usr/share/wechatpush/errlog
|
||
sleep 2 && reboot && exit
|
||
elif [ ! -z "$autoreboot_network_uptime" ] && [ ! -z "$interfaceuptime" ] && [ `echo "$interfaceuptime"|awk -F. '{run_hour=$1/3600;printf("%d",run_hour)}'` -ge "$autoreboot_network_uptime" ] && [ "$unattended_autoreboot_mode" -eq "2" ]; then
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` 【无人值守任务】重新拨号咯" >> ${logfile}
|
||
ifup wan >/dev/null 2>&1
|
||
sleep 60
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# 检测网络状态
|
||
function rand_geturl(){
|
||
# 获取网络状态
|
||
function getcheck(){
|
||
local urllist="https://www.163.com https://www.qq.com https://www.baidu.com https://www.qidian.com https://www.douban.com"
|
||
local url_number=`expr $(echo "$urllist"|grep -o ' '|wc -l) + 1`
|
||
local url_str=`echo "$urllist"|awk -v i=$(rand 1 $url_number) '{print $i}'`
|
||
echo `curl -k -s -w "%{http_code}" -m 5 ${url_str} -A "${User_Agent}" -o /dev/null`
|
||
}
|
||
local check=`getcheck`
|
||
while [ -z "$check" ] || [[ $check -ne 200 && $check -ne 301 && $check -ne 302 ]]; do
|
||
local check=`getcheck`
|
||
if [ ! -z "$check" ] && [[ $check -eq 200 || $check -eq 301 || $check -eq 302 ]]; then
|
||
[ ! -z "$network_enable" ] && [ "$network_enable" -eq "404" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【网络状态】网络恢复正常.." >> ${logfile}
|
||
local network_enable="200"
|
||
else
|
||
[ -z "$network_enable" ] || [ "$network_enable" -eq "200" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】当前网络不通!停止检测! " >> ${logfile}
|
||
local network_enable="404"
|
||
# 无人值守、待弃用或改进
|
||
[ -z "$network_unattended_time" ] && network_unattended_time=`date +%s`
|
||
if [ ! -z "$network_disconnect_event" ] && [ "$((`date +%s`-$network_unattended_time))" -ge "300" ]; then
|
||
> ${dir}send_enable.lock && first && deltemp
|
||
geterrdevicealiases
|
||
if [ "$?" -eq "0" ]; then
|
||
[ -f /usr/share/wechatpush/autoreboot_count ] && retry_count=`cat /usr/share/wechatpush/autoreboot_count` && rm -f /usr/share/wechatpush/autoreboot_count >/dev/null 2>&1
|
||
[ ! -z "${retry_count}" ] && retry_count=0
|
||
retry_count=$((retry_count + 1))
|
||
if [ "$network_disconnect_event" -eq "1" ] ;then
|
||
if [ "$retry_count" -lt "3" ] ;then
|
||
echo "$retry_count" > /usr/share/wechatpush/autoreboot_count
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】正在尝试重启路由,当前第 $retry_count 次 " >> ${logfile}
|
||
cat ${logfile} > /usr/share/wechatpush/errlog
|
||
getgateway "reboot"
|
||
sleep 2 && reboot && exit
|
||
fi
|
||
[ "$retry_count" -eq "3" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】已经重启路由2次,修复失败,请主人自行修复哦" >> ${logfile}
|
||
elif [ "$network_disconnect_event" -eq "2" ] ;then
|
||
[ "$retry_count" -lt "3" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】正在尝试重启网络,当前第 $retry_count 次 " >> ${logfile} && /etc/init.d/network restart >/dev/null 2>&1
|
||
[ "$retry_count" -eq "3" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】已经重启网络2次,修复失败,请主人自行修复哦 " >> ${logfile}
|
||
fi
|
||
fi
|
||
elif [ -f /usr/share/wechatpush/autoreboot_count ]; then
|
||
network_unattended_time=$((network_unattended_time - 300)) && sleep 60
|
||
fi
|
||
enable_detection
|
||
sleep $sleeptime
|
||
fi
|
||
continue
|
||
done
|
||
rm -f /usr/share/wechatpush/autoreboot_count >/dev/null 2>&1
|
||
}
|
||
|
||
# 检测 ip 状况
|
||
function ip_changes(){
|
||
[ "$get_ipv4_mode" -eq "1" ] && local IPv4=`getip wanipv4` && local IPv4_URL="网络接口"
|
||
[ "$get_ipv4_mode" -eq "2" ] && local IPv4=`getip hostipv4` && local IPv4_URL=`echo ${IPv4}|jq -r '.URL'` && local IPv4=`echo ${IPv4}|jq -r '.IP'`
|
||
[ "$get_ipv6_mode" -eq "1" ] && local IPv6=`getip wanipv6` && local IPv6_URL="网络接口"
|
||
[ "$get_ipv6_mode" -eq "2" ] && local IPv6=`getip hostipv6` && local IPv6_URL=`echo ${IPv6}|jq -r '.URL'` && local IPv6=`echo ${IPv6}|jq -r '.IP'`
|
||
|
||
if [ "$1" ] && [ $1 == "getip" ]; then
|
||
echo "IPv4:$IPv4<br/>地址:$(get_ip_attribution $IPv4)<br/>接口:$IPv4_URL<br/>IPv6:$IPv6<br/>地址:$(get_ip_attribution $IPv6)<br/>接口:$IPv6_URL"
|
||
return
|
||
fi
|
||
|
||
# 存在临时文件
|
||
if [ -f ${dir}ip ]; then
|
||
local last_IPv4=$(cat "${dir}ip"|grep IPv4|awk '{print $2}'|grep -v "^$"|sort -u|head -n1)
|
||
local last_IPv6=$(cat "${dir}ip"|grep IPv6|awk '{print $2}'|grep -v "^$"|sort -u|head -n1)
|
||
if [ "$get_ipv4_mode" -ne "0" ] && [ ! -z "$IPv4" ] && ( ! echo ${IPv4}|grep -w -q ${last_IPv4} ); then
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}当前 IP:${IPv4} from:${IPv4_URL}" >> ${logfile}
|
||
echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $last_IPv6 >> ${dir}ip
|
||
title="IP 地址变化"
|
||
content="${content}${str_splitline}${str_title_start} IP 地址变化${str_title_end}${str_linefeed}${str_tab}当前 IP:${IPv4}"
|
||
fi
|
||
|
||
if [ "$get_ipv6_mode" -ne "0" ] && [ ! -z "$IPv6" ] && ( ! echo "$IPv6"|grep -w -q ${last_IPv6} ); then
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}当前 IPv6:${IPv6} from:${IPv6_URL}" >> ${logfile}
|
||
echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $IPv6 >> ${dir}ip
|
||
[ -z "$title" ] && title="IPv6 地址变化"
|
||
[ ! -z "$title" ] && title="IP 地址变化"
|
||
content="${content}${str_splitline}${str_title_start} IPv6 地址变化${str_title_end}${str_linefeed}${str_tab}当前 IPv6:${IPv6}"
|
||
fi
|
||
|
||
# 临时文件目录为空
|
||
else
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}路由器已经重启!" >> ${logfile}
|
||
[ "$get_ipv4_mode" -ne "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}当前 IP: ${IPv4} from:${IPv4_URL}" >> ${logfile}
|
||
[ "$get_ipv6_mode" -ne "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}当前 IPv6: ${IPv6} from:${IPv6_URL}" >> ${logfile}
|
||
echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $IPv6 >> ${dir}ip
|
||
title="路由器重新启动"
|
||
content="${content}${str_splitline}${str_title_start} 路由器重新启动${str_title_end}"
|
||
[ "$get_ipv4_mode" -ne "0" ] && content="${content}${str_linefeed}${str_tab}当前IP:${IPv4}"
|
||
[ "$get_ipv6_mode" -ne "0" ] && content="${content}${str_linefeed}${str_tab}当前IPv6:${IPv6}"
|
||
fi
|
||
|
||
# IP 变化,悄咪咪的重启 zerotier
|
||
if [ ! -z "$content" ] && [ -n "$zerotier_helper" ] && [ "$zerotier_helper" -eq "1" ];then
|
||
[ -z "$zerotier_enabled" ] && zerotier_enabled=$(uci get zerotier.sample_config.enabled)
|
||
if [ ! -z "$zerotier_enabled" ] && [ $zerotier_enabled -eq "1" ] ; then
|
||
/etc/init.d/zerotier restart >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# 检测设备上线
|
||
function up(){
|
||
[ -f ${dir}ipAddress ] && ( cat ${dir}ipAddress|grep -q -w $1 ) && return
|
||
|
||
local ip_mac=`getmac $1`
|
||
local ip_name=`getname ${1} ${ip_mac}`
|
||
local ip_interface=`getinterface ${ip_mac}`
|
||
getping ${1} ${ip_mac} ${up_timeout} "1";local ping_online=$?
|
||
|
||
# 连通
|
||
if [ "$ping_online" -eq "0" ]; then
|
||
LockFile lock
|
||
[ ! -z "$up_down_push_blacklist" ] && local tmp_mac=`echo "${up_down_push_blacklist}"|grep -w -i ${ip_mac}`
|
||
[ ! -z "$up_down_push_whitelist" ] && local tmp_mac=`echo "${up_down_push_whitelist}"|grep -w -i ${ip_mac}`
|
||
echo "{'ip': '${1}','mac': '${ip_mac}','name': '${ip_name}','uptime': '0秒','interface': '${ip_interface}','usage': ''}" > ${dir}client/${1}
|
||
# ???
|
||
if [ ! -z "$tmp_mac" ] && ( cat ${dir}ipAddress|grep -q -w -i ${tmp_mac} ); then
|
||
usage down ${1}
|
||
echo "${1} ${ip_mac} ${ip_name// /_} `date +%s` ${ip_interface}" >> ${dir}ipAddress
|
||
LockFile unlock && return
|
||
# ???
|
||
elif [ ! -z "$tmp_mac" ] && [ -f "${dir}tmp_downlist" ] && ( cat ${dir}tmp_downip|grep -q -w -i ${tmp_mac} ); then
|
||
local tmp_downip=`cat ${dir}tmp_downlist|grep -w -i ${tmp_mac}|awk '{print $1}'|grep -v "^$"|sort -u|head -n1`
|
||
usage down $tmp_downip
|
||
sed -i "/^${tmp_downip} /d" ${dir}tmp_downlist
|
||
LockFile unlock && return
|
||
fi
|
||
# 从离线二次验证区恢复信息
|
||
[ -f "${dir}tmp_downlist" ] && local tmp_downip=`cat ${dir}tmp_downlist|grep -w ${1}|grep -v "^$"|sort -u|head -n1`
|
||
if [ ! -z "$tmp_downip" ]; then
|
||
cat ${dir}tmp_downlist|grep -w ${1}|grep -v "^$"|sort -u|head -n1 >> ${dir}ipAddress
|
||
sed -i "/^${1} /d" ${dir}tmp_downlist
|
||
# up
|
||
else
|
||
usage down $1
|
||
echo "$1 ${ip_mac} ${ip_name// /_} `date +%s` ${ip_interface}" >> ${dir}ipAddress
|
||
blackwhitelist ${ip_mac};local ip_blackwhite=$?
|
||
[ -f "${dir}send_enable.lock" ] || [ -z "$notification_online" ] || [ -z "$ip_blackwhite" ] && LockFile unlock && return
|
||
[ -z "$ip_blackwhite" ] || [ "$ip_blackwhite" -ne "0" ] && LockFile unlock && return
|
||
|
||
[ -f "${dir}title" ] && local title=`cat ${dir}title`
|
||
[ -f "${dir}content" ] && local content=`cat ${dir}content`
|
||
if [ -z "$title" ]; then
|
||
local title="$ip_name 连接了你的路由器"
|
||
local content="${str_splitline}${str_title_start} 新设备连接${str_title_end}${str_linefeed}${str_tab}客户端名:${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP: ${str_space}${str_space}${str_space}${str_space}${1}${str_linefeed}${str_tab}客户端MAC:${str_space}${str_space}${str_space}${str_space}${ip_mac}${str_linefeed}${str_tab}网络接口:${str_space}${str_space}${str_space}${str_space}${str_space}${ip_interface}"
|
||
elif ( echo ${title}|grep -q "连接了你的路由器" ); then
|
||
local title="${ip_name} ${title}"
|
||
local content="${str_splitline}${str_tab}客户端名:${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP: ${str_space}${str_space}${str_space}${str_space}${1}${str_linefeed}${str_tab}客户端MAC:${str_space}${str_space}${str_space}${str_space}${ip_mac}${str_linefeed}${str_tab}网络接口:${str_space}${str_space}${str_space}${str_space}${str_space}${ip_interface}"
|
||
else
|
||
local title="设备状态变化"
|
||
local content="${str_splitline}${str_title_start} 新设备连接${str_title_end}${str_linefeed}${str_tab}客户端名:${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP: ${str_space}${str_space}${str_space}${str_space}${1}${str_linefeed}${str_tab}客户端MAC:${str_space}${str_space}${str_space}${str_space}${ip_mac}${str_linefeed}${str_tab}网络接口:${str_space}${str_space}${str_space}${str_space}${str_space}${ip_interface}"
|
||
fi
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}新设备 ${ip_name} ${1} 连接了">> ${logfile}
|
||
#[ ! -z "$up_down_push_blacklist" ] && local title="你偷偷关注的设备上线了"
|
||
[ ! -z "$title" ] && echo "$title" >${dir}title
|
||
[ ! -z "$content" ] && echo -n "$content" >>${dir}content
|
||
fi
|
||
fi
|
||
LockFile unlock
|
||
}
|
||
|
||
# 检测设备离线
|
||
function down(){
|
||
local ip_mac=`getmac $1`
|
||
local ip_name=`getname ${1} ${ip_mac}`
|
||
local ip_interface=`getinterface ${ip_mac}`
|
||
|
||
tmp_timeout=$down_timeout && tmp_retry_count=$timeout_retry_count
|
||
[ -n "$only_timeout_push" ] && blackwhitelist ${ip_mac};local ip_blackwhite=$? && [ "$ip_blackwhite" -ne "0" ] && tmp_timeout=10 && tmp_retry_count=2
|
||
getping ${1} ${ip_mac} ${tmp_timeout} ${tmp_retry_count};local ping_online=$?
|
||
# 离线,置入二次验证区
|
||
if [ "$ping_online" -eq "1" ]; then
|
||
LockFile lock
|
||
[ ! -f "${dir}send_enable.lock" ] && cat ${dir}ipAddress|grep -w ${1}|grep -v "^$"|sort -u|head -n1 >> ${dir}tmp_downlist
|
||
sed -i "/^${1} /d" ${dir}ipAddress
|
||
rm -f ${dir}client/${1} >/dev/null 2>&1
|
||
LockFile unlock
|
||
# 更新主机名或 MAC
|
||
else
|
||
local tmp_name=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $3}'|grep -v "^$"|sort -u|head -n1`
|
||
local tmp_mac=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $2}'|grep -v "^$"|sort -u|head -n1`
|
||
if [ ${ip_name// /_} != ${tmp_name} ] || [ ${ip_mac} != ${tmp_mac} ]; then
|
||
LockFile lock
|
||
olduptime=$(cat ${dir}ipAddress|grep -w ${1}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1)
|
||
sed -i "/^${1} /d" ${dir}ipAddress
|
||
[ ${ip_mac} != ${tmp_mac} ] && ip_name="unknown" # MAC 变化时应删除主机名重新获取
|
||
echo "$1 ${ip_mac} ${ip_name// /_} ${olduptime} ${ip_interface}" >> ${dir}ipAddress
|
||
LockFile unlock
|
||
fi
|
||
local time_up=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1`
|
||
local time1=`date +%s`
|
||
local time1=$(time_for_humans `expr ${time1} - ${time_up}`)
|
||
echo "{'ip': '${1}','mac': '${ip_mac}','name': '${ip_name}','uptime': '${time1}','interface': '${ip_interface}','usage': '`usage get $ip_mac`'}" > ${dir}client/${1}
|
||
fi
|
||
}
|
||
|
||
# 设备离线通知
|
||
function down_send(){
|
||
[ ! -f "${dir}tmp_downlist" ] && return
|
||
|
||
local IPLIST=`cat ${dir}tmp_downlist|awk '{print $1}'`
|
||
for ip in $IPLIST; do
|
||
local ip_mac=`getmac ${ip}`
|
||
blackwhitelist ${ip_mac};local ip_blackwhite=$?
|
||
[ -z "$notification_offline" ] || [ -z "$ip_blackwhite" ] && continue
|
||
[ -z "$ip_blackwhite" ] || [ "$ip_blackwhite" -ne "0" ] && continue
|
||
[ ! -z "$up_down_push_blacklist" ] && local tmp_mac=`echo "${up_down_push_blacklist}"|grep -w -i ${ip_mac}`
|
||
[ ! -z "$up_down_push_whitelist" ] && local tmp_mac=`echo "${up_down_push_whitelist}"|grep -w -i ${ip_mac}`
|
||
[ ! -z "$tmp_mac" ] && ( cat ${dir}ipAddress|grep -q -w -i ${tmp_mac} ) && continue
|
||
|
||
local ip_name=`getname ${ip} ${ip_mac}`
|
||
local time_up=`cat ${dir}tmp_downlist|grep -w ${ip}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1`
|
||
local ip_total=`usage get $ip_mac` && [ ! -z "$ip_total" ] && local ip_total="${str_linefeed}${str_tab}总计流量: ${str_space}${str_space}${str_space}${str_space}${ip_total}"
|
||
local time1=`date +%s`
|
||
local time1=$(time_for_humans `expr ${time1} - ${time_up}`)
|
||
if [ -z "$title" ]; then
|
||
title="${ip_name} 断开连接"
|
||
content="${content}${str_splitline}${str_title_start} 设备断开连接${str_title_end}${str_linefeed}${str_tab}客户端名:${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP: ${str_space}${str_space}${str_space}${str_space}${ip}${str_linefeed}${str_tab}客户端MAC:${str_space}${str_space}${str_space}${str_space}${ip_mac}$ip_total${str_linefeed}${str_tab}在线时间: ${str_space}${str_space}${str_space}${str_space}${time1}"
|
||
elif ( echo "$title"|grep -q "断开连接" ); then
|
||
title="${ip_name} ${title}"
|
||
content="${content}${str_splitline}${str_tab}客户端名:${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP: ${str_space}${str_space}${str_space}${str_space}${ip}${str_linefeed}${str_tab}客户端MAC:${str_space}${str_space}${str_space}${str_space}${ip_mac}$ip_total${str_linefeed}${str_tab}在线时间: ${str_space}${str_space}${str_space}${str_space}${time1}"
|
||
else
|
||
title="设备状态变化"
|
||
content="${content}${str_splitline}${str_title_start} 设备断开连接${str_title_end}${str_linefeed}${str_tab}客户端名:${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}${str_linefeed}${str_tab}客户端IP: ${str_space}${str_space}${str_space}${str_space}${ip}${str_linefeed}${str_tab}客户端MAC:${str_space}${str_space}${str_space}${str_space}${ip_mac}$ip_total${str_linefeed}${str_tab}在线时间: ${str_space}${str_space}${str_space}${str_space}${time1}"
|
||
fi
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}设备 ${ip_name} ${ip} 断开连接 " >> ${logfile}
|
||
done
|
||
|
||
rm -f ${dir}tmp_downlist >/dev/null 2>&1
|
||
}
|
||
|
||
# 当前设备列表
|
||
function current_device(){
|
||
( echo "$lite_enable"|grep -q "content" ) || ( echo "$lite_enable"|grep -q "device" ) && return
|
||
[ -f ${dir}ipAddress ] && local logrow=$(grep -c "" ${dir}ipAddress) || local logrow="0";[ $logrow -eq "0" ] && return
|
||
|
||
[ -f ${dir}usage.db ] && local ip_total_db="总计流量${str_space}${str_space}${str_space}${str_space}"
|
||
content="${content}${str_splitline}${str_title_start} 现有在线设备 ${logrow} 台,具体如下${str_title_end}${str_linefeed}${str_tab}IP 地址${str_space}${str_space}${str_space}${str_space}${str_space}${str_space}${str_space}${str_space}${str_space}${ip_total_db}客户端名"
|
||
local IPLIST=`cat ${dir}ipAddress|awk '{print $1}'`
|
||
for ip in $IPLIST; do
|
||
local ip_mac=`getmac ${ip}`
|
||
local ip_total=`usage get ${ip_mac}`
|
||
local ip_name=`getname ${ip} ${ip_mac}`
|
||
local ip_name=`cut_str "$ip_name" "15"`
|
||
if [ "${#ip}" -lt "15" ]; then
|
||
local n=`expr 15 - ${#ip}`
|
||
for i in `seq 1 $n`; do
|
||
local ip="${ip}${str_space}"
|
||
done
|
||
unset i n
|
||
fi
|
||
if [ ! -z "$ip_total" ]; then
|
||
local n=`expr 11 - ${#ip_total}`
|
||
for i in `seq 1 $n`; do
|
||
local ip_total="${ip_total}${str_space}"
|
||
done
|
||
fi
|
||
content="${content}${str_linefeed}${str_tab}${ip}${ip_total}${ip_name}"
|
||
unset i n ip_total ip_mac ip_name
|
||
done
|
||
}
|
||
|
||
# 检测 cpu 状态
|
||
function cpu_load(){
|
||
if [ -n "$notification_temp" ] && [ -n "$temperature_threshold" ]; then
|
||
[ -z "$temp_last_overload_time" ] && temp_last_overload_time=`date +%s`
|
||
local cpu_temp=`soc_temp`;
|
||
|
||
if [ ! -z "$cpu_temp" ] && [ `expr $cpu_temp \> $temperature_threshold` -eq "1" ]; then
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!警报!!】 CPU 温度过高: ${cpu_temp}" >> ${logfile}
|
||
else
|
||
temp_last_overload_time=`date +%s`
|
||
fi
|
||
|
||
if [ ! -z "$cpu_temp" ] && [ "$((`date +%s`-$temp_last_overload_time))" -ge "300" ] && [ -z "$temperaturecd_time" ]; then
|
||
title="CPU 温度过高!"
|
||
temperaturecd_time=`date +%s`
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text} CPU 温 度过高: ${cpu_temp}" >> ${logfile}
|
||
content="${content}${str_splitline}${str_title_start} CPU 温度过高${str_title_end}${str_linefeed}${str_tab}CPU 温度已连续五分钟超过预设${str_linefeed}${str_tab}接下来一小 时不再提示${str_linefeed}${str_tab}当前温度:${cpu_temp}℃"
|
||
elif [ ! -z "$temperaturecd_time" ] && [ "$((`date +%s`-$temperaturecd_time))" -ge "3300" ] ;then
|
||
unset temperaturecd_time
|
||
fi
|
||
fi
|
||
|
||
if [ -n "$notification_load" ] && [ -n "$cpu_load_threshold" ]; then
|
||
[ -z "$cpu_last_overload_time" ] && cpu_last_overload_time=`date +%s`
|
||
local cpu_fuzai=`cat /proc/loadavg|awk '{print $1}'` 2>/dev/null
|
||
|
||
if [ ! -z "$cpu_fuzai" ] && [ `expr $cpu_fuzai \> $cpu_load_threshold` -eq "1" ]; then
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!警报!!】 CPU 负载过高: ${cpu_fuzai}" >> ${logfile}
|
||
cputop log
|
||
elif [ ! -z "$cpu_fuzai" ]; then
|
||
cpu_last_overload_time=`date +%s`
|
||
fi
|
||
|
||
if [ ! -z "$cpu_fuzai" ] && [ "$((`date +%s`-$cpu_last_overload_time))" -ge "300" ] && [ -z "$cpucd_time" ]; then
|
||
unset getlogtop
|
||
if [ ! -z "$title" ] && ( echo "$title"|grep -q "过高" ); then
|
||
title="设备报警!"
|
||
else
|
||
title="CPU 负载过高!"
|
||
fi
|
||
cpucd_time=`date +%s`
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text} CPU 负 载过高: ${cpu_fuzai}" >> ${logfile}
|
||
content="${content}${str_splitline}${str_title_start} CPU 负载过高${str_title_end}${str_linefeed}${str_tab}CPU 负载已连续五分钟超过预设${str_linefeed}${str_tab}接下来一小 时不再提示${str_linefeed}${str_tab}当前负载:${cpu_fuzai}"
|
||
cputop
|
||
elif [ ! -z "$cpucd_time" ] && [ "$((`date +%s`-$cpucd_time))" -ge "3300" ] ;then
|
||
unset cpucd_time
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# CPU 占用前三
|
||
function cputop(){
|
||
[ -z "$1" ] && content="${content}${str_splitline}${str_title_start} 当前 CPU 占用前三的进程${str_title_end}"
|
||
local gettop=`top -bn 1|grep -v "top -bn 1"`
|
||
for i in `seq 5 7`; do
|
||
local top_name=`echo "${gettop}"|awk 'NR=='${i}|awk '{print ($8 ~ /\/bin\/sh|\/bin\/bash/) ? $9 : $8}'`
|
||
local top_load=`echo "${gettop}"|awk 'NR=='${i}|awk '{print $7}'`
|
||
local temp_top="${top_name} ${top_load}"
|
||
[ ! -z "$1" ] && local logtop="$logtop $temp_top"
|
||
[ -z "$1" ] && content="${content}${str_linefeed}${str_tab}${temp_top}"
|
||
done
|
||
unset i
|
||
[ ! -z "$1" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!警报!!】 CPU 占用前三: ${logtop}" >> ${logfile}
|
||
}
|
||
|
||
# 检测硬盘状态
|
||
function get_disk() {
|
||
mkdir -p "${dir}disk_info"
|
||
local_disk_names=()
|
||
pve_disk_names=()
|
||
|
||
# 查询本地硬盘名
|
||
local_disk_names=($(lsblk 2>/dev/null | awk '$NF=="disk" {print $1}' | sort -u))
|
||
# 如未安装 lsblk,查找以 /dev/ 开头,但挂载点不是根目录 / 的设备,然后提取硬盘的名称(准确性较低)
|
||
[ -z "$local_disk_names" ] && local_disk_names=($(df -h 2>/dev/null | awk '$1 ~ /^\/dev/ {if ($NF ~ /^\/[a-zA-Z0-9]/) { sub("/dev/", "", $1); sub(/[0-9]+$/, "", $1); print $1 }}'))
|
||
local_disk_tags=($(for _ in "${local_disk_names[@]}"; do echo "local"; done))
|
||
|
||
# 查询远程硬盘名
|
||
if [ -n "$server_host" ]; then
|
||
ssh_command="ssh -o StrictHostKeyChecking=yes -o BatchMode=yes -i /root/.ssh/id_rsa root@${server_host} -p ${server_port}"
|
||
pve_disk_names=($(eval ${ssh_command} lsblk | awk '$NF=="disk" {print $1}' | sort -u))
|
||
pve_disk_tags=($(for _ in "${pve_disk_names[@]}"; do echo "pve"; done))
|
||
fi
|
||
|
||
# 合并本地和远程硬盘名及标记
|
||
all_disk_names=("${local_disk_names[@]}" "${pve_disk_names[@]}")
|
||
all_disk_tags=("${local_disk_tags[@]}" "${pve_disk_tags[@]}")
|
||
|
||
for i in "${!all_disk_names[@]}"; do
|
||
tmp_name=${all_disk_names[i]}
|
||
tmp_tag=${all_disk_tags[i]}
|
||
error_pattern="No such device|Unable to detect device type|Unknown USB bridge|QEMU HARDDISK"
|
||
unset tmp_command disk_type disk_err
|
||
|
||
# 判断硬盘类型
|
||
if [ "$tmp_tag" == "pve" ]; then
|
||
tmp_command="$ssh_command"
|
||
disk_type="_pve"
|
||
fi
|
||
file_path="${dir}disk_info/${tmp_name}${disk_type}"
|
||
|
||
# 如果不能获取值,使用分区名重试(因为不清楚是 OpenWrt 的原因还是 smartctl 版本的原因,使用出错重试的方式)
|
||
eval ${tmp_command} smartctl -i -n standby "/dev/${tmp_name}" 2>/dev/null | grep -qE "$error_pattern" && {
|
||
tmp_name=$(eval ${tmp_command} df -h | awk "/^\\/dev\\/${tmp_name}/ {print \$1}" | awk -F '/' '{print $NF}' | head -n1)
|
||
[ -z "$tmp_name" ] && continue
|
||
}
|
||
|
||
# 手上的硬盘不能休眠,不确定命令是否会唤醒硬盘,每天只运行一次
|
||
last_disk_time=$(date -r "${file_path}" +%s 2>/dev/null) || last_disk_time=0
|
||
|
||
if [ $(( $(date +%s) - $last_disk_time )) -gt 86000 ]; then
|
||
disk_info=$(eval ${tmp_command} smartctl -i -n standby "/dev/${tmp_name}" 2>/dev/null)
|
||
echo "$disk_info" | grep -qE "$error_pattern" && {
|
||
continue
|
||
} || \
|
||
echo "$disk_info" | grep -q "STANDBY" && {
|
||
echo "$disk_info" > "${file_path}"
|
||
} || \
|
||
eval ${tmp_command} smartctl -a -j /dev/${tmp_name} 2>/dev/null> ${file_path}
|
||
fi
|
||
|
||
# 硬盘状态
|
||
if [ -f "${file_path}" ] && [ -s "${file_path}" ] && ( ! cat "${file_path}" | grep -q -v "STANDBY" ); then
|
||
disk_name=$(awk '/Device Model/{print $NF}' "$file_path")
|
||
[[ -n $disk_name && $disk_name != null && $disk_name != 0 ]] && {
|
||
disk_name=$(cut_str "$disk_name" "20")
|
||
disk_name="${disk_name}_$(eval ${tmp_command} lsblk -o NAME,SIZE | awk "/^${all_disk_names[i]}/ {print \$NF}")"
|
||
}
|
||
printf "${str_linefeed}${str_title_start} 硬盘名称:${disk_name}${disk_type}${str_title_end}${str_linefeed}${str_tab}硬盘休眠中" >> "$output_dir/get_disk"
|
||
elif [ -f "${file_path}" ]; then
|
||
# 硬盘名称
|
||
disk_name=$(jq -r .model_name ${file_path})
|
||
[ -z "$disk_name" ] && disk_name=$(cat /sys/block/"${all_disk_names[i]}"/device/model)
|
||
[[ -n $disk_name && $disk_name != null && $disk_name != 0 ]] && {
|
||
disk_name=$(cut_str "$disk_name" "20")
|
||
disk_size=$(eval ${tmp_command} lsblk -o NAME,SIZE 2>/dev/null | awk "/^${all_disk_names[i]}/ {print \$NF}")
|
||
[ -z "$disk_size" ] && disk_size=$(eval ${tmp_command} df -h 2>/dev/null | awk -v tmp_disk_name="${all_disk_names[i]}" '$1 ~ "^/dev/"tmp_disk_name {print $2}')
|
||
disk_name="${disk_name}_${disk_size}"
|
||
}
|
||
printf "${str_linefeed}${str_title_start} 硬盘名称:${disk_name}${disk_type}${str_title_end}" >> "$output_dir/get_disk"
|
||
# 硬盘温度
|
||
disk_temp=$(jq -r .temperature.current ${file_path})
|
||
[[ -n $disk_temp && $disk_temp != null && $disk_temp != 0 ]] && printf "${str_linefeed}${str_tab}硬盘温度:${disk_temp}℃" >> "$output_dir/get_disk"
|
||
# 通电时间
|
||
disk_time=$(jq -r .power_on_time.hours ${file_path})
|
||
[[ -n $disk_time && $disk_time != null ]] && printf "${str_linefeed}${str_tab}通电时间:${disk_time}h" >> "$output_dir/get_disk"
|
||
# 空间使用
|
||
disk_use=$(eval ${tmp_command} lsblk -o NAME,FSUSE%,TYPE 2>/dev/null | awk -v part_name="${all_disk_names[i]}" '$NF == "part" && $1 ~ part_name && NF > 2 {sub(".*" part_name, part_name, $1); printf "%s: %s ", $1, $2} END {print ""}')
|
||
[ -z "$disk_use" ] && disk_use=$(eval ${tmp_command} df -h 2>/dev/null | awk -v part_name="${all_disk_names[i]}" '$1 ~ "^/dev/"part_name && NF > 1 {sub("/dev/", "", $1); sub(/[0-9]+$/, "", $1); printf "%s: %s ", $1, $5} END {print ""}')
|
||
[ -n "$disk_use" ] && [ -n "${disk_use// }" ] && echo -e -n "${str_linefeed}${str_tab}空间使用:${disk_use}" >> "$output_dir/get_disk"
|
||
# 寿命使用
|
||
disk_health=$(jq -r .nvme_smart_health_information_log.percentage_used ${file_path})
|
||
[[ -n $disk_health && $disk_health != null ]] && echo -e -n "${str_linefeed}${str_tab}寿命使用:${disk_health}%" >> "$output_dir/get_disk"
|
||
# 错误日志
|
||
disk_log_err=$(jq -r .ata_smart_error_log.summary.count ${file_path})
|
||
[[ -n $disk_log_err && $disk_log_err != null && $disk_log_err != 0 ]] && disk_err="true" && printf "${str_linefeed}${str_tab}错误日志:${disk_log_err}" >> "$output_dir/get_disk"
|
||
# 自检错误
|
||
disk_test_err=$(jq -r .ata_smart_self_test_log.standard.error_count_total ${file_path})
|
||
[[ -n $disk_test_err && $disk_test_err != null && $disk_test_err != 0 ]] && disk_err="true" && printf "${str_linefeed}${str_tab}自检错误:${disk_test_err}" >> "$output_dir/get_disk"
|
||
# 0E 错误
|
||
disk_0e_err=$(jq -r .nvme_smart_health_information_log.media_errors ${file_path})
|
||
[[ -n $disk_0e_err && $disk_0e_err != null && $disk_0e_err != 0 ]] && disk_err="true" && printf "${str_linefeed}${str_tab}0E 错误:${disk_0e_err}" >> "$output_dir/get_disk"
|
||
# 整体健康
|
||
smart_status=$(jq -r .smart_status.passed ${file_path})
|
||
[[ -n $smart_status && $smart_status != null && $smart_status != "true" ]] && {
|
||
echo -e -n "${str_linefeed}${str_tab}${str_title_start}硬盘整体健康评估不通过!!!${str_title_end}" >> "$output_dir/get_disk"
|
||
disk_err="true"
|
||
}
|
||
[ -n "$disk_err" ] && echo -e -n "${str_linefeed}${str_tab}${str_title_start}硬盘存在错误,请及时备份数据!!!${str_title_end}" >> "$output_dir/get_disk"
|
||
fi
|
||
done
|
||
}
|
||
|
||
|
||
# 查询 IP 归属地
|
||
function get_ip_attribution(){
|
||
ip="$1"
|
||
[ -f ${dir}ipAddress ] && ( cat ${dir}ipAddress|grep -q -w -i "$ip" ) && echo "本地局域网" && return
|
||
ip_attribution_urls=$(cat /usr/share/wechatpush/api/ip_attribution.list)
|
||
while IFS= read -r ip_attribution_command; do
|
||
local login_ip_attribution=$(eval "$ip_attribution_command" 2>/dev/null)
|
||
[ "$login_ip_attribution" == "null" ] && unset login_ip_attribution
|
||
[ -n "$login_ip_attribution" ] && break
|
||
done <<< "$ip_attribution_urls"
|
||
echo "$login_ip_attribution"
|
||
}
|
||
|
||
# 登录提醒通知
|
||
function login_send(){
|
||
[ -n "$login_web_black" ] && [ "$login_web_black" -eq "1" ] && init_ip_black "ipv4"
|
||
[ -n "$login_web_black" ] && [ "$login_web_black" -eq "1" ] && init_ip_black "ipv6"
|
||
[ -n "$port_knocking_enable" ] && [ "$port_knocking_enable" -eq "1" ] && init_ip_white "ipv4"
|
||
[ -n "$port_knocking_enable" ] && [ "$port_knocking_enable" -eq "1" ] && init_ip_white "ipv6"
|
||
tmp_ip_list=`echo "$login_ip_white_list"|grep -v "^$"|sort -u`
|
||
while IFS= read -r tmp_ip; do
|
||
[ -n "$tmp_ip" ] && add_ip_white "$tmp_ip" "0"
|
||
done <<< "$tmp_ip_list"
|
||
[ -z "$web_logged" ] && [ -z "$ssh_logged" ] && [ -z "$web_login_failed" ] && [ -z "$ssh_login_failed" ] && return
|
||
set_ip_black
|
||
sys_log=$(logread notice)
|
||
|
||
# Web 登录提醒
|
||
[ -f ${dir}web_login ] && for login_ip in `cat ${dir}web_login | sort -u`; do
|
||
[ -z "$login_ip" ] && continue
|
||
local login_time=$(echo "$sys_log" | grep -w ${login_ip} | awk '{print $4}' | tail -n 1)
|
||
local login_mode=$(echo "$sys_log" | grep -w ${login_ip} | awk '{print $13}' | tail -n 1)
|
||
unset log_only content_attribution content_mode
|
||
echo "$login_ip_white_list" | grep -w -q "$login_ip" && log_only="1" && [ -n "$login_log_enable" ] && continue
|
||
if [ -z "$log_only" ] && [ ! -z "$login_disturb" ] && [ "$login_disturb" -eq "2" ]; then
|
||
[ -f "$logfile" ] && login_log=$(grep -w "$login_ip" "$logfile" | grep -v "\【info\】" | tail -n 1)
|
||
[ ! -z "$login_log" ] && log_timestamp=$(date -d "$(echo "$login_log" | awk '{print $1, $2}')" +%s) || log_timestamp=0
|
||
[ $(($(date +%s) - log_timestamp)) -lt $login_notification_delay ] && log_only="1" && [ -n "$login_log_enable" ] && continue
|
||
fi
|
||
[ -n "$log_only" ] && echo "`date "+%Y-%m-%d"` ${login_time} 【info】设备 ${login_ip} 通过 Web ${login_mode} 登录了路由器 " >> ${logfile} && continue
|
||
|
||
local login_ip_attribution=$(get_ip_attribution ${login_ip})
|
||
[ -n "$login_ip_attribution" ] && content_attribution="${str_linefeed}${str_tab}IP 归属地: ${str_space}${str_space}${str_space}${str_space}${login_ip_attribution}"
|
||
[ -n "$login_mode" ] && content_mode="${str_linefeed}${str_tab}登录方式: ${str_space}${str_space}${str_space}${str_space}${login_mode}"
|
||
if { [ -z "$login_disturb" ] || [ "$login_disturb" -ne "1" ]; }; then
|
||
if [ -z "$title" ]; then
|
||
title="${login_ip} 通过 Web 登录了路由器"
|
||
content="${content}${str_splitline}${str_title_start} 登录信息${str_title_end}${str_linefeed}${str_tab}时间:${str_space}${str_space}${str_space}${str_space}${str_space}${login_time}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_attribution}${content_mode}"
|
||
elif ( echo "$title"|grep -q "登录了路由器" ); then
|
||
title="${login_ip} ${title}"
|
||
content="${content}${str_splitline}${str_tab}时间:${str_space}${str_space}${str_space}${str_space}${str_space}${login_time}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_attribution}${content_mode}"
|
||
else
|
||
title="${login_ip} 通过 Web 登录了路由器"
|
||
content="${content}${str_splitline}${str_title_start} 登录信息${str_title_end}${str_linefeed}${str_tab}时间:${str_space}${str_space}${str_space}${str_space}${str_space}${login_time}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_attribution}${content_mode}"
|
||
fi
|
||
fi
|
||
echo "`date "+%Y-%m-%d"` ${login_time} ${disturb_text}设备 ${login_ip} (${login_ip_attribution}) 通过 Web ${login_mode} 登录了路由器 " >> ${logfile}
|
||
done
|
||
rm -f ${dir}web_login >/dev/null 2>&1
|
||
unset login_ip login_time login_mode
|
||
# SSH 登录提醒
|
||
[ -f ${dir}ssh_login ] && for login_ip in `cat ${dir}ssh_login | sort -u`; do
|
||
[ -z "$login_ip" ] && continue
|
||
local login_time=$(echo "$sys_log" | grep -w ${login_ip} | awk '{print $4}' | tail -n 1)
|
||
local login_mode=$(echo "$sys_log" | grep -w ${login_ip} | awk '{print $8}' | tail -n 1)
|
||
unset log_only content_attribution content_mode
|
||
echo "$login_ip_white_list"|grep -w -q "$login_ip" && log_only="1" && [ -n "$login_log_enable" ] && continue
|
||
if [ -z "$log_only" ] && [ ! -z "$login_disturb" ] && [ "$login_disturb" -eq "2" ]; then
|
||
[ -f "$logfile" ] && login_log=$(grep -w "$login_ip" "$logfile" | grep -v "\【info\】" | tail -n 1)
|
||
[ ! -z "$login_log" ] && log_timestamp=$(date -d "$(echo "$login_log" | awk '{print $1, $2}')" +%s) || log_timestamp=0
|
||
[ $(($(date +%s) - log_timestamp)) -lt $login_notification_delay ] && log_only="1" && [ -n "$login_log_enable" ] && continue
|
||
fi
|
||
[ -n "$log_only" ] && echo "`date "+%Y-%m-%d"` ${login_time} 【info】设备 ${login_ip} 通过 SSH ${login_mode} 登录了路由器 " >> ${logfile} && continue
|
||
|
||
local login_ip_attribution=$(get_ip_attribution ${login_ip})
|
||
[ -n "$login_ip_attribution" ] && content_attribution="${str_linefeed}${str_tab}IP 归属地: ${str_space}${str_space}${str_space}${str_space}${login_ip_attribution}"
|
||
[ ! -z "$login_mode" ] && content_mode="${str_linefeed}${str_tab}登录方式: ${str_space}${str_space}${str_space}${str_space}${login_mode}"
|
||
if { [ -z "$login_disturb" ] || [ "$login_disturb" -ne "1" ]; }; then
|
||
if [ -z "$title" ]; then
|
||
title="${login_ip} 通过 SSH 登录了路由器"
|
||
content="${content}${str_splitline}${str_title_start} 登录信息${str_title_end}${str_linefeed}${str_tab}时间:${str_space}${str_space}${str_space}${str_space}${str_space}${login_time}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_attribution}${content_mode}"
|
||
elif ( echo "$title"|grep -q "登录了路由器" ); then
|
||
title="${login_ip} ${title}"
|
||
content="${content}${str_splitline}${str_tab}时间:${str_space}${str_space}${str_space}${str_space}${str_space}${login_time}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_attribution}${content_mode}"
|
||
else
|
||
title="${login_ip} 通过 SSH 登录了路由器"
|
||
content="${content}${str_splitline}${str_title_start} 登录信息${str_title_end}${str_linefeed}${str_tab}时间:${str_space}${str_space}${str_space}${str_space}${str_space}${login_time}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_attribution}${content_mode}"
|
||
fi
|
||
fi
|
||
echo "`date "+%Y-%m-%d"` ${login_time} ${disturb_text}设备 ${login_ip} (${login_ip_attribution}) 通过 SSH ${login_mode} 登录了路由器 " >> ${logfile}
|
||
done
|
||
rm -f ${dir}ssh_login >/dev/null 2>&1
|
||
unset login_ip login_time login_mode
|
||
# Web 非法登录
|
||
[ -f ${dir}web_failed ] && for login_ip in `cat ${dir}web_failed | sort -u`; do
|
||
[ -z "$login_ip" ] && continue
|
||
local login_ip_attribution=$(get_ip_attribution ${login_ip})
|
||
[ -n "$login_ip_attribution" ] && content_attribution="${str_linefeed}${str_tab}IP 归属地: ${str_space}${str_space}${str_space}${str_space}${login_ip_attribution}" || unset content_attribution
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】设备 ${login_ip} (${login_ip_attribution}) 通过 Web 频繁尝试登录" >> ${logfile}
|
||
[ -n "$login_disturb" ] && [ "$login_disturb" -eq "1" ] && continue
|
||
if [ -z "$title" ]; then
|
||
title="${login_ip} 通过 Web 频繁尝试登录"
|
||
content="${content}${str_splitline}${str_title_start} 登录信息${str_title_end}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_attribution}"
|
||
elif ( echo "$title"|grep -q "频繁尝试登录" ); then
|
||
title="${login_ip} ${title}"
|
||
content="${content}${str_splitline}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_attribution}"
|
||
else
|
||
title="设备状态变化"
|
||
content="${content}${str_splitline}${str_title_start} 登录信息${str_title_end}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_attribution}"
|
||
fi
|
||
done
|
||
rm -f ${dir}web_failed >/dev/null 2>&1
|
||
unset login_ip
|
||
# SSH 非法登录
|
||
[ -f ${dir}ssh_failed ] && for login_ip in `cat ${dir}ssh_failed | sort -u`; do
|
||
[ -z "$login_ip" ] && continue
|
||
local login_ip_attribution=$(get_ip_attribution ${login_ip})
|
||
[ -n "$login_ip_attribution" ] && content_attribution="${str_linefeed}${str_tab}IP 归属地: ${str_space}${str_space}${str_space}${str_space}${login_ip_attribution}" || unset content_attribution
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】设备 ${login_ip} (${login_ip_attribution}) 通过 SSH 频繁尝试登录" >> ${logfile}
|
||
[ -n "$login_disturb" ] && [ "$login_disturb" -eq "1" ] && continue
|
||
if [ -z "$title" ]; then
|
||
title="${login_ip} 通过 SSH 频繁尝试登录"
|
||
content="${content}${str_splitline}${str_title_start} 登录信息${str_title_end}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_attribution}"
|
||
elif ( echo "$title"|grep -q "频繁尝试登录" ); then
|
||
title="${login_ip} ${title}"
|
||
content="${content}${str_splitline}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_attribution}"
|
||
else
|
||
title="设备状态变化"
|
||
content="${content}${str_splitline}${str_title_start} 登录信息${str_title_end}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_attribution}"
|
||
fi
|
||
done
|
||
rm -f ${dir}ssh_failed >/dev/null 2>&1
|
||
unset login_ip
|
||
}
|
||
|
||
# 添加白名单,懒得写删除项和信息显示了,纯粹就是懒
|
||
function add_ip_white() {
|
||
[ -n "$port_knocking_enable" ] && [ "$port_knocking_enable" -eq "1" ] || return
|
||
[ -z "$2" ] && timeout=$login_ip_white_timeout || timeout=$2
|
||
# 检查 IP 版本
|
||
unset ipset_name
|
||
( echo "$1"|grep -Eq '^([0-9]{1,3}\.){3}[0-9]{1,3}$' ) && local ipset_name="wechatpush_whitelist"
|
||
( echo "$1"|grep -Eq '^([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}$' ) && local ipset_name="wechatpush_whitelistv6"
|
||
[ -z "$ipset_name" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】白名单添加失败,IP 格式错误" >> ${logfile} && return
|
||
|
||
[ -n "$nftables_version" ] && nft delete element inet fw4 $ipset_name { $1 } >/dev/null 2>&1
|
||
[ -n "$nftables_version" ] && nft add element inet fw4 $ipset_name { $1 expires ${timeout}s } && return #没找到刷新时间的命令,删除再添加
|
||
ipset -exist add $ipset_name $1 timeout $timeout
|
||
}
|
||
|
||
# 初始化白名单
|
||
function init_ip_white() {
|
||
[ -n "$port_knocking_enable" ] && [ "$port_knocking_enable" -eq "1" ] || return
|
||
# 设置 IP 版本变量
|
||
if [ $1 == "ipv4" ]; then
|
||
ipset_name="wechatpush_whitelist"
|
||
ip_version="ip"
|
||
elif [ $1 == "ipv6" ]; then
|
||
ipset_name="wechatpush_whitelistv6"
|
||
ip_version="ip6"
|
||
nat_table_cmd="family inet6"
|
||
fi
|
||
|
||
if [ -n "$nftables_version" ]; then
|
||
! nft list set inet fw4 $ipset_name >/dev/null 2>&1 && nft add set inet fw4 $ipset_name { type ${1}_addr\; flags timeout\; timeout ${login_ip_white_timeout}s\; }
|
||
nft -- add chain inet fw4 wechatpush_dstnat { type nat hook prerouting priority -100 \; }
|
||
nft add chain inet fw4 wechatpush_srcnat { type nat hook postrouting priority 100 \; }
|
||
else
|
||
! ipset list $ipset_name >/dev/null 2>&1 && ipset create $ipset_name hash:ip timeout $login_ip_white_timeout $nat_table_cmd >/dev/null 2>&1
|
||
fi
|
||
|
||
# 端口放行
|
||
if [ ! -z "$login_port_white" ]; then
|
||
local login_port_white=`echo "$login_port_white"|sed 's/ //g'|sed 's/,/, /g'` 2>/dev/null
|
||
if [ -n "$nftables_version" ]; then
|
||
local count_accept_rules=`nft list ruleset | grep -c "tcp dport.* ${login_port_white}.* $ip_version saddr @${ipset_name} counter packets .* accept comment \"\!wechatpush Accept rule\""`
|
||
if [ $count_accept_rules -eq 0 ]; then
|
||
nft insert rule inet fw4 input tcp dport { $login_port_white } $ip_version saddr @$ipset_name counter accept comment \"\!wechatpush Accept rule\" >/dev/null 2>&1
|
||
elif [ $count_accept_rules -ne 1 ]; then
|
||
local i=0
|
||
local handles=`nft --handle list ruleset | grep "\!wechatpush Accept rule" | grep -v "tcp dport.* ${login_port_white}.* $ip_version saddr @${ipset_name} counter packets .* accept comment \"\!wechatpush Accept rule\"" | awk '{print $NF}'`
|
||
for handle in $handles; do
|
||
[ $i -eq 0 ] && i=1 && continue
|
||
nft delete rule $handle
|
||
done
|
||
fi
|
||
else
|
||
${ip_version}tables -C INPUT -m set --match-set $ipset_name src -p tcp -m multiport --dport $login_port_white -j ACCEPT >/dev/null 2>&1 || ${ip_version}tables -I INPUT -m set --match-set $ipset_name src -p tcp -m multiport --dport $login_port_white -j ACCEPT >/dev/null 2>&1
|
||
fi
|
||
fi
|
||
unset handle
|
||
# 端口转发
|
||
while IFS= read -r port_forward; do
|
||
port_forward=`echo "$port_forward"|sed 's/,/ /g'` 2>/dev/null
|
||
[ `echo $port_forward| awk -F" " '{print NF}'` -ne "4" ] && continue
|
||
local src_ip=`echo ${port_forward}|awk '{print $1}'`
|
||
local src_port=`echo ${port_forward}|awk '{print $2}'`
|
||
local dst_ip=`echo ${port_forward}|awk '{print $3}'`
|
||
local dst_port=`echo ${port_forward}|awk '{print $4}'`
|
||
if [ -n "$nftables_version" ]; then
|
||
! nft list ruleset|grep "$ip_version saddr @${ipset_name} tcp dport $src_port counter .* dnat $ip_version to $dst_ip:$dst_port comment \"\!wechatpush DNAT rule\"" >/dev/null 2>&1 && nft insert rule inet fw4 wechatpush_dstnat meta nfproto $1 $ip_version saddr @${ipset_name} tcp dport $src_port counter dnat to "$dst_ip:$dst_port" comment \"\!wechatpush DNAT rule\" >/dev/null 2>&1
|
||
! nft list ruleset|grep "$ip_version daddr $dst_ip tcp dport $dst_port counter .* snat $ip_version to $src_ip comment \"\!wechatpush SNAT rule\"" >/dev/null 2>&1 && nft insert rule inet fw4 wechatpush_srcnat $ip_version daddr $dst_ip tcp dport $dst_port counter snat to $src_ip comment \"\!wechatpush SNAT rule\" >/dev/null 2>&1
|
||
else
|
||
${ip_version}tables -t nat -C PREROUTING -m set --match-set $ipset_name src -p tcp --dport $src_port -j DNAT --to-destination "$dst_ip:$dst_port" >/dev/null 2>&1 || ${ip_version}tables -t nat -I PREROUTING -m set --match-set $ipset_name src -p tcp --dport $src_port -j DNAT --to-destination "$dst_ip:$dst_port" >/dev/null 2>&1
|
||
${ip_version}tables -t nat -C POSTROUTING -m set --match-set $ipset_name src -p tcp -d $dst_ip --dport $dst_port -j SNAT --to-source $src_ip >/dev/null 2>&1 || ${ip_version}tables -t nat -I POSTROUTING -m set --match-set $ipset_name src -p tcp -d $dst_ip --dport $dst_port -j SNAT --to-source $src_ip >/dev/null 2>&1
|
||
fi
|
||
done <<< "$login_port_forward_list"
|
||
unset port_forward
|
||
}
|
||
|
||
# 初始化黑名单规则
|
||
function init_ip_black(){
|
||
[ -n "$login_web_black" ] && [ "$login_web_black" -eq "1" ] || return
|
||
# 设置 IP 版本变量
|
||
if [ $1 == "ipv4" ]; then
|
||
ipset_name="wechatpush_blacklist"
|
||
ip_version="ip"
|
||
elif [ $1 == "ipv6" ]; then
|
||
ipset_name="wechatpush_blacklistv6"
|
||
ip_version="ip6"
|
||
nat_table_cmd="family inet6"
|
||
fi
|
||
|
||
if [ -n "$nftables_version" ]; then
|
||
! nft list set inet fw4 ${ipset_name} >/dev/null 2>&1 && nft add set inet fw4 ${ipset_name} { type ${1}_addr\; flags timeout\; timeout ${login_ip_black_timeout}s\; }
|
||
! nft list ruleset|grep "$ip_version saddr @${ipset_name} counter .* comment \"\!wechatpush Drop rule\"" >/dev/null 2>&1 && nft insert rule inet fw4 input $ip_version saddr @${ipset_name} counter drop comment \"\!wechatpush Drop rule\" >/dev/null 2>&1
|
||
else
|
||
ipset list $ipset_name >/dev/null 2>&1 || ipset create ${ipset_name} hash:ip timeout ${login_ip_black_timeout} ${nat_table_cmd} >/dev/null 2>&1
|
||
${ip_version}tables -C INPUT -m set --match-set ${ipset_name} src -j DROP >/dev/null 2>&1 || ${ip_version}tables -I INPUT -m set --match-set ${ipset_name} src -j DROP >/dev/null 2>&1
|
||
fi
|
||
}
|
||
|
||
# 添加黑名单
|
||
function add_ip_black(){
|
||
[ ! "$1" ] && return
|
||
echo "$login_ip_white_list"|grep -w -q "$1" && return
|
||
# 检查 IP 版本
|
||
unset ipset_name
|
||
( echo "$1"|grep -Eq '^([0-9]{1,3}\.){3}[0-9]{1,3}$' ) && ipset_name="wechatpush_blacklist"
|
||
( echo "$1"|grep -Eq '^([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}$' ) && ipset_name="wechatpush_blacklistv6"
|
||
[ -z "$ipset_name" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】黑名单添加失败,IP 格式错误" >> ${logfile} && return
|
||
|
||
! cat ${ip_blacklist_path}|grep -q -w -i ${1} && echo "$1 timeout ${login_ip_black_timeout}" >> ${ip_blacklist_path}
|
||
|
||
[ -n "$nftables_version" ] && nft add element inet fw4 ${ipset_name} { $1 expires ${login_ip_black_timeout}s } >/dev/null 2>&1
|
||
[ -n "$nftables_version" ] && return
|
||
|
||
ipset -exist add $ipset_name ${1} timeout ${login_ip_black_timeout}
|
||
}
|
||
|
||
# 移出黑名单
|
||
function del_ip_black(){
|
||
[ ! "$1" ] && return
|
||
sed -i "/^${1}/d" ${ip_blacklist_path}
|
||
|
||
# 检查 IP 版本
|
||
unset ipset_name
|
||
( echo "$1"|grep -Eq '^([0-9]{1,3}\.){3}[0-9]{1,3}$' ) && ipset_name="wechatpush_blacklist"
|
||
( echo "$1"|grep -Eq '^([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}$' ) && ipset_name="wechatpush_blacklistv6"
|
||
[ -z "$ipset_name" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】黑名单删除失败,IP 格式错误" >> ${logfile} && return
|
||
|
||
[ -n "$nftables_version" ] && nft delete element inet fw4 ${ipset_name} { $1 } >/dev/null 2>&1
|
||
[ -n "$nftables_version" ] && return
|
||
ipset list ${ipset_name} >/dev/null 2>&1 && ipset -! del ${ipset_name} ${1}
|
||
}
|
||
|
||
# 设置防火墙列表
|
||
function set_ip_black(){
|
||
# 检查换行,避免出错
|
||
[ `tail -n1 "${ip_blacklist_path}" | wc -l` -eq "0" ] && echo -e >> ${ip_blacklist_path}
|
||
|
||
# 从 ip_blacklist 文件逐行添加黑名单,add_ip_black() 处验证是否重复
|
||
for ip_black in `cat ${ip_blacklist_path}|awk '{print $1}'`; do
|
||
add_ip_black ${ip_black}
|
||
done
|
||
# 当 ip_blacklist 文件清除 IP 时,从集合中清除 IP
|
||
[ -n "$nftables_version" ] && fw_info_blacklist=$(nft list set inet fw4 wechatpush_blacklist | tr -d '\n' | grep -oE 'elements = \{[^}]*\}' | grep -oE '[^{}]+ expires [^,}]+[,\}]' | tr ',}' '\n' | tr -s ' ' | sed -e 's/^[[:space:]]*//')
|
||
[ -n "$nftables_version" ] && fw_info_blacklistv6=$(nft list set inet fw4 wechatpush_blacklistv6 | tr -d '\n' | grep -oE 'elements = \{[^}]*\}' | grep -oE '[^{}]+ expires [^,}]+[,\}]' | tr ',}' '\n' | tr -s ' ' | sed -e 's/^[[:space:]]*//')
|
||
[ -z "$nftables_version" ] && fw_info_blacklist=$(ipset list wechatpush_blacklist | grep "timeout" 2>/dev/null)
|
||
[ -z "$nftables_version" ] && fw_info_blacklistv6=$(ipset list wechatpush_blacklistv6 | grep "timeout" 2>/dev/null)
|
||
|
||
fw_info_blacklist="${fw_info_blacklist}\n${fw_info_blacklistv6}"
|
||
while IFS= read -r ip_black_info; do
|
||
ip_black=$(echo "$ip_black_info"|grep -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}")
|
||
[ -z "$ip_black" ] && ip_black=$(echo "$ip_black_info"|grep -Eo "([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}")
|
||
[ -z "$ip_black" ] && continue
|
||
cat ${ip_blacklist_path}|grep -q -w -i ${ip_black} && sed -i "/^${ip_black}/d" ${ip_blacklist_path} && echo ${ip_black_info} >> ${ip_blacklist_path} || del_ip_black ${ip_black}
|
||
done <<< "$fw_info_blacklist"
|
||
}
|
||
|
||
# 发送定时数据
|
||
function send(){
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` 【定时数据】创建定时任务" >> ${logfile}
|
||
disturb;local send_disturb=$?
|
||
get_config "send_title" "send_notification"
|
||
|
||
cpuload=`getcpu`
|
||
service_status=$(ubus call service list '{"name": "wechatpush"}' | grep -o '"running": true')
|
||
[ -z "$1" ] && ( echo "$send_notification"|grep -q "client_list" ) && > ${dir}send_enable.lock && [ -z "$service_status" ] && first &
|
||
if [ -z "$1" ] && ( echo "$send_notification"|grep -q "router_status" ); then
|
||
cat /proc/loadavg|awk '{print $1" "$2" "$3}' > "$output_dir/systemload" &
|
||
free -m|sed -n '2p'|awk '{printf "%.2f%%\n",($3/$2)*100}' > "$output_dir/ramload" &
|
||
curl -o /dev/null --connect-timeout 5 -s -w %{http_code} www.google.com > "$output_dir/Qwai" &
|
||
cat /proc/uptime|awk -F. '{run_days=$1 / 86400;run_hour=($1 % 86400)/3600;run_minute=($1 % 3600)/60;run_second=$1 % 60;printf("运行时间:%d天%d时%d分%d秒",run_days,run_hour,run_minute,run_second)}' > "$output_dir/systemstatustime" &
|
||
systeminfo_enable="1"
|
||
fi
|
||
[ -z "$1" ] && ( echo "$send_notification"|grep -q "router_temp" ) && soc_temp > "$output_dir/cputemp" &
|
||
|
||
if [ -z "$1" ] && ( echo "$send_notification"|grep -q "wan_info" ); then
|
||
getip wanipv4 > "$output_dir/send_wanIP" &
|
||
getip hostipv4|jq -r '.IP' > "$output_dir/send_hostIP" &
|
||
waninfo_enable="1"
|
||
if [ "$get_ipv6_mode" -ne "0" ]; then
|
||
getip wanipv6 > "$output_dir/send_wanIPv6" &
|
||
getip hostipv6|jq -r '.IP' > "$output_dir/send_hostIPv6" &
|
||
ipv6_enable="1"
|
||
fi
|
||
getinterfaceuptime > "$output_dir/interfaceuptime" &
|
||
fi
|
||
|
||
#[ -z "$1" ] && ( echo "$send_notification"|grep -q "disk_info" ) && get_disk &
|
||
[ -z "$1" ] && get_disk &
|
||
|
||
[ -z "$send_title" ] && send_title="路由状态:"
|
||
[ ! -z "$1" ] && send_title="发送测试:" && send_content="${str_splitline}${str_title_start}内容1${str_title_end}${str_linefeed}${str_tab}设备1${str_linefeed}${str_tab}设备2${str_splitline}${str_title_start}内容2${str_title_end}${str_linefeed}${str_tab}设备3${str_linefeed}${str_tab}设备4"
|
||
|
||
wait_and_cat
|
||
if [ -n "$systeminfo_enable" ]; then
|
||
[[ $Qwai -eq 200 || $Qwai -eq 301 || $Qwai -eq 302 ]] && Qwai_status="已连通!" || Qwai_status="已断开!"
|
||
send_content="${send_content}${str_splitline}${str_title_start} 系统运行状态${str_title_end}"
|
||
send_content="${send_content}${str_linefeed}${str_tab}平均负载:${systemload}"
|
||
send_content="${send_content}${str_linefeed}${str_tab}CPU占用:${cpuload}"
|
||
send_content="${send_content}${str_linefeed}${str_tab}内存占用:${ramload}"
|
||
send_content="${send_content}${str_linefeed}${str_tab}全球互联:${Qwai_status}"
|
||
send_content="${send_content}${str_linefeed}${str_tab}${systemstatustime}"
|
||
fi
|
||
|
||
if [ -z "$1" ] && ( echo "$send_notification"|grep -q "router_temp" ); then
|
||
[ ! -z "$cputemp" ] && send_content="${send_content}${str_splitline}${str_title_start} 设备温度${str_title_end}${str_linefeed}${str_tab}CPU:${cputemp}℃"
|
||
[ -z "$cputemp" ] && send_content="${send_content}${str_splitline}${str_title_start} 设备温度${str_title_end}${str_linefeed}${str_tab}无法获取设备温度"
|
||
fi
|
||
|
||
#if [ -z "$1" ] && ( echo "$send_notification"|grep -q "disk_info" ); then
|
||
if [ -z "$1" ]; then
|
||
send_content="${send_content}${get_disk}"
|
||
fi
|
||
|
||
if [ -n "$waninfo_enable" ]; then
|
||
send_content="${send_content}${str_splitline}${str_title_start} WAN 口信息${str_title_end}"
|
||
if [ "$send_wanIP" == "$send_hostIP" ]; then
|
||
send_content="${send_content}${str_linefeed}${str_tab}IPv4: ${send_wanIP}"
|
||
elif [ "$get_ipv4_mode" -eq "1" ]; then
|
||
send_content="${send_content}${str_linefeed}${str_tab}接口 IPv4: ${send_wanIP}"
|
||
[ -n "$send_hostIP" ] && send_content="${send_content}${str_linefeed}${str_tab}外网 IPv4: ${send_hostIP}"
|
||
elif [ "$get_ipv4_mode" -eq "2" ]; then
|
||
[ -n "$send_wanIP" ] && send_content="${send_content}${str_linefeed}${str_tab}接口 IPv4: ${send_wanIP}"
|
||
send_content="${send_content}${str_linefeed}${str_tab}外网 IPv4: ${send_hostIP}"
|
||
fi
|
||
if [ -n "$ipv6_enable" ]; then
|
||
if [ "$send_wanIPv6" == "$send_hostIPv6" ]; then
|
||
send_content="${send_content}${str_linefeed}${str_tab}IPv6: ${send_wanIPv6}"
|
||
elif [ "$get_ipv6_mode" -eq "1" ]; then
|
||
send_content="${send_content}${str_linefeed}${str_tab}接口 IPv6: ${send_wanIPv6}"
|
||
[ -n "$send_hostIPv6" ] && send_content="${send_content}${str_linefeed}${str_tab}外网 IPv6: ${send_hostIPv6}"
|
||
elif [ "$get_ipv6_mode" -eq "2" ]; then
|
||
[ -n "$send_wanIPv6" ] && send_content="${send_content}${str_linefeed}${str_tab}接口 IPv6: ${send_wanIPv6}"
|
||
send_content="${send_content}${str_linefeed}${str_tab}外网 IPv6: ${send_hostIPv6}"
|
||
fi
|
||
fi
|
||
interfaceuptime=`getinterfaceuptime`
|
||
[ ! -z "$interfaceuptime" ] && wanstatustime=$(printf "在线时间:%d天%d时%d分%d秒" $((interfaceuptime / 86400)) $(((interfaceuptime % 86400) / 3600)) $(((interfaceuptime % 3600) / 60)) $((interfaceuptime % 60)))
|
||
send_content="${send_content}${str_linefeed}${str_tab}${wanstatustime}"
|
||
fi
|
||
|
||
if [ -z "$1" ] && ( echo "$send_notification"|grep -q "client_list" ); then
|
||
wait
|
||
awk '{ lines[i++] = $0 } END { for (j = i-1; j >= 0; j--) print lines[j] }' "${dir}ipAddress" > "${dir}tmp_sort_file"
|
||
logrow=$(awk 'END {print NR}' ${dir}ipAddress)
|
||
send_content="${send_content}${str_splitline}${str_title_start} 现有在线设备 ${logrow} 台${str_title_end}"
|
||
[ "$logrow" -eq "0" ] && send_content="${send_content}${str_splitline}${str_title_start} 当前无在线设备${str_title_end}"
|
||
time_now=$(date +%s)
|
||
while read -r tmp_ip tmp_mac tmp_name time_up _; do
|
||
tmp_name=${tmp_name//_/ }
|
||
tmp_name=$(cut_str "$tmp_name" "20")
|
||
time_online=$(time_for_humans $((time_now - time_up)))
|
||
ip_total=$(usage get "$tmp_mac")
|
||
[ -n "$ip_total" ] && ip_total="总计流量:${ip_total} "
|
||
send_content="${send_content}${str_linefeed}【${tmp_name}】 ${ip_total}${str_linefeed}${str_tab}${tmp_ip} 在线 ${time_online}"
|
||
done < "${dir}tmp_sort_file"
|
||
fi
|
||
|
||
[ ! -z "$device_name" ] && send_title="【$device_name】${send_title}"
|
||
[ -z "$send_content" ] && send_content="${str_splitline}${str_title_start} 我遇到了一个难题${str_title_end}${str_linefeed}${str_tab}定时发送选项错误,你没有选择需要发送的项目,该怎 么办呢${str_splitline}"
|
||
[ "$send_disturb" -eq "0" ] && diy_send "${send_title}" "${send_content}" "${jsonpath}" "$1" >/dev/null 2>&1
|
||
RETVAL=$?
|
||
[ $RETVAL -eq 1 ] && [ "$send_disturb" -eq "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】定时推送失败,请检查网络或设置信息" >> ${logfile} || echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}定时推送任务完成" >> ${logfile}
|
||
deltemp
|
||
return $RETVAL
|
||
}
|
||
|
||
# 初始化
|
||
if [ "$1" ] ;then
|
||
[ $1 == "soc" ] && get_config "soc_code" "server_host" "server_port"
|
||
[ $1 == "soc" ] && soc_temp && exit $?
|
||
[ $1 == "getip" ] && {
|
||
get_config "get_ipv4_mode" "ipv4_interface" "get_ipv6_mode" "ipv6_interface"
|
||
ipv4_urllist=`cat /usr/share/wechatpush/api/ipv4.list` 2>/dev/null
|
||
ipv6_urllist=`cat /usr/share/wechatpush/api/ipv6.list` 2>/dev/null
|
||
ip_changes getip && exit $?
|
||
}
|
||
read_config
|
||
[ $1 == "send" ] && send && exit $?
|
||
[ $1 == "test" ] && send test && exit $?
|
||
[ $1 == "t1" ] && thread_num=1 || exit
|
||
else
|
||
read_config
|
||
fi
|
||
|
||
# 限制并发进程
|
||
[ -z "$thread_num" ] || [ "$thread_num" -eq "0" ] && thread_num=5
|
||
[ -e ${dir}fd1 ] || mkfifo ${dir}fd1
|
||
exec 5<>${dir}fd1
|
||
rm -f ${dir}fd1 >/dev/null 2>&1
|
||
for i in `seq 1 $thread_num`; do
|
||
echo >&5
|
||
done
|
||
unset i
|
||
|
||
process_login() {
|
||
local login_ip=$1
|
||
local -n login_counts=$2
|
||
|
||
if [ -z "${login_counts["$login_ip"]}" ]; then
|
||
login_counts["$login_ip"]=0
|
||
fi
|
||
login_counts["$login_ip"]=$((login_counts["$login_ip"]+1))
|
||
local count=${login_counts["$login_ip"]}
|
||
login_log=$(logread notice | grep -w -i "$login_ip" | tail -n 1)
|
||
|
||
if [[ $count -eq $login_max_num && ( "$2" == "web_failed_counts" || "$2" == "ssh_failed_counts" ) ]]; then
|
||
add_ip_black ${login_ip}
|
||
unset login_counts["$login_ip"]
|
||
[ "$2" == "web_failed_counts" ] && echo "${login_ip}" >> ${dir}web_failed
|
||
[ "$2" == "ssh_failed_counts" ] && echo "${login_ip}" >> ${dir}ssh_failed
|
||
fi
|
||
|
||
if [[ "$2" == "web_login_counts" || "$2" == "ssh_login_counts" ]]; then
|
||
add_ip_white ${login_ip}
|
||
unset web_failed_counts["$login_ip"]
|
||
unset ssh_failed_counts["$login_ip"]
|
||
unset login_counts["$login_ip"]
|
||
[ "$2" == "web_login_counts" ] && echo "${login_ip}" >> ${dir}web_login
|
||
[ "$2" == "ssh_login_counts" ] && echo "${login_ip}" >> ${dir}ssh_login
|
||
[ "${#login_counts[@]}" -gt "100" ] && login_counts=("${login_counts[@]: -100}")
|
||
fi
|
||
}
|
||
|
||
# 监听登录事件
|
||
if [ -n "$web_logged" ] || [ -n "$ssh_logged" ] || [ -n "$web_login_failed" ] || [ -n "$ssh_login_failed" ]; then
|
||
declare -A web_login_counts
|
||
declare -A ssh_login_counts
|
||
declare -A web_failed_counts
|
||
declare -A ssh_failed_counts
|
||
[ -f ${dir}child_pid ] && child_pid=$(cat ${dir}child_pid)
|
||
[ -n "$child_pid" ] && kill $child_pid >/dev/null 2>&1
|
||
(
|
||
logread -f -p notice | while IFS= read -r line; do
|
||
[ -n "$web_logged" ] && {
|
||
web_login_ip=$(echo "$line" | grep -i "accepted login" | awk '{print $NF}')
|
||
[ -n "$web_login_ip" ] && process_login "$web_login_ip" web_login_counts
|
||
}
|
||
|
||
[ -n "$ssh_logged" ] && {
|
||
ssh_login_ip=$(echo "$line" | grep -i "Password auth succeeded\|Pubkey auth succeeded" | awk '{print $NF}' | sed -nr 's#^(.*):.[0-9]{1,5}#\1#gp' | sed -e 's/%.*//')
|
||
[ -n "$ssh_login_ip" ] && process_login "$ssh_login_ip" ssh_login_counts
|
||
}
|
||
|
||
[ -n "$web_login_failed" ] && {
|
||
web_failed_ip=$(echo "$line" | grep -i "failed login"|awk '{print $NF}')
|
||
[ -n "$web_failed_ip" ] && process_login "$web_failed_ip" web_failed_counts
|
||
}
|
||
|
||
[ -n "$ssh_login_failed" ] && {
|
||
ssh_failed_ip=$(echo "$line" | grep -i "Bad password attempt\|Login attempt for nonexistent user from" | awk '{print $NF}' | sed -nr 's#^(.*):.[0-9]{1,5}#\1#gp' | sed -e 's/%.*//')
|
||
[ -z "$ssh_failed_ip" ] && ssh_failed_num=$(echo "$line" | sed -n 's/.*authpriv\.warn dropbear\[\([0-9]\+\)\]: Login attempt for nonexistent user/\1/p') && [ -n "$ssh_failed_num" ] && ssh_failed_ip=$(logread notice | grep "authpriv\.info dropbear\[${failed_user_id}\].*Child connection from" | awk '{print $NF}' | sed -nr 's#^(.*):.[0-9]{1,5}#\1#gp' | sed -e 's/%.*//')
|
||
[ -n "$ssh_failed_ip" ] && process_login "$ssh_failed_ip" ssh_failed_counts
|
||
}
|
||
done
|
||
) &
|
||
# 分离子shell,避免影响 wait
|
||
child_pid=$!
|
||
sleep 1
|
||
disown "$child_pid"
|
||
echo $child_pid > ${dir}child_pid
|
||
fi
|
||
|
||
# 载入在线设备
|
||
init;[ $? -eq 1 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】读取设置出错,请检查设置项 " >> ${logfile} && exit
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】载入在线设备..." >> ${logfile}
|
||
> ${dir}send_enable.lock && first && deltemp
|
||
echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】初始化完成" >> ${logfile}
|
||
|
||
# 循环
|
||
while [ "$enable" -eq "1" ]; do
|
||
deltemp
|
||
usage update
|
||
disturb;disturb=$?
|
||
device_aliases=`cat /usr/share/wechatpush/api/device_aliases.list` 2>/dev/null
|
||
|
||
[ -f ${dir}ipAddress ] && ipAddress_logrow=$(grep -c "" ${dir}ipAddress) || ipAddress_logrow="0";
|
||
if [ $ipAddress_logrow -ne "0" ]; then
|
||
online_list=`cat ${dir}ipAddress|awk '{print $2}'|grep -v "^$"|sort -u`
|
||
for online_mac in $online_list; do
|
||
[ ! -z "$online_mac" ] && mac_online_status="`echo "$mark_mac_list"|grep -i $online_mac|grep -v "^$"|sort -u|head -n1`${mac_online_status}"
|
||
done
|
||
fi
|
||
|
||
# 网络状态与 IP 变动
|
||
if [ "$get_ipv4_mode" -ne "0" ] || [ "$get_ipv6_mode" -ne "0" ]; then
|
||
rand_geturl
|
||
ip_changes
|
||
fi
|
||
|
||
# 设备列表
|
||
if [ ! -f "${dir}send_enable.lock" ]; then
|
||
[ ! -z "$title" ] && echo "$title" > ${dir}title
|
||
[ ! -z "$content" ] && echo "$content" > ${dir}content
|
||
first
|
||
[ -f "${dir}title" ] && title=`cat ${dir}title` && rm -f ${dir}title >/dev/null 2>&1
|
||
[ -f "${dir}content" ] && content=`cat ${dir}content` && rm -f ${dir}content >/dev/null 2>&1
|
||
fi
|
||
|
||
# 离线二次验证区推送
|
||
[ ! -f "${dir}send_enable.lock" ] && down_send
|
||
|
||
# 当前设备列表
|
||
[ ! -z "$content" ] && [ ! -f "${dir}send_enable.lock" ] && current_device
|
||
|
||
# 无人值守任务
|
||
[ ! -f "${dir}send_enable.lock" ] && unattended
|
||
|
||
# CPU 检测
|
||
[ ! -f "${dir}send_enable.lock" ] && cpu_load
|
||
|
||
# 硬盘检测
|
||
#[ ! -f "${dir}send_enable.lock" ] && get_disk
|
||
|
||
# 异常流量检测
|
||
[ ! -f "${dir}send_enable.lock" ] && get_client_usage
|
||
|
||
# 登录提醒通知
|
||
[ ! -f "${dir}send_enable.lock" ] && login_send
|
||
|
||
# 推送
|
||
if [ ! -f "${dir}send_enable.lock" ] && [ ! -z "$title" ] && [ ! -z "$content" ]; then
|
||
[ ! -z "$device_name" ] && title="【$device_name】$title"
|
||
( echo "$lite_enable"|grep -q "content" ) && content="$title"
|
||
[ "$disturb" -eq "0" ] && diy_send "${title}" "${content}" "${jsonpath}" >/dev/null 2>&1
|
||
fi
|
||
|
||
# 等待定时任务推送完成
|
||
while [ -f "${dir}send_enable.lock" ]; do
|
||
sleep $sleeptime
|
||
done
|
||
|
||
sleep $sleeptime
|
||
done |