small-package/luci-app-wechatpush/root/usr/share/wechatpush/wechatpush

1788 lines
99 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

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

#!/bin/bash
# 读取设置文件
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