diff --git a/package/lean/luci-app-pushbot/Makefile b/package/lean/luci-app-pushbot/Makefile new file mode 100644 index 000000000..be51293de --- /dev/null +++ b/package/lean/luci-app-pushbot/Makefile @@ -0,0 +1,40 @@ +# Copyright (C) 2020 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-pushbot +PKG_VERSION:=3.12 +PKG_RELEASE:=9 + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=luci + CATEGORY:=LuCI + SUBMENU:=3. Applications + DEPENDS:=+iputils-arping +curl + TITLE:=LuCI support for Pushbot + PKGARCH:=all +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/conffiles +/etc/config/pushbot +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/etc/init.d $(1)/usr/bin/pushbot $(1)/etc/config $(1)/usr/lib/lua/luci $(1)/etc/uci-defaults $(1)/usr/share/rpcd/acl.d + $(CP) ./luasrc/* $(1)/usr/lib/lua/luci + $(INSTALL_CONF) ./root/etc/config/pushbot $(1)/etc/config + $(INSTALL_BIN) ./root/etc/init.d/pushbot $(1)/etc/init.d + $(INSTALL_BIN) ./root/etc/uci-defaults/luci-pushbot $(1)/etc/uci-defaults/luci-pushbot + $(INSTALL_BIN) ./root/usr/bin/pushbot/pushbot $(1)/usr/bin/pushbot + $(INSTALL_DATA) ./root/usr/share/rpcd/acl.d/luci-app-pushbot.json $(1)/usr/share/rpcd/acl.d/luci-app-pushbot.json +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/package/lean/luci-app-pushbot/README.md b/package/lean/luci-app-pushbot/README.md new file mode 100644 index 000000000..c7a6bde90 --- /dev/null +++ b/package/lean/luci-app-pushbot/README.md @@ -0,0 +1,90 @@ +# 改名公告 +#### 2021年04月25日 起luci-app-serverchand 改名为 luci-app-pushbot + +如需拉取编译 +请把: + +`# git clone https://github.com/zzsj0928/luci-app-serverchand package/luci-app-serverchand` + +改为 + +`git clone https://github.com/zzsj0928/luci-app-pushbot package/luci-app-pushbot` + +并把 .config 中 + +`CONFIG_PACKAGE_luci-app-serverchand=y` + +改为 + +`CONFIG_PACKAGE_luci-app-pushbot=y` + +注意:本次改名需要提前备份serverchand配置,并于PushBot中重新配置。 + +再次谢谢各位支持 + +# 申明 +- 本插件由[tty228/luci-app-serverchan](https://github.com/tty228/luci-app-serverchan)原创. +- 因微信推送存在诸多弊端(无法分开聊天工具与功能性消息推送,通知内不显示内容,内容需要点开才能查看等), +- 故由 然后七年 @zzsj0928 重新修改为本插件,为钉钉机器人API使用。 +- 本插件工作在:openwrt +- 本插件支持:钉钉推送,企业微信推送,PushPlus推送,微信推送,企业微信应用推送,飞书推送,钉钉机器人推送,企业微信机器人推送,飞书机器人推送,一对多推送,Bark推送(仅iOS) +# 显示效果 +## 通知栏:直接显示推送主题,一目了然,按设备不同,分组显示 + + +## 消息列表:直接显示最新推送的标题 + + +## 消息内容:直接显示所有推送信息,不用二次点开再查看 + + +# 下载 +- [luci-app-pushbot](https://github.com/zzsj0928/luci-app-pushbot/releases) + + +----------------------------------------------------- +##################################################### +----------------------------------------------------- + +# 以下为原插件简介: + +# 简介 +- 用于 OpenWRT/LEDE 路由器上进行 Server酱 微信/Telegram 推送的插件 +- 基于 serverchan 提供的接口发送信息,Server酱说明:http://sc.ftqq.com/1.version +- **基于斐讯 k3 制作,不同系统不同设备,请自行修改部分代码,无测试条件无法重现的 bug 不考虑修复** +- 依赖 iputils-arping + curl 命令,安装前请 `opkg update`,小内存路由谨慎安装 +- 使用主动探测设备连接的方式检测设备在线状态,以避免WiFi休眠机制,主动探测较为耗时,**如遇设备休眠频繁,请自行调整超时设置** +- 流量统计功能依赖 wrtbwmon ,自行选装或编译,该插件与 Routing/NAT 、Flow Offloading 冲突,开启无法获取流量,自行选择,L大版本直接编译 luci-app-wrtbwmon + +#### 主要功能 +- 路由 ip/ipv6 变动推送 +- 设备别名 +- 设备上线推送 +- 设备离线推送及流量使用情况 +- CPU 负载、温度监视 +- 定时推送设备运行状态 +- MAC 白名单、黑名单、按接口检测设备 +- 免打扰 +- 无人值守任务 + +#### 说明 +- 潘多拉系统、或不支持 sh 的系统,请将脚本开头 `#!/bin/sh` 改为 `#!/bin/bash`,或手动安装 `sh` +- 追新是没有意义的,没有问题没必要更新,上班事情忙完了,摸鱼又不会摸,只能靠写几行 bug ,才能缓解无聊这样子 + +#### 已知问题 +- 直接关闭接口时,该接口的离线设备会忽略检测 +- 部分设备无法读取到设备名,脚本使用 `cat /var/dhcp.leases` 命令读取设备名,如果 dhcp 中不存在设备名,则无法读取设备名(如二级路由设备、静态ip设备),请使用设备名备注 + +# Download +- [luci-app-serverchan](https://github.com/tty228/luci-app-serverchan/releases) +- [wrtbwmon](https://github.com/brvphoenix/wrtbwmon) +- [luci-app-wrtbwmon](https://github.com/brvphoenix/luci-app-wrtbwmon) + +#### ps +- 新功能看情况开发 +- 王者荣耀新赛季,不思进取中 +- 欢迎各种代码提交 +- 提交bug时请尽量带上设备信息,日志与描述(如执行`/usr/bin/serverchan/serverchan`后的提示、日志信息、/tmp/serverchan/ipAddress 文件信息) +- 三言两句恕我无能为力 +- 武汉加油 + diff --git a/package/lean/luci-app-pushbot/luasrc/controller/pushbot.lua b/package/lean/luci-app-pushbot/luasrc/controller/pushbot.lua new file mode 100644 index 000000000..e581cf840 --- /dev/null +++ b/package/lean/luci-app-pushbot/luasrc/controller/pushbot.lua @@ -0,0 +1,33 @@ +module("luci.controller.pushbot",package.seeall) + +function index() + + if not nixio.fs.access("/etc/config/pushbot")then + return + end + + entry({"admin", "services", "pushbot"}, alias("admin", "services", "pushbot", "setting"),_("全能推送"), 30).dependent = true + entry({"admin", "services", "pushbot", "setting"}, cbi("pushbot/setting"),_("配置"), 40).leaf = true + entry({"admin", "services", "pushbot", "advanced"}, cbi("pushbot/advanced"),_("高级设置"), 50).leaf = true + entry({"admin", "services", "pushbot", "client"}, form("pushbot/client"), "在线设备", 80) + entry({"admin", "services", "pushbot", "log"}, form("pushbot/log"),_("日志"), 99).leaf = true + entry({"admin", "services", "pushbot", "get_log"}, call("get_log")).leaf = true + entry({"admin", "services", "pushbot", "clear_log"}, call("clear_log")).leaf = true + entry({"admin", "services", "pushbot", "status"}, call("act_status")).leaf = true +end + +function act_status() + local e={} + e.running=luci.sys.call("busybox ps|grep -v grep|grep -c pushbot >/dev/null")==0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function get_log() + luci.http.write(luci.sys.exec( + "[ -f '/tmp/pushbot/pushbot.log' ] && cat /tmp/pushbot/pushbot.log")) +end + +function clear_log() + luci.sys.call("echo '' > /tmp/pushbot/pushbot.log") +end diff --git a/package/lean/luci-app-pushbot/luasrc/model/cbi/pushbot/advanced.lua b/package/lean/luci-app-pushbot/luasrc/model/cbi/pushbot/advanced.lua new file mode 100644 index 000000000..a29a80151 --- /dev/null +++ b/package/lean/luci-app-pushbot/luasrc/model/cbi/pushbot/advanced.lua @@ -0,0 +1,112 @@ +local nt = require "luci.sys".net +local fs=require"nixio.fs" + +m=Map("pushbot",translate("提示:"), +translate("如果你不了解这些选项的含义,请不要修改这些选项")) + +s = m:section(TypedSection, "pushbot", "高级设置") +s.anonymous = true +s.addremove = false + +a=s:option(Value,"up_timeout",translate('设备上线检测超时(s)')) +a.default = "2" +a.optional=false +a.datatype="uinteger" + +a=s:option(Value,"down_timeout",translate('设备离线检测超时(s)')) +a.default = "20" +a.optional=false +a.datatype="uinteger" + +a=s:option(Value,"timeout_retry_count",translate('离线检测次数')) +a.default = "2" +a.optional=false +a.datatype="uinteger" +a.description = translate("若无二级路由设备,信号强度良好,可以减少以上数值
因夜间 wifi 休眠较为玄学,遇到设备频繁推送断开,烦请自行调整参数
..╮(╯_╰)╭..") + +a=s:option(Value,"thread_num",translate('最大并发进程数')) +a.default = "3" +a.datatype="uinteger" + +a=s:option(Value, "soc_code", "自定义温度读取命令") +a.rmempty = true +a:value("",translate("默认")) +a:value("sensors",translate("sensors命令")) +a.description = translate("请尽量避免使用特殊符号,如双引号、$、!等,执行结果需为数字,用于温度对比") + +a=s:option(Button,"soc",translate("测试温度命令")) +a.inputtitle = translate("输出信息") +a.write = function() + luci.sys.call("/usr/bin/pushbot/pushbot soc") + luci.http.redirect(luci.dispatcher.build_url("admin","services","pushbot","advanced")) +end + +if nixio.fs.access("/tmp/pushbot/soc_tmp") then +e=s:option(TextValue,"soc_tmp") +e.rows=2 +e.readonly=true +e.cfgvalue = function() + return luci.sys.exec("cat /tmp/pushbot/soc_tmp && rm -f /tmp/pushbot/soc_tmp") +end +end + +a=s:option(Flag,"err_enable",translate("无人值守任务")) +a.default=0 +a.rmempty=true +a.description = translate("请确认脚本可以正常运行,否则可能造成频繁重启等错误!") + +a=s:option(Flag,"err_sheep_enable",translate("仅在免打扰时段重拨")) +a.default=0 +a.rmempty=true +a.description = translate("避免白天重拨 ddns 域名等待解析,此功能不影响断网检测
因夜间跑流量问题,该功能可能不稳定") +a:depends({err_enable="1"}) + +a= s:option(DynamicList, "err_device_aliases", translate("关注列表")) +a.rmempty = true +a.description = translate("只会在列表中设备都不在线时才会执行
免打扰时段一小时后,关注设备五分钟低流量(约100kb/m)将视为离线") +nt.mac_hints(function(mac, name) a :value(mac, "%s (%s)" %{ mac, name }) end) +a:depends({err_enable="1"}) + +a=s:option(ListValue,"network_err_event",translate("网络断开时")) +a.default="" +a:depends({err_enable="1"}) +a:value("",translate("无操作")) +a:value("1",translate("重启路由器")) +a:value("2",translate("重新拨号")) +a:value("3",translate("修改相关设置项,尝试自动修复网络")) +a.description = translate("选项 1 选项 2 不会修改设置,并最多尝试 2 次。
选项 3 会将设置项备份于 /usr/bin/pushbot/configbak 目录,并在失败后还原。
【!!无法保证兼容性!!】不熟悉系统设置项,不会救砖请勿使用") + +a=s:option(ListValue,"system_time_event",translate("定时重启")) +a.default="" +a:depends({err_enable="1"}) +a:value("",translate("无操作")) +a:value("1",translate("重启路由器")) +a:value("2",translate("重新拨号")) + +a= s:option(Value, "autoreboot_time", "系统运行时间大于") +a.rmempty = true +a.default = "24" +a.datatype="uinteger" +a:depends({system_time_event="1"}) +a.description = translate("单位为小时") + +a=s:option(Value, "network_restart_time", "网络在线时间大于") +a.rmempty = true +a.default = "24" +a.datatype="uinteger" +a:depends({system_time_event="2"}) +a.description = translate("单位为小时") + +a=s:option(Flag,"public_ip_event",translate("重拨尝试获取公网 ip")) +a.default=0 +a.rmempty=true +a:depends({err_enable="1"}) +a.description = translate("重拨时不会推送 ip 变动通知,并会导致你的域名无法及时更新 ip 地址
请确认你可以通过重拨获取公网 ip,否则这不仅徒劳无功还会引起频繁断网
移动等大内网你就别挣扎了!!") + +a= s:option(Value, "public_ip_retry_count", "当天最大重试次数") +a.rmempty = true +a.default = "10" +a.datatype="uinteger" +a:depends({public_ip_event="1"}) + +return m diff --git a/package/lean/luci-app-pushbot/luasrc/model/cbi/pushbot/client.lua b/package/lean/luci-app-pushbot/luasrc/model/cbi/pushbot/client.lua new file mode 100644 index 000000000..411dea8da --- /dev/null +++ b/package/lean/luci-app-pushbot/luasrc/model/cbi/pushbot/client.lua @@ -0,0 +1,6 @@ +f = SimpleForm("pushbot") +luci.sys.call("/usr/bin/pushbot/pushbot client") +f.reset = false +f.submit = false +f:append(Template("pushbot/client")) +return f diff --git a/package/lean/luci-app-pushbot/luasrc/model/cbi/pushbot/log.lua b/package/lean/luci-app-pushbot/luasrc/model/cbi/pushbot/log.lua new file mode 100644 index 000000000..21a7a0ce9 --- /dev/null +++ b/package/lean/luci-app-pushbot/luasrc/model/cbi/pushbot/log.lua @@ -0,0 +1,5 @@ +f = SimpleForm("pushbot") +f.reset = false +f.submit = false +f:append(Template("pushbot/log")) +return f diff --git a/package/lean/luci-app-pushbot/luasrc/model/cbi/pushbot/setting.lua b/package/lean/luci-app-pushbot/luasrc/model/cbi/pushbot/setting.lua new file mode 100644 index 000000000..22c1b29d5 --- /dev/null +++ b/package/lean/luci-app-pushbot/luasrc/model/cbi/pushbot/setting.lua @@ -0,0 +1,404 @@ + +local nt = require "luci.sys".net +local fs=require"nixio.fs" +local e=luci.model.uci.cursor() +local net = require "luci.model.network".init() +local sys = require "luci.sys" +local ifaces = sys.net:devices() + +m=Map("pushbot",translate("PushBot"), +translate("「全能推送」,英文名「PushBot」,是一款从服务器推送报警信息和日志到各平台的工具。
支持钉钉推送,企业微信推送,PushPlus推送。
本插件由tty228/luci-app-serverchan创建,然后七年修改为全能推送自用。

如果你在使用中遇到问题,请到这里提交:") +.. [[]] +.. translate("github 项目地址") +.. [[]] +) + +m:section(SimpleSection).template = "pushbot/status" + +s=m:section(NamedSection,"pushbot","pushbot",translate("")) +s:tab("basic", translate("基本设置")) +s:tab("content", translate("推送内容")) +s:tab("crontab", translate("定时推送")) +s:tab("disturb", translate("免打扰")) +s.addremove = false +s.anonymous = true + +--基本设置 +a=s:taboption("basic", Flag,"pushbot_enable",translate("启用")) +a.default=0 +a.rmempty = true + +--精简模式 +a=s:taboption("basic", Flag,"lite_enable",translate("精简模式")) +a.default=0 +a.rmempty = true + +a= s:taboption("basic", Flag, "content_current_device", "精简当前设备列表") +a.default = 0 +a.rmempty = true +a:depends({lite_enable="1"}) + +a= s:taboption("basic", Flag, "content_nowtime", "精简当前时间") +a.default = 0 +a.rmempty = true +a:depends({lite_enable="1"}) + +a= s:taboption("basic", Flag, "content_content", "只推送标题") +a.default = 0 +a.rmempty = true +a:depends({lite_enable="1"}) + +a=s:taboption("basic", ListValue,"send_we",translate("推送模式")) +a.default="" +a.rmempty = true +a:value("",translate("钉钉")) +a:value("1",translate("企业微信")) +a:value("3",translate("飞书")) +a:value("4",translate("Bark")) +a:value("2",translate("PushPlus")) + +a=s:taboption("basic", Value,"dd_webhook",translate('Webhook'), translate("钉钉机器人 Webhook").."
调用代码获取点击这里

") +a.rmempty = true +a:depends("send_we","") + +a=s:taboption("basic", Value, "we_webhook", translate("Webhook"),translate("企业微信机器人 Webhook").."
调用代码获取点击这里

") +a.rmempty = true +a:depends("send_we","1") + +a=s:taboption("basic", Value,"pp_token",translate('PushPlus Token'), translate("PushPlus Token").."
调用代码获取点击这里

") +a.rmempty = true +a:depends("send_we","2") + +a=s:taboption("basic", ListValue,"pp_channel",translate('PushPlus Channel')) +a.rmempty = true +a:depends("send_we","2") +a:value("wechat",translate("wechat:PushPlus微信公众号")) +a:value("cp",translate("cp:企业微信应用")) +a:value("webhook",translate("webhook:第三方webhook")) +a:value("sms",translate("sms:短信")) +a:value("mail",translate("mail:邮箱")) +a.description = translate("第三方webhook:企业微信、钉钉、飞书、server酱
sms短信/mail邮箱:PushPlus暂未开放
具体channel设定参见:点击这里") + +a=s:taboption("basic", Value,"pp_webhook",translate('PushPlus Custom Webhook'), translate("PushPlus 自定义Webhook").."
第三方webhook或企业微信调用
具体自定义Webhook设定参见:点击这里

") +a.rmempty = true +a:depends("pp_channel","cp") +a:depends("pp_channel","webhook") + +a=s:taboption("basic", Flag,"pp_topic_enable",translate("PushPlus 一对多推送")) +a.default=0 +a.rmempty = true +a:depends("pp_channel","wechat") + +a=s:taboption("basic", Value,"pp_topic",translate('PushPlus Topic'), translate("PushPlus 群组编码").."
一对多推送时指定的群组编码
具体群组编码Topic设定参见:点击这里

") +a.rmempty = true +a:depends("pp_topic_enable","1") + +a=s:taboption("basic", Value,"fs_webhook",translate('WebHook'), translate("飞书 WebHook").."
调用代码获取点击这里

") +a.rmempty = true +a:depends("send_we","3") + +a=s:taboption("basic", Value,"bark_token",translate('Bark Token'), translate("Bark Token").."
调用代码获取点击这里

") +a.rmempty = true +a:depends("send_we","4") + +a=s:taboption("basic", Flag,"bark_srv_enable",translate("自建 Bark 服务器")) +a.default=0 +a.rmempty = true +a:depends("send_we","4") + +a=s:taboption("basic", Value,"bark_srv",translate('Bark Server'), translate("Bark 自建服务器地址").."
如https://your.domain:port
具体自建服务器设定参见:点击这里

") +a.rmempty = true +a:depends("bark_srv_enable","1") + +a=s:taboption("basic", Value,"device_name",translate('本设备名称')) +a.rmempty = true +a.description = translate("在推送信息标题中会标识本设备名称,用于区分推送信息的来源设备") + +a=s:taboption("basic", Value,"sleeptime",translate('检测时间间隔')) +a.rmempty = true +a.optional = false +a.default = "60" +a.description = translate("越短的时间时间响应越及时,但会占用更多的系统资源") + +a=s:taboption("basic", ListValue,"oui_data",translate("MAC设备信息数据库")) +a.rmempty = true +a.default="" +a:value("",translate("关闭")) +a:value("1",translate("简化版")) +a:value("2",translate("完整版")) +a:value("3",translate("网络查询")) +a.description = translate("需下载 4.36m 原始数据,处理后完整版约 1.2M,简化版约 250kb
若无梯子,请勿使用网络查询") + +a=s:taboption("basic", Flag,"oui_dir",translate("下载到内存")) +a.rmempty = true +a:depends("oui_data","1") +a:depends("oui_data","2") +a.description = translate("懒得做自动更新了,下载到内存中,重启会重新下载
若无梯子,还是下到机身吧") + +a=s:taboption("basic", Flag,"reset_regularly",translate("每天零点重置流量数据")) +a.rmempty = true + +a=s:taboption("basic", Flag,"debuglevel",translate("开启日志")) +a.rmempty = true + +a= s:taboption("basic", DynamicList, "device_aliases", translate("设备别名")) +a.rmempty = true +a.description = translate("
请输入设备 MAC 和设备别名,用“-”隔开,如:
XX:XX:XX:XX:XX:XX-我的手机") + +--设备状态 +a=s:taboption("content", ListValue,"pushbot_ipv4",translate("ipv4 变动通知")) +a.rmempty = true +a.default="" +a:value("",translate("关闭")) +a:value("1",translate("通过接口获取")) +a:value("2",translate("通过URL获取")) + +a = s:taboption("content", ListValue, "ipv4_interface", translate("接口名称")) +a.rmempty = true +a:depends({pushbot_ipv4="1"}) +for _, iface in ipairs(ifaces) do + if not (iface == "lo" or iface:match("^ifb.*")) then + local nets = net:get_interface(iface) + nets = nets and nets:get_networks() or {} + for k, v in pairs(nets) do + nets[k] = nets[k].sid + end + nets = table.concat(nets, ",") + a:value(iface, ((#nets > 0) and "%s (%s)" % {iface, nets} or iface)) + end +end +a.description = translate("
一般选择 wan 接口,多拨环境请自行选择") + +a= s:taboption("content", DynamicList, "ipv4_URL", "URL 地址") +a.rmempty = true + +a:depends({pushbot_ipv4="2"}) +a.description = translate("
会因服务器稳定性、连接频繁等原因导致获取失败
从以上列表中随机一个地址,留空使用默认地址") + +a=s:taboption("content", ListValue,"pushbot_ipv6",translate("ipv6 变动通知")) +a.rmempty = true +a.default="disable" +a:value("0",translate("关闭")) +a:value("1",translate("通过接口获取")) +a:value("2",translate("通过URL获取")) + +a = s:taboption("content", ListValue, "ipv6_interface", translate("接口名称")) +a.rmempty = true +a:depends({pushbot_ipv6="1"}) +for _, iface in ipairs(ifaces) do + if not (iface == "lo" or iface:match("^ifb.*")) then + local nets = net:get_interface(iface) + nets = nets and nets:get_networks() or {} + for k, v in pairs(nets) do + nets[k] = nets[k].sid + end + nets = table.concat(nets, ",") + a:value(iface, ((#nets > 0) and "%s (%s)" % {iface, nets} or iface)) + end +end +a.description = translate("
一般选择 wan 接口,多拨环境请自行选择") + +a= s:taboption("content", DynamicList, "ipv6_URL", "URL 地址") +a.rmempty = true + +a:depends({pushbot_ipv6="2"}) +a.description = translate("
会因服务器稳定性、连接频繁等原因导致获取失败
从以上列表中随机一个地址,留空使用默认地址") + +a=s:taboption("content", Flag,"pushbot_up",translate("设备上线通知")) +a.default=1 +a.rmempty = true + +a=s:taboption("content", Flag,"pushbot_down",translate("设备下线通知")) +a.default=1 +a.rmempty = true + +a=s:taboption("content", Flag,"cpuload_enable",translate("CPU 负载报警")) +a.default=1 +a.rmempty = true + +a= s:taboption("content", Value, "cpuload", "负载报警阈值") +a.default = 2 +a.rmempty = true +a:depends({cpuload_enable="1"}) + +a=s:taboption("content", Flag,"temperature_enable",translate("CPU 温度报警")) +a.default=1 +a.rmempty = true +a.description = translate("请确认设备可以获取温度,如需修改命令,请移步高级设置") + +a= s:taboption("content", Value, "temperature", "温度报警阈值") +a.rmempty = true +a.default = "80" +a.datatype="uinteger" +a:depends({temperature_enable="1"}) +a.description = translate("
设备报警只会在连续五分钟超过设定值时才会推送
而且一个小时内不会再提醒第二次") + +a=s:taboption("content", Flag,"client_usage",translate("设备异常流量")) +a.default=0 +a.rmempty = true + +a= s:taboption("content", Value, "client_usage_max", "每分钟流量限制") +a.default = "10M" +a.rmempty = true +a:depends({client_usage="1"}) +a.description = translate("设备异常流量警报(byte),你可以追加 K 或者 M") + +a=s:taboption("content", Flag,"client_usage_disturb",translate("异常流量免打扰")) +a.default=1 +a.rmempty = true +a:depends({client_usage="1"}) + +a = s:taboption("content", DynamicList, "client_usage_whitelist", translate("异常流量关注列表")) +nt.mac_hints(function(mac, name) a:value(mac, "%s (%s)" %{ mac, name }) end) +a.rmempty = true +a:depends({client_usage_disturb="1"}) +a.description = translate("请输入设备 MAC") + +--定时推送 +a=s:taboption("crontab", ListValue,"send_mode",translate("定时任务设定")) +a.rmempty = true +a.default="" +a:value("",translate("关闭")) +a:value("1",translate("定时发送")) +a:value("2",translate("间隔发送")) + +a=s:taboption("crontab", ListValue,"regular_time",translate("发送时间")) +a.rmempty = true +for t=0,23 do +a:value(t,translate("每天"..t.."点")) +end +a.default=8 +a.datatype=uinteger +a:depends("send_mode","1") + +a=s:taboption("crontab", ListValue,"regular_time_2",translate("发送时间")) +a.rmempty = true +a:value("",translate("关闭")) +for t=0,23 do +a:value(t,translate("每天"..t.."点")) +end +a.default="关闭" +a.datatype=uinteger +a:depends("send_mode","1") + +a=s:taboption("crontab", ListValue,"regular_time_3",translate("发送时间")) +a.rmempty = true + +a:value("",translate("关闭")) +for t=0,23 do +a:value(t,translate("每天"..t.."点")) +end +a.default="关闭" +a.datatype=uinteger +a:depends("send_mode","1") + +a=s:taboption("crontab", ListValue,"interval_time",translate("发送间隔")) +a.rmempty = true +for t=1,23 do +a:value(t,translate(t.."小时")) +end +a.default=6 +a.datatype=uinteger +a:depends("send_mode","2") +a.description = translate("
从 00:00 开始,每 * 小时发送一次") + +a= s:taboption("crontab", Value, "send_title", translate("推送标题")) +a:depends("send_mode","1") +a:depends("send_mode","2") +a.placeholder = "OpenWrt By tty228 路由状态:" +a.description = translate("
使用特殊符号可能会造成发送失败") + +a=s:taboption("crontab", Flag,"router_status",translate("系统运行情况")) +a.default=1 +a:depends("send_mode","1") +a:depends("send_mode","2") + +a=s:taboption("crontab", Flag,"router_temp",translate("设备温度")) +a.default=1 +a:depends("send_mode","1") +a:depends("send_mode","2") + +a=s:taboption("crontab", Flag,"router_wan",translate("WAN信息")) +a.default=1 +a:depends("send_mode","1") +a:depends("send_mode","2") + +a=s:taboption("crontab", Flag,"client_list",translate("客户端列表")) +a.default=1 +a:depends("send_mode","1") +a:depends("send_mode","2") + +e=s:taboption("crontab", Button,"_add",translate("手动发送")) +e.inputtitle=translate("发送") +e:depends("send_mode","1") +e:depends("send_mode","2") +e.inputstyle = "apply" +function e.write(self, section) +luci.sys.call("cbi.apply") + luci.sys.call("/usr/bin/pushbot/pushbot send &") +end + +--免打扰 +a=s:taboption("disturb", ListValue,"pushbot_sheep",translate("免打扰时段设置"),translate("在指定整点时间段内,暂停推送消息
免打扰时间中,定时推送也会被阻止。")) +a.rmempty = true + +a:value("",translate("关闭")) +a:value("1",translate("模式一:脚本挂起")) +a:value("2",translate("模式二:静默模式")) +a.description = translate("模式一停止一切检测,包括无人值守。") +a=s:taboption("disturb", ListValue,"starttime",translate("免打扰开始时间")) +a.rmempty = true + +for t=0,23 do +a:value(t,translate("每天"..t.."点")) +end +a.default=0 +a.datatype=uinteger +a:depends({pushbot_sheep="1"}) +a:depends({pushbot_sheep="2"}) +a=s:taboption("disturb", ListValue,"endtime",translate("免打扰结束时间")) +a.rmempty = true + +for t=0,23 do +a:value(t,translate("每天"..t.."点")) +end +a.default=8 +a.datatype=uinteger +a:depends({pushbot_sheep="1"}) +a:depends({pushbot_sheep="2"}) + +a=s:taboption("disturb", ListValue,"macmechanism",translate("MAC过滤")) +a:value("",translate("disable")) +a:value("allow",translate("忽略列表内设备")) +a:value("block",translate("仅通知列表内设备")) +a:value("interface",translate("仅通知此接口设备")) +a.rmempty = true + + +a = s:taboption("disturb", DynamicList, "pushbot_whitelist", translate("忽略列表")) +nt.mac_hints(function(mac, name) a :value(mac, "%s (%s)" %{ mac, name }) end) +a.rmempty = true +a:depends({macmechanism="allow"}) + +a = s:taboption("disturb", DynamicList, "pushbot_blacklist", translate("关注列表")) +nt.mac_hints(function(mac, name) a:value(mac, "%s (%s)" %{ mac, name }) end) +a.rmempty = true +a:depends({macmechanism="block"}) + +a = s:taboption("disturb", ListValue, "pushbot_interface", translate("接口名称")) +a:depends({macmechanism="interface"}) +a.rmempty = true + +for _, iface in ipairs(ifaces) do + if not (iface == "lo" or iface:match("^ifb.*")) then + local nets = net:get_interface(iface) + nets = nets and nets:get_networks() or {} + for k, v in pairs(nets) do + nets[k] = nets[k].sid + end + nets = table.concat(nets, ",") + a:value(iface, ((#nets > 0) and "%s (%s)" % {iface, nets} or iface)) + end +end + +return m diff --git a/package/lean/luci-app-pushbot/luasrc/view/pushbot/log.htm b/package/lean/luci-app-pushbot/luasrc/view/pushbot/log.htm new file mode 100644 index 000000000..225f5f1db --- /dev/null +++ b/package/lean/luci-app-pushbot/luasrc/view/pushbot/log.htm @@ -0,0 +1,33 @@ +<% +local dsp = require "luci.dispatcher" +-%> + + +
+ <%:自动刷新%> + + +
diff --git a/package/lean/luci-app-pushbot/luasrc/view/pushbot/status.htm b/package/lean/luci-app-pushbot/luasrc/view/pushbot/status.htm new file mode 100644 index 000000000..40769f004 --- /dev/null +++ b/package/lean/luci-app-pushbot/luasrc/view/pushbot/status.htm @@ -0,0 +1,22 @@ + + +
+

+ <%:Collecting data...%> +

+
diff --git a/package/lean/luci-app-pushbot/root/etc/config/pushbot b/package/lean/luci-app-pushbot/root/etc/config/pushbot new file mode 100644 index 000000000..ec0ddfc4e --- /dev/null +++ b/package/lean/luci-app-pushbot/root/etc/config/pushbot @@ -0,0 +1,11 @@ + +config pushbot 'pushbot' + option pushbot_enable '0' + option sleeptime '60' + option pushbot_ipv6 '0' + option pushbot_up '1' + option pushbot_down '1' + option cpuload_enable '1' + option cpuload '2' + option temperature_enable '0' + diff --git a/package/lean/luci-app-pushbot/root/etc/init.d/pushbot b/package/lean/luci-app-pushbot/root/etc/init.d/pushbot new file mode 100644 index 000000000..be7d9d28c --- /dev/null +++ b/package/lean/luci-app-pushbot/root/etc/init.d/pushbot @@ -0,0 +1,26 @@ +#!/bin/sh /etc/rc.common + +START=99 +STOP=10 + +start() { + state=`pgrep -f "/usr/bin/pushbot/pushbot"` + if [ ! -z "$state" ]; then + restart + else + /usr/bin/pushbot/pushbot & + fi + echo "pushbot is starting now ..." +} + +stop() { + kill -9 `pgrep -f "/usr/bin/pushbot/pushbot"` 2>/dev/null + echo "pushbot exit ..." +} + +restart(){ + stop + sleep 1 + start + echo "restarted." +} diff --git a/package/lean/luci-app-pushbot/root/etc/uci-defaults/luci-pushbot b/package/lean/luci-app-pushbot/root/etc/uci-defaults/luci-pushbot new file mode 100644 index 000000000..c768cce4e --- /dev/null +++ b/package/lean/luci-app-pushbot/root/etc/uci-defaults/luci-pushbot @@ -0,0 +1,11 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@pushbot[-1] + add ucitrack pushbot + set ucitrack.@pushbot[-1].init=pushbot + commit ucitrack +EOF + +rm -rf /tmp/luci-* +exit 0 diff --git a/package/lean/luci-app-pushbot/root/usr/bin/pushbot/pushbot b/package/lean/luci-app-pushbot/root/usr/bin/pushbot/pushbot new file mode 100644 index 000000000..e62a147ff --- /dev/null +++ b/package/lean/luci-app-pushbot/root/usr/bin/pushbot/pushbot @@ -0,0 +1,1046 @@ +#!/bin/sh + +# 读取设置文件 +function get_config(){ + while [[ "$*" != "" ]]; do + eval ${1}='`uci get pushbot.pushbot.$1`' 2>/dev/null + shift + done +} + +# 初始化设置信息 +function read_config(){ + get_config "pushbot_enable" "dd_webhook" "pushbot_ipv4" "ipv4_interface" "pushbot_ipv6" "ipv6_interface" "pushbot_up" "pushbot_down" "pushbot_sheep" "pushbot_whitelist" "pushbot_blacklist" "pushbot_interface" "starttime" "endtime" "cpuload_enable" "cpuload" "temperature_enable" "temperature" "device_name" "err_enable" "network_err_event" "err_sheep_enable" "system_time_event" "autoreboot_time" "network_restart_time" "public_ip_event" "public_ip_retry_count" "soc_code" "sleeptime" "up_timeout" "down_timeout" "device_aliases" "debuglevel" "cpuload" "temperature" "send_mode" "regular_time" "regular_time_2" "regular_time_3" "interval_time" "thread_num" "timeout_retry_count" "send_we" "we_webhook" "pp_token" "pp_channel" "pp_webhook" "pp_topic_enable" "pp_topic" "fs_webhook" "bark_srv_enable" "bark_srv" "bark_token" "err_device_aliases" "oui_dir" "oui_data" "client_usage" "client_usage_max" "client_usage_disturb" "client_usage_whitelist" "reset_regularly" "ipv4_urllist" "ipv6_urllist" "lite_enable" "content_current_device" "content_nowtime" "content_content" + 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 + dir="/tmp/pushbot/" && mkdir -p ${dir} + [ ! -z "$oui_dir" ] && [ "$oui_dir" -eq "1" ] && oui_base="${dir}oui_base.txt" || oui_base="/usr/bin/pushbot/oui_base.txt" + debuglevel=`echo "$debuglevel"` && [ -z "$debuglevel" ] && logfile="/dev/null" || logfile="${dir}pushbot.log" + device_aliases=`echo "$device_aliases"|sed 's/ /\n/g'|sed 's/-/ /'` 2>/dev/null + err_device_aliases=`echo "$err_device_aliases"|sed 's/ /\n/g'` 2>/dev/null + client_usage_whitelist=`echo "$client_usage_whitelist"|sed 's/ /\n/g'` 2>/dev/null + [ "$iw_version" ] && wlan_interface=`iw dev|grep Interface|awk '{print $2}'` >/dev/null 2>&1 + [ -z "$up_timeout" ] || [ "$up_timeout" -eq "0" ] && up_timeout="2" + [ -z "$down_timeout" ] || [ "$down_timeout" -eq "0" ] && down_timeout="20";down_timeout=`expr ${down_timeout} / 2 + 1` + [ -z "$timeout_retry_count" ] && timeout_retry_count="2";[ "$timeout_retry_count" -eq "0" ] && timeout_retry_count="1" + markdown_splitline="\n\n---\n\n";markdown_linefeed="\n\n";markdown_tab=" ";markdown_space=" ";greenfont="";bluefont="";fontend=""; + tabletab=${bluefont}┋${fontend};boldstar="**";titlel4="####";titlebold="**";titleboldend="**";titleblue="";titlegreen="";titleend="";titlered="" + [ ! -z "$send_we" ] && [ "$send_we" -eq "1" ] && markdown_splitline="\n\n-------\n\n" && markdown_tab=" " + [ ! -z "$send_we" ] && [ "$send_we" -eq "2" ] && percentsym=25 && markdown_splitline="%0D%0A%0D%0A" && markdown_linefeed="%0D%0A%0D%0A" && greenfont="" && bluefont="" && fontend="" && tabletab=" " && boldstar="" + [ ! -z "$send_we" ] && [ "$send_we" -eq "3" ] && titlel4="" && titlebold="【" && titleboldend="】" && titleblue="" && titlegreen="" && titleend="" && titlered="" && greenfont="" && bluefont="" && fontend="" && tabletab=" " && boldstar="" && markdown_splitline="\n---\n" && markdown_linefeed="\n" + [ ! -z "$send_we" ] && [ "$send_we" -eq "4" ] && titlel4="" && titlebold="【" && titleboldend="】" && titleblue="" && titlegreen="" && titleend="" && titlered="" && greenfont="" && bluefont="" && fontend="" && tabletab=" " && boldstar="" && markdown_splitline="%0D%0A%0D%0A" && markdown_linefeed="%0D%0A%0D%0A" && percentsym=25 && [ -z "$bark_srv" ] && bark_srv="https://api.day.app" + # [ ! -z "$content_content" ] && [ "$content_content" -eq "1" ] && str_title_start="" && str_title_end="" && str_splitline="" && str_linefeed="" && str_tab="" +} + +# 初始化 +function pushbot_init(){ + enable_detection + if [ -f "/usr/bin/pushbot/errlog" ]; then + cat /usr/bin/pushbot/errlog > ${logfile} + echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】载入上次重启前日志" >> ${logfile} + echo "--------------------------------------------------------" >> ${logfile} + fi + down_oui & + deltemp + rm -f ${dir}fd1 ${dir}sheep_usage ${dir}old_sheep_usage ${dir}client_usage_aliases ${dir}old_client_usage_aliases /usr/bin/pushbot/errlog >/dev/null 2>&1 + [ ! -f "/usr/sbin/wrtbwmon" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】未安装 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 "$dd_webhook" ] && [ -z "$pp_token" ] && [ -z "$we_webhook" ] && [ -z "$fs_webhook" ] && [ -z "$bark_token" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】请填写正确的Token/Webhook " >> ${logfile} && return 1 + local interfacelist=`getinterfacelist` && [ -z "$interfacelist" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】无法正确获取接口信息,请确认插件是否正常运行" >> ${logfile} + return 0 +} + +# 下载设备MAC厂商信息 +function down_oui(){ + [ -f ${oui_base} ] && local logrow=$(grep -c "" ${oui_base}) || local logrow="0" + [ $logrow -lt "10" ] && rm -f ${oui_base} >/dev/null 2>&1 + if [ ! -z "$oui_data" ] && [ "$oui_data" -ne "3" ] && [ ! -f ${oui_base} ]; then + echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】设备MAC厂商信息不存在,重新下载" >> ${logfile} + wget --no-check-certificate -t 3 -T 15 -O ${dir}oui.txt https://linuxnet.ca/ieee/oui.txt >/dev/null 2>&1 + if [ -f ${dir}oui.txt ] && [ "$oui_data" -eq "1" ]; then + cat ${dir}oui.txt|grep "base 16"|grep -i "apple\|aruba\|asus\|autelan\|belkin\|bhu\|buffalo\|cctf\|cisco\|comba\|datang\|dell\|dlink\|dowell\|ericsson\|fast\|feixun\|\ +fiberhome\|fujitsu\|grentech\|h3c\|hisense\|hiwifi\|honghai\|honghao\|hp\|htc\|huawei\|intel\|jinli\|jse\|lenovo\|lg\|liteon\|malata\|meizu\|mercury\|meru\|moto\|netcore\|\ +netgear\|nokia\|omron\|oneplus\|oppo\|philips\|router_unkown\|samsung\|shanzhai\|sony\|start_net\|sunyuanda\|tcl\|tenda\|texas\|tianyu\|tp-link\|ubq\|undefine\|VMware\|\ +utstarcom\|volans\|xerox\|xiaomi\|zdc\|zhongxing\|smartisan" > ${oui_base} && echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】设备MAC厂商信息下载成功" >> ${logfile} || echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】设备MAC厂商信息下载失败" >> ${logfile} + fi + if [ -f ${dir}oui.txt ] && [ "$oui_data" -eq "2" ]; then + cat ${dir}oui.txt|grep "base 16" > ${oui_base} && echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】设备MAC厂商信息下载成功" >> ${logfile} || echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】设备MAC厂商信息下载失败" >> ${logfile} + fi + rm -f ${dir}oui.txt >/dev/null 2>&1 + fi +} + +# 清理临时文件 +function deltemp(){ + unset title content + rm -f ${dir}title ${dir}content ${dir}top ${dir}tmp_downlist ${dir}send_enable.lock >/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 pushbot_enable;[ -z "$pushbot_enable" ] || [ "$pushbot_enable" -eq "0" ] && `/etc/init.d/pushbot stop` || sleep 1 + done +} + +# 获取 ip +function getip(){ + [ ! "$1" ] && return + 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" + elif [ $1 == "hostipv4" ] ;then + function get_hostipv4() + { + [ -z "$ipv4_urllist" ] && local ipv4_urllist="www.cip.cc myip.ipip.net ipv4.ddnspod.com ifcfg.cn speed.neu.edu.cn/getIP.php ddns.oray.com/checkip www.net.cn/static/customercare/yourip.asp" + local url_number=`expr $(echo "$ipv4_urllist"|grep -o ' '|wc -l) + 1` + local ipv4_URL=`echo "$ipv4_urllist"|awk -v i=$(rand 1 $url_number) '{print $i}'` + [ ! -z "$ipv4_interface" ] && local hostIP=$(curl -k -s -4 --interface ${ipv4_interface} -m 5 ${ipv4_URL}) || local hostIP=$(curl -k -s -4 -m 5 ${ipv4_URL}) + echo $hostIP|grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'|head -n1 + } + local hostIP=`get_hostipv4` + [ -z "$hostIP" ] && local hostIP=`get_hostipv4` + [ -z "$hostIP" ] && local hostIP=`get_hostipv4` + echo $hostIP + elif [ $1 == "wanipv6" ] ;then + [ ! -z "$ipv6_interface" ] && local wanIPv6=$(ip addr show ${ipv6_interface}|grep -v deprecated|grep -A1 'inet6 [^f:]'|sed -nr ':a;N;s#^ +inet6 ([a-f0-9:]+)/.+? scope global .*? valid_lft ([0-9]+sec) .*#\2 \1#p;ta'|sort -nr|head -n1|awk '{print $2}') + [ -z "$ipv6_interface" ] && local wanIPv6=$(ip addr show|grep -v deprecated|grep -A1 'inet6 [^f:]'|sed -nr ':a;N;s#^ +inet6 ([a-f0-9:]+)/.+? scope global .*? valid_lft ([0-9]+sec) .*#\2 \1#p;ta'|sort -nr|head -n1|awk '{print $2}') + echo "$wanIPv6" + elif [ $1 == "hostipv6" ] ;then + function get_hostipv6() + { + [ -z "$ipv6_urllist" ] && local ipv6_urllist="ip.sb ipv6.ddnspod.com api-ipv6.ip.sb/ip speed.neu6.edu.cn/getIP.php v6.myip.la/json" + local urlv6_number=`expr $(echo "$ipv6_urllist"|grep -o ' '|wc -l) + 1` + local ipv6_URL=`echo "$ipv6_urllist"|awk -v i=$(rand 1 $url_number) '{print $i}'` + [ ! -z "$ipv6_interface" ] && local hostIPv6=$(curl -k -s -6 --interface ${ipv6_interface} -m 5 ${ipv6_URL}) || local hostIPv6=$(curl -k -s -6 -m 5 ${ipv6_URL}) + echo $hostIPv6|grep -oE '([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}' + } + local hostIPv6=`get_hostipv6` + [ -z "$hostIPv6" ] && local hostIPv6=`get_hostipv6` + [ -z "$hostIPv6" ] && local hostIPv6=`get_hostipv6` + echo $hostIPv6 # 重试,偷懒,有空再优化 + fi +} + +# 获取接口信息 +function getinterfacelist(){ + [ `ubus list|grep -w -i "network.interface.wan"|wc -l` -ge "1" ] && ubus call network.interface.wan status && return + [ `ubus list|grep -i "network.interface."|grep -v "loopback"|grep -v "wan6"|wc -l` -eq "1" ] && ubus call `ubus list|grep "network.interface."|grep -v "loopback"` status && return +} + +# 获取接口在线时间 +function getinterfaceuptime(){ + getinterfacelist|grep \"uptime\"|sed $'s/\"uptime": //g'|sed $'s/\,//g' +} + +# 查询 mac 地址 +function getmac(){ + ( echo "$tmp_mac"|grep -q "unknown" ) && unset tmp_mac # 为unknown时重新读取 + [ -f "${dir}ipAddress" ] && [ -z "$tmp_mac" ] && local tmp_mac=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $2}'|grep -v "^$"|sort -u|head -n1` + [ -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` + [ -f "/var/dhcp.leases" ] && [ -z "$tmp_mac" ] && local tmp_mac=`cat /var/dhcp.leases|grep -w ${1}|awk '{print $2}'|grep -v "^$"|sort -u|head -n1` + [ -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" +} + +# 查询主机名 +function getname(){ + [ -z "$tmp_name" ] && local tmp_name=`echo "$device_aliases"|grep -i $2|awk '{print $2}'|grep -v "^$"|sort -u|head -n1` + [ -f "${dir}ipAddress" ] && [ -z "$tmp_name" ] && local tmp_name=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $3}'|grep -v "^$"|sort -u|head -n1` + [ -f "${dir}tmp_downlist" ] && [ -z "$tmp_name" ] && 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\|*" ) && [ ! -z "$tmp_name" ] && echo "$tmp_name" && return || unset tmp_name # 为unknown时重新读取 + [ -f "/var/dhcp.leases" ] && [ -z "$tmp_name" ] && local tmp_name=`cat /var/dhcp.leases|grep -w ${1}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1` + ( ! echo "$tmp_name"|grep -q -w "unknown\|*" ) && [ ! -z "$tmp_name" ] && echo "$tmp_name" && return || unset tmp_name # 为unknown时重新读取 + [ -z "$dhcp_config" ] && dhcp_config=`uci show dhcp|grep "ip\|mac\|name"` + for dhcp_config_str in "host" "domain"; do + local 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" ] && local tmp_name=`uci get dhcp.${dhcp_ip_n}.name` 2>/dev/null + local 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" ] && local tmp_name=`uci get dhcp.${dhcp_ip_n}.name` 2>/dev/null + [ ! -z "$tmp_name" ] && break + done + ( ! echo "$tmp_name"|grep -q -w "unknown\|*" ) && [ ! -z "$tmp_name" ] && echo "$tmp_name" && return || unset tmp_name # 为unknown时重新读取 + [ -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'|sed 's/ /_/g') + [ ! -z "$oui_data" ] && [ "$oui_data" -eq "4" ] && local tmp_name=$(curl -sS "http://standards-oui.ieee.org/oui.txt"|grep -i $(echo "$2"|cut -c 1,2,4,5,7,8)|sed -nr 's#^.*16)..(.*)#\1#gp'|sed 's/ /_/g') + [ -z "$tmp_name" ] && local tmp_name="unknown" + echo "$tmp_name" +} + +# 查询设备接口 +function getinterface(){ + [ -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" +} + +# ping +function getping(){ + [ "$iw_version" ] && local wlan_online=`iw dev ${ip_interface} station dump|grep -i -w ${ip_mac}|grep Station` >/dev/null 2>&1 + [ "$wlan_online" ] && return 0 + for i in `seq 1 ${3}`; do + ( ! echo "$ip_ms"|grep -q "ms" ) && local ip_ms=$( arping -I `cat /proc/net/arp|grep -w ${1}|awk '{print $6}'|grep -v "^$"|sort -u|head -n1` -c 20 -f -w ${2} $1 ) 2>/dev/null + ( ! echo "$ip_ms"|grep -q "ms" ) && local ip_ms=`ping -c 5 -w ${2} ${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 3 + 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" ] && soc_code="cat /sys/class/thermal/thermal_zone*/temp|sort -nr|head -n1|cut -c-2" + [ "$soc_code" == "sensors" ] && soc_code="sensors|grep °C|sed -nr 's#^.*:.*\+(.*)°C .*#\1#gp'|sort -nr|head -n1" + echo "$soc_code"|awk '{run=$0;system(run)}' 2>/dev/null +} + +# 流量数据 +function usage(){ + [ ! -f "/usr/sbin/wrtbwmon" ] || [ ! "$1" ] && return + if [ $1 == "update" ] ;then + function version_le() { test "$(echo "$@"|tr " " "\n"|sort -V|head -n 1)" == "$1"; } + function version_ge() { test "$(echo "$@"|tr " " "\n"|sort -rV|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'}'`G" && return + [ "$1" -gt 1048576 ] && echo "`awk 'BEGIN{printf "%.2f\n",'$1'/'1048576'}'` M" && return + [ "$1" -gt 1024 ] && echo "`awk 'BEGIN{printf "%.2f\n",'$1'/'1024'}'` K" && 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="${markdown_linefeed}${markdown_tab}总计流量: ${markdown_space}${markdown_space}${markdown_space}${markdown_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}${markdown_splitline}${titlel4} ${titlered}设备流量异常${titleend}${markdown_linefeed}${markdown_tab}客户端名:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_name}${markdown_linefeed}${markdown_tab}客户端IP: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip}${markdown_linefeed}${markdown_tab}客户端MAC:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${mac}$ip_total${markdown_linefeed}${markdown_tab}一分钟内流量: ${markdown_space}${markdown_space}${tmp_usage}${markdown_linefeed}${markdown_tab}在线时间: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${time1}" + elif ( echo "$title"|grep -q "流量异常" ); then + title="${ip_name} ${title}" + content="${content}${markdown_splitline}${markdown_tab}客户端名:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_name}${markdown_linefeed}${markdown_tab}客户端IP: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip}${markdown_linefeed}${markdown_tab}客户端MAC:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${mac}$ip_total${markdown_linefeed}${markdown_tab}一分钟内流量: ${markdown_space}${markdown_space}${markdown_space}${tmp_usage}${markdown_linefeed}${markdown_tab}在线时间: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${time1}" + else + title="设备状态变化" + content="${content}${markdown_splitline}${titlel4} ${titlered}设备流量异常${titleend}${markdown_linefeed}${markdown_tab}客户端名:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_name}${markdown_linefeed}${markdown_tab}客户端IP: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip}${markdown_linefeed}${markdown_tab}客户端MAC:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${mac}$ip_total${markdown_linefeed}${markdown_tab}一分钟内流量: ${markdown_space}${markdown_space}${markdown_space}${tmp_usage}${markdown_linefeed}${markdown_tab}在线时间: ${markdown_space}${markdown_space}${markdown_space}${markdown_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 `expr $length_zh / 3 \* 2 + $length_en` +} + +# 截取字符,避免中文乱码 +function cut_str { + [ ! "$1" ] && return + [ ! "$2" ] && return + [ `length_str $1` -le "$2" ] && echo "$1" && return + local temp_length=$2 + while [ $(length_str `echo "$1"|cut -c -$temp_length`) -lt "$2" ]; do + temp_length=`expr $temp_length + 1` + done + while [ $(printf "%d" \'`echo "$1"|cut -c $temp_length`) -ge "128" ] && [ $(printf "%d" \'`echo "$1"|cut -c $temp_length`) -lt "224" ]; do + temp_length=`expr $temp_length + 1` + done + temp_length=`expr $temp_length - 1` + echo $(echo "$1"|cut -c -$temp_length)"*" +} + +# 随机数 +function rand(){ + min=$1 + max=$(($2- $min + 1)) + num=$(date +%s%N) + echo $(($num % $max + $min)) +} + +# 在线设备列表 +function pushbot_first(){ + [ -f "${dir}ipAddress" ] && local IPLIST=`cat ${dir}ipAddress|awk '{print $1}'|grep -v "^$"|sort -u` + for ip in $IPLIST; do + read -u 5 + { + down $ip + echo "" >&5 + }& + done + wait + unset ip IPLIST + local IPLIST=`cat /proc/net/arp|grep "0x2\|0x6"|awk '{print $1}'|grep -v "^169.254."|grep -v "^$"|sort -u` + for ip in $IPLIST; do + read -u 5 + { + up $ip + echo "" >&5 + }& + done + wait +} + +# 创建计划任务 +function pushbot_cron(){ + function del_cron(){ + ( echo `crontab -l 2>/dev/null`|grep -q "pushbot" ) && crontab -l > conf && sed -i "/pushbot/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 "$pushbot_enable" ] || [ -z "$send_mode" -a -z "$reset_regularly" ]; 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 /tmp/pushbot/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 /tmp/pushbot/usage6.db >/dev/null 2>&1" >> conf && crontab conf && rm -f conf >/dev/null 2>&1 + fi + [ ! -z "$regular_time_2" ] && local regular_time_2=",${regular_time_2}" + [ ! -z "$regular_time_3" ] && local regular_time_3=",${regular_time_3}" + # 定时发送 + if [ ! -z "$regular_time" ] || [ ! -z "$regular_time_2" ] || [ ! -z "$regular_time_3" ]; then + crontab -l 2>/dev/null > conf && echo -e "0 $regular_time$regular_time_2$regular_time_3 * * * /usr/bin/pushbot/pushbot send &" >> conf && crontab conf && rm -f conf >/dev/null 2>&1 + # 间隔发送 + elif [ ! -z "$interval_time" ]; then + crontab -l 2>/dev/null > conf && echo -e "0 */$interval_time * * * /usr/bin/pushbot/pushbot send &" >> conf && crontab conf && rm -f conf >/dev/null 2>&1 + fi + re_cron +} + +# 免打扰检测 +function pushbot_disturb(){ + [ -z "$pushbot_sheep" ] || [ -z "$starttime" ] || [ -z "$endtime" ] && return 0 + if [ `date +%H` -ge $endtime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a `date +%H` -ge $endtime -a $starttime -gt $endtime ]; then + unset sheep_starttime + rm -f ${dir}sheep_usage ${dir}old_sheep_usage 2>/dev/null + disturb_text="【钉钉推送】" + [ ! -z "$send_we" ] && [ "$send_we" -eq "1" ] && disturb_text="【企业微信推送】" + return 0 + else + [ -z "$sheep_starttime" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【免打扰】夜深了,该休息了" >> ${logfile} && sheep_starttime=`date +%s` + if [ "$pushbot_sheep" -eq "1" ] ;then + while [ `date +%H` -lt "$endtime" ]; do + enable_detection + sleep $sleeptime + done + elif [ "$pushbot_sheep" -eq "2" ] ;then + disturb_text="【免打扰】" + return 1 + fi + fi +} + +# 文件锁 +function LockFile(){ + if [ $1 = "lock" ] ;then + [ ! -f "${dir}pushbot.lock" ] && > ${dir}pushbot.lock && return + while [ -f "${dir}pushbot.lock" ]; do + enable_detection 1 + done + LockFile lock + fi + [ $1 = "unlock" ] && rm -f ${dir}pushbot.lock >/dev/null 2>&1 + return +} + +# 检测黑白名单 +function blackwhitelist(){ + [ ! "$1" ] && return 1 + [ -z "$pushbot_whitelist" ] && [ -z "$pushbot_blacklist" ] && [ -z "$pushbot_interface" ] && return + [ ! -z "$pushbot_whitelist" ] && ( ! echo "$pushbot_whitelist"|grep -q -i -w $1) && return + [ ! -z "$pushbot_blacklist" ] && ( echo "$pushbot_blacklist"|grep -q -i -w $1) && return + [ ! -z "$pushbot_interface" ] && ( echo `getinterface ${1}`|grep -q -i -w $pushbot_interface ) && return + return 1 +} + +function get_client(){ + if [ -f "${dir}ipAddress" ]; then + while read line; do + local js_str="${js_str}
" + local js_str="${js_str}
<%:`echo "$line"|awk '{print $3}'`%>
" + local tmp_mac=`echo "$line"|awk '{print $2}'` + local js_str="${js_str}
<%:${tmp_mac}%>
" + local js_str="${js_str}
<%:`echo "$line"|awk '{print $1}'`%>
" + local tmp_usage=`usage get ${tmp_mac}` + local js_str="${js_str}
<%:${tmp_usage}%>
" + local tmp_uptime=`echo "$line"|awk '{print $4}'` + local tmp_timenow=`date +%s` + local tmp_uptime=$(time_for_humans `expr ${tmp_timenow} - ${tmp_uptime}`) + local js_str="${js_str}
<%:${tmp_uptime}%>
" + done < ${dir}ipAddress + fi +cat>/usr/lib/lua/luci/view/pushbot/client.htm<<%:在线设备列表%>
<%:客户端名%>
<%:MAC%>
<%:IP%>
<%:总计流量%>
<%:在线时间%>
+$js_str +
+EOF +} + +# 重启网络服务 +function network_restart(){ +cat>${dir}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 "$err_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 "$err_mac" ] && [ ! -z "$mac" ] && local err_mac=`echo "$err_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 "$err_device_aliases"|grep -v "^$"|sort -u` + for mac in $MACLIST; 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 + 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 err_mac + fi + [ -z "$err_mac" ] +} + +# 无人值守任务 +function unattended(){ + [ -z "$err_enable" ] || [ "$err_enable" -ne "1" ] && return + [ ! -z "$err_sheep_enable" ] && [ "$err_sheep_enable" -eq "1" ] && [ -z "$sheep_starttime" ] && return + geterrdevicealiases;[ $? -eq "1" ] && return + + if [ ! -z "$system_time_event" ]; then + local interfaceuptime=`getinterfaceuptime` + if [ ! -z "$autoreboot_time" ] && [ `cat /proc/uptime|awk -F. '{run_hour=$1/3600;printf("%d",run_hour)}'` -ge "$autoreboot_time" ] && [ "$system_time_event" -eq "1" ]; then + echo "`date "+%Y-%m-%d %H:%M:%S"` 【无人值守任务】重启路由器咯" >> ${logfile} + cat ${logfile} > /usr/bin/pushbot/errlog + sleep 2 && reboot && exit + elif [ ! -z "$network_restart_time" ] && [ ! -z "$interfaceuptime" ] && [ `echo "$interfaceuptime"|awk -F. '{run_hour=$1/3600;printf("%d",run_hour)}'` -ge "$network_restart_time" ] && [ "$system_time_event" -eq "2" ]; then + echo "`date "+%Y-%m-%d %H:%M:%S"` 【无人值守任务】重新拨号咯" >> ${logfile} + ifup wan >/dev/null 2>&1 + sleep 60 + fi + fi + + [ -z "$public_ip_today" ] && public_ip_today=`date +"%d"` + [ -z "$public_ip_count" ] && public_ip_count="0" + [ $public_ip_today -ne `date +"%d"` ] && public_ip_today=`date +"%d"` && public_ip_count=1 + if [ ! -z "$public_ip_event" ] && [ ! -z "$public_ip_retry_count" ] && [ "$public_ip_count" -le "$public_ip_retry_count" ]; then + public_ip_count=`expr $public_ip_count + 1` + local wanIP=`getip wanipv4` + local hostIP=`getip hostipv4` + if [ ! -z "$wanIP" ] && [ ! -z "$hostIP" ] && ( ! echo "$wanIP"|grep -q -w ${hostIP} );then + echo "`date "+%Y-%m-%d %H:%M:%S"` 【无人值守任务】重拨尝试获取公网 ip,当前第 $public_ip_count 次 " >> ${logfile} + ifup wan >/dev/null 2>&1 + sleep 60 + local wanIP=`getip wanipv4` && local hostIP=`getip hostipv4` + [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -eq "1" ] && local IPv4=${wanIP} + [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -eq "2" ] && local IPv4=${hostIP} + [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -eq "1" ] && local IPv6=`getip wanipv6` + [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -eq "2" ] && local IPv6=`getip hostipv6` + [ ! -z "$wanIP" ] && [ ! -z "$hostIP" ] && ( ! echo "$wanIP"|grep -q -w ${hostIP} ) && echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $last_IPv6 >> ${dir}ip + 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 "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36" -o /dev/null` + } + local check=`getcheck` + while [ -z "$check" ] || [ "$check" -ne "200" ]; do + local check=`getcheck` + if [ ! -z "$check" ] && [ "$check" -eq "200" ]; 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_err_time" ] && network_err_time=`date +%s` + if [ ! -z "$network_err_event" ] && [ "$((`date +%s`-$network_err_time))" -ge "600" ]; then + > ${dir}send_enable.lock && pushbot_first && deltemp + geterrdevicealiases + if [ "$?" -eq "0" ]; then + [ -f /usr/bin/pushbot/autoreboot_count ] && retry_count=`cat /usr/bin/pushbot/autoreboot_count` && rm -f /usr/bin/pushbot/autoreboot_count >/dev/null 2>&1 + [ ! -z ${retry_count} ] && retry_count=0;retry_count=`expr $retry_count + 1` + if [ "$network_err_event" -eq "1" ] ;then + if [ "$retry_count" -lt "3" ] ;then + echo "$retry_count" > /usr/bin/pushbot/autoreboot_count + echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】正在尝试重启路由,当前第 $retry_count 次 " >> ${logfile} + cat ${logfile} > /usr/bin/pushbot/errlog + sleep 2 && reboot && exit + fi + [ "$retry_count" -eq "3" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】已经重启路由2次,修复失败,请主人自行修复哦" >> ${logfile} + elif [ "$network_err_event" -eq "2" ] ;then + [ "$retry_count" -lt "3" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】正在尝试重启网络,当前第 $retry_count 次 " >> ${logfile} && ifup wan >/dev/null 2>&1 + [ "$retry_count" -eq "3" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】已经重启网络2次,修复失败,请主人自行修复哦 " >> ${logfile} + elif [ "$network_err_event" -eq "3" ] ;then + if [ "$retry_count" -eq "1" ] ;then + echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】正在尝试修复网络,当前第 1 次,重启网络服务中 " >> ${logfile} && network_restart + elif [ "$retry_count" -eq "2" ] ;then + echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】正在尝试修复网络,当前第 2 次,关闭可能造成网络断开的软件" >> ${logfile} + [ `uci get koolproxy.@global[0].enabled 2>/dev/null` -eq "1" ] && [ `uci get koolproxy.@global[0].koolproxy_mode 2>/dev/null` -eq "1" ] && /etc/init.d/koolproxy stop >/dev/null 2>&1 + [ `uci get adbyby.@adbyby[0].enable 2>/dev/null` -eq "1" ] && [ `uci get adbyby.@adbyby[0].wan_mode 2>/dev/null` -eq "0" ] && /etc/init.d/adbyby stop >/dev/null 2>&1 + [ `uci get passwall.@global[0].enabled 2>/dev/null` -eq "1" ] && [ `uci get passwall.@global[0].proxy_mode 2>/dev/null|grep global` ] && /etc/init.d/koolproxy stop >/dev/null 2>&1 + local shadowsocksr_enabled=`uci get shadowsocksr.@global[0].global_server 2>/dev/null|grep nil` + local shadowsocksr_run_mode=`uci get shadowsocksr.@global[0].run_mode 2>/dev/null|grep all` + [ -z "$shadowsocksr_enabled" ] && [ ! -z "$shadowsocksr_run_mode" ] && /etc/init.d/shadowsocksr stop >/dev/null 2>&1 + sleep 60 && network_restart + elif [ "$retry_count" -eq "3" ] ;then + echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】正在尝试修复网络,当前第 3 次,备份设置项,并修改相关设置" >> ${logfile} + mkdir -p /usr/bin/pushbot/configbak + cp -p -f /etc/config/network /usr/bin/pushbot/configbak/network + cp -p -f /etc/config/dhcp /usr/bin/pushbot/configbak/dhcp + cp -p -f /etc/config/firewall /usr/bin/pushbot/configbak/firewall + cp -p -f /etc/firewall.user /usr/bin/pushbot/configbak/firewall.user + uci set network.wan.peerdns='0' + uci delete network.wan.dns + uci add_list network.wan.dns='223.5.5.5' + uci add_list network.wan.dns='119.29.29.29' + uci delete network.wan.mtu + uci commit network + uci set dhcp.@dnsmasq[0].port='53' + uci set dhcp.@dnsmasq[0].resolvfile='/tmp/resolv.conf.auto' + uci delete dhcp.@dnsmasq[0].server + uci delete dhcp.@dnsmasq[0].noresolv + uci commit dhcp + uci delete firewall.redirect + >/etc/firewall.user + uci commit firewall + sleep 60 && network_restart + elif [ "$retry_count" -eq "4" ] ;then + echo "$retry_count" > /usr/bin/pushbot/autoreboot_count + cat ${logfile} > /usr/bin/pushbot/errlog + sleep 2 && reboot && exit + elif [ "$retry_count" -eq "5" ] ;then + echo "$retry_count" > /usr/bin/pushbot/autoreboot_count + echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】修复失败,还原设置中,请自行检查网络设置" >> ${logfile} + cp -p -f /usr/bin/pushbot/configbak/network /etc/config/network + cp -p -f /usr/bin/pushbot/configbak/dhcp /etc/config/dhcp + cp -p -f /usr/bin/pushbot/configbak/firewall /etc/config/firewall + cp -p -f /usr/bin/pushbot/configbak/firewall.user /etc/firewall.user + cat ${logfile} > /usr/bin/pushbot/errlog + sleep 2 && reboot && exit + fi + fi + fi + elif [ -f /usr/bin/pushbot/autoreboot_count ]; then + network_err_time=`expr $network_err_time - 600` && sleep 60 + fi + enable_detection + sleep $sleeptime + fi + continue + done + rm -f /usr/bin/pushbot/autoreboot_count >/dev/null 2>&1 +} + +# 检测 ip 状况 +function ip_changes(){ + [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -eq "1" ] && local IPv4=`getip wanipv4` + [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -eq "2" ] && local IPv4=`getip hostipv4` + [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -eq "1" ] && local IPv6=`getip wanipv6` + [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -eq "2" ] && local IPv6=`getip hostipv6` + + 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 [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -ne "0" ] && [ ! -z "$IPv4" ] && ( ! echo ${IPv4}|grep -w -q ${last_IPv4} ); then + echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}当前IP:${IPv4}" >> ${logfile} + echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $last_IPv6 >> ${dir}ip + title="IP 地址变化" + content="${content}${markdown_splitline}${titlel4} ${titlegreen}IP 地址变化${titleend}${markdown_linefeed}${markdown_tab}当前 IP:${IPv4}" + elif [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -ne "0" ] && [ -z "$IPv4" ]; then + echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】获取 IPv4 地址失败" >> ${logfile} + fi + + if [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -ne "0" ] && [ ! -z "$IPv6" ] && ( ! echo "$IPv6"|grep -w -q ${last_IPv6} ); then + echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}当前IPv6:${IPv6}" >> ${logfile} + echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $IPv6 >> ${dir}ip + [ -z "$title" ] && title="IPv6 地址变化" + [ ! -z "$title" ] && title="IP 地址变化" + content="${content}${markdown_splitline}${titlel4} ${titlegreen}IPv6 地址变化${titleend}${markdown_linefeed}${markdown_tab}当前 IPv6:${IPv6}" + elif [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -ne "0" ] && [ -z "$IPv6" ]; then + echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】获取 IPv6 地址失败" >> ${logfile} + fi + + else + echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}路由器已经重启!" >> ${logfile} + [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -ne "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 当前IP: ${IPv4}" >> ${logfile} + [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -ne "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 当前IPv6: ${IPv6}" >> ${logfile} + echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $IPv6 >> ${dir}ip + title="路由器重新启动" + content="${content}${markdown_splitline}${titlel4} ${titlegreen}路由器重新启动${titleend}" + [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -ne "0" ] && content="${content}${markdown_linefeed}${markdown_tab}当前IP:${IPv4}" + [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -ne "0" ] && content="${content}${markdown_linefeed}${markdown_tab}当前IPv6:${IPv6}" + fi + + if [ ! -z "$content" ] ;then + [ -z "$ddns_enabled" ] && ddns_enabled=$(uci show ddns|grep "enabled"|grep "1") + [ -z "$ddns_enabled" ] && ddns_logrow=0 || ddns_logrow=$(echo "$ddns_enabled"|wc -l) + if [ $ddns_logrow -ge 1 ]; then + /etc/init.d/ddns stop >/dev/null 2>&1 + sleep 10 + /etc/init.d/ddns start >/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_interface=`getinterface ${ip_mac}` + getping ${1} ${up_timeout} "1";local ping_online=$? + if [ "$ping_online" -eq "0" ]; then + LockFile lock + [ -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 + else + usage down $1 + local ip_name=`getname ${1} ${ip_mac}` + blackwhitelist ${ip_mac};local ip_blackwhite=$? + echo "$1 ${ip_mac} ${ip_name} `date +%s` ${ip_interface}" >> ${dir}ipAddress + [ -f "${dir}send_enable.lock" ] || [ -z "$pushbot_up" ] || [ -z "$ip_blackwhite" ] && LockFile unlock && return + [ ! -z "$pushbot_up" ] && [ "$pushbot_up" -ne "1" ] && 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="${markdown_splitline}${titlel4} ${titlegreen}新设备连接${titleend}${markdown_linefeed}${markdown_tab}客户端名:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_name}${markdown_linefeed}${markdown_tab}客户端IP: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${1}${markdown_linefeed}${markdown_tab}客户端MAC:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_mac}${markdown_linefeed}${markdown_tab}网络接口:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_interface}" + elif ( echo ${title}|grep -q "连接了你的路由器" ); then + local title="${ip_name} ${title}" + local content="${markdown_splitline}${markdown_tab}客户端名:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_name}${markdown_linefeed}${markdown_tab}客户端IP: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${1}${markdown_linefeed}${markdown_tab}客户端MAC:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_mac}${markdown_linefeed}${markdown_tab}网络接口:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_interface}" + else + local title="设备状态变化" + local content="${markdown_splitline}${titlel4} ${titlegreen}新设备连接${titleend}${markdown_linefeed}${markdown_tab}客户端名:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_name}${markdown_linefeed}${markdown_tab}客户端IP: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${1}${markdown_linefeed}${markdown_tab}客户端MAC:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_mac}${markdown_linefeed}${markdown_tab}网络接口:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_interface}" + fi + echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}新设备 ${ip_name} ${1} 连接了">> ${logfile} + #[ ! -z "$pushbot_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}` + getping ${1} ${down_timeout} ${timeout_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 + LockFile unlock + else + local tmp_name=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $3}'|grep -v "^$"|sort -u|head -n1` + if [ "$ip_name" != "$tmp_name" ]; then + LockFile lock + local tmp_str=$(echo "$1 ${ip_mac} ${ip_name} `cat ${dir}ipAddress|grep -w ${1}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1` ${ip_interface}") + sed -i "/^${1} /d" ${dir}ipAddress + echo "$tmp_str" >> ${dir}ipAddress + LockFile unlock + fi + 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 "$pushbot_down" ] || [ -z "$ip_blackwhite" ] && continue + [ ! -z "$pushbot_down" ] && [ "$pushbot_down" -ne "1" ] && continue + [ ! -z "$ip_blackwhite" ] && [ "$ip_blackwhite" -ne "0" ] && 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="${markdown_linefeed}${markdown_tab}总计流量: ${markdown_space}${markdown_space}${markdown_space}${markdown_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}${markdown_splitline}${titlel4} ${titlered}设备断开连接${titleend}${markdown_linefeed}${markdown_tab}客户端名:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_name}${markdown_linefeed}${markdown_tab}客户端IP: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip}${markdown_linefeed}${markdown_tab}客户端MAC:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_mac}$ip_total${markdown_linefeed}${markdown_tab}在线时间: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${time1}" + elif ( echo "$title"|grep -q "断开连接" ); then + title="${ip_name} ${title}" + content="${content}${markdown_splitline}${markdown_tab}客户端名:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_name}${markdown_linefeed}${markdown_tab}客户端IP: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip}${markdown_linefeed}${markdown_tab}客户端MAC:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_mac}$ip_total${markdown_linefeed}${markdown_tab}在线时间: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${time1}" + else + title="设备状态变化" + content="${content}${markdown_splitline}${titlel4} ${titlered}设备断开连接${titleend}${markdown_linefeed}${markdown_tab}客户端名:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_name}${markdown_linefeed}${markdown_tab}客户端IP: ${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip}${markdown_linefeed}${markdown_tab}客户端MAC:${markdown_space}${markdown_space}${markdown_space}${markdown_space}${ip_mac}$ip_total${markdown_linefeed}${markdown_tab}在线时间: ${markdown_space}${markdown_space}${markdown_space}${markdown_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(){ + [ -f ${dir}ipAddress ] && local logrow=$(grep -c "" ${dir}ipAddress) || local logrow="0";[ $logrow -eq "0" ] && return + [ -f ${dir}usage.db ] && local ip_total_db="总计流量" + content="${content}${markdown_splitline}${titlel4} ${titlebold}${titleblue}现有在线设备 ${logrow} 台,具体如下${titleend}${titleboldend}${markdown_linefeed}${markdown_tab}IP 地址${markdown_tab}${tabletab}${ip_total_db}${tabletab}${boldstar}客户端名${boldstar}" + 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}" + 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}" + done + fi + content="${content}${markdown_linefeed}${markdown_tab}${ip}${tabletab}${ip_total}${tabletab}${boldstar}${greenfont}${ip_name}${fontend}${boldstar}" + unset i n ip_total ip_mac ip_name + done +} + +# 检测 cpu 状态 +function cpu_load(){ + if [ ! -z "$temperature_enable" ] && [ "$temperature_enable" -eq "1" ] && [ ! -z "$temperature" ]; then + [ -z "$temperature_time" ] && temperature_time=`date +%s` + local cpu_wendu=`soc_temp`; + [ -z "$cpu_wendu" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】无法读取设备温度,请检查命令" >> ${logfile} + + if [ "$cpu_wendu" -gt "$temperature" ]; then + echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!警报!!】 CPU 温度过高: ${cpu_wendu}" >> ${logfile} + else + temperature_time=`date +%s` + fi + + if [ "$((`date +%s`-$temperature_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_wendu}" >> ${logfile} + content="${content}${markdown_splitline}${titlel4} ${titlered}CPU 温度过高${titleend}${markdown_linefeed}${markdown_tab}CPU 温度已连续五分钟超过预设${markdown_linefeed}${markdown_tab}接下来一小时不再提示${markdown_linefeed}${markdown_tab}当前温度:${cpu_wendu}" + elif [ ! -z "$temperaturecd_time" ] && [ "$((`date +%s`-$temperaturecd_time))" -ge "3300" ] ;then + unset temperaturecd_time + fi + fi + + if [ ! -z "$cpuload_enable" ] && [ "$cpuload_enable" -eq "1" ] && [ ! -z "$cpuload" ]; then + [ -z "$cpuload_time" ] && cpuload_time=`date +%s` + local cpu_fuzai=`cat /proc/loadavg|awk '{print $1}'` 2>/dev/null + [ -z "$cpu_fuzai" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】无法读取设备负载,请检查命令" >> ${logfile} + + if [ `expr $cpu_fuzai \> $cpuload` -eq "1" ]; then + echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!警报!!】 CPU 负载过高: ${cpu_fuzai}" >> ${logfile} + cputop log + else + cpuload_time=`date +%s` + fi + + if [ "$((`date +%s`-$cpuload_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}${markdown_splitline}${titlel4} ${titlered}CPU 负载过高${titleend}${markdown_linefeed}${markdown_tab}CPU 负载已连续五分钟超过预设${markdown_linefeed}${markdown_tab}接下来一小时不再提示${markdown_linefeed}${markdown_tab}当前负载:${cpu_fuzai}" + cputop + elif [ ! -z "$cpucd_time" ] && [ "$((`date +%s`-$cpucd_time))" -ge "3300" ] ;then + unset cpucd_time + fi + fi +} + +function cputop(){ + [ -z "$1" ] && content="${content}${markdown_splitline}${titlel4} 当前 CPU 占用前三的进程" + local i=1 && local top_i=5 && `top -bn 1 > ${dir}top` >/dev/null 2>&1 + while [ $i -le 3 ]; do + if ( ! cat ${dir}top|awk 'NR=='${top_i}|grep -q "top -bn 1" ); then + local top_name=`cat ${dir}top|awk 'NR=='${top_i}|awk '{print $8}'`;[ "$top_name" == "/bin/sh" ] || [ "$top_name" == "/bin/bash" ] && local top_name=`cat ${dir}top|awk 'NR=='${top_i}|awk '{print $9}'` + local top_load=`cat ${dir}top|awk 'NR=='${top_i}|awk '{print $7}'` + local temp_top="${top_name} ${top_load}" + [ ! -z "$1" ] && local logtop="$logtop $temp_top" + [ -z "$1" ] && content="${content}${markdown_linefeed}${markdown_tab}${temp_top}" + local i=`expr ${i} + 1` + fi + local top_i=`expr ${top_i} + 1` + done + [ ! -z "$1" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!警报!!】 CPU 占用前三: ${logtop}" >> ${logfile} + rm -f ${dir}top >/dev/null 2>&1 +} + +# 发送定时数据 +function send(){ + echo "`date "+%Y-%m-%d %H:%M:%S"` 【定时数据】创建定时任务" >> ${logfile} + pushbot_disturb;local send_disturb=$? + get_config "send_title" "router_status" "client_list" "router_temp" "router_wan" + + [ -z "$send_title" ] && local send_title="路由状态:" + [ ! -z "$client_list" ] && [ "$client_list" -eq "1" ] && > ${dir}send_enable.lock && pushbot_first & + + if [ ! -z "$router_status" ] && [ "$router_status" -eq "1" ]; then + local systemload=`cat /proc/loadavg|awk '{print $1" "$2" "$3}'` + local cpuload=`getcpu` + local ramload=`free -m|sed -n '2p'|awk '{printf "%.2f%%\n",($3/$2)*100}'` + local systemstatustime=`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)}'`;unset run_days run_hour run_minute run_second + local send_content="${send_content}${markdown_splitline}${titlel4} ${titlebold}${titleblue}系统运行状态${titleend}${titleboldend}" + local send_content="${send_content}${markdown_linefeed}${markdown_tab}平均负载:${systemload}" + local send_content="${send_content}${markdown_linefeed}${markdown_tab}CPU占用:${cpuload}${percentsym}" + local send_content="${send_content}${markdown_linefeed}${markdown_tab}内存占用:${ramload}${percentsym}" + local send_content="${send_content}${markdown_linefeed}${markdown_tab}${systemstatustime}" + fi + + [ ! -z "$router_temp" ] && [ "$router_temp" -eq "1" ] && local cputemp=`soc_temp` && local send_content="${send_content}${markdown_splitline}${titlel4} ${titlebold}${titleblue}设备温度${titleend}${titleboldend}${markdown_linefeed}${markdown_tab}CPU:${cputemp}℃" #%e2%84%83="℃" + + if [ ! -z "$router_wan" ] && [ "$router_wan" -eq "1" ]; then + local send_wanIP=`getip wanipv4`;local send_hostIP=`getip hostipv4` + local send_content="${send_content}${markdown_splitline}${titlel4} ${titlebold}${titleblue}WAN 口信息${titleend}${titleboldend}${markdown_linefeed}${markdown_tab}接口ip:${send_wanIP}" + local send_content="${send_content}${markdown_linefeed}${markdown_tab}外网ip:${send_hostIP}" + if [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -ne "0" ]; then + local send_wanIPv6=`getip wanipv6`;local send_hostIPv6=`getip hostipv6` + local send_content="${send_content}${markdown_linefeed}${markdown_tab}ipv6 :${send_wanIPv6}" + local send_content="${send_content}${markdown_linefeed}${markdown_tab}外网v6:${send_hostIPv6}" + fi + ( ! echo "$send_wanIP"|grep -q -w ${send_hostIP} ) && local send_content="${send_content}${markdown_linefeed}${markdown_tab}外网 ip 与接口 ip 不一致,你的 ip 不是公网 ip" + local interfaceuptime=`getinterfaceuptime` + [ ! -z "$interfaceuptime" ] && local wanstatustime=`getinterfaceuptime|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)}'` && unset run_days run_hour run_minute run_second + local send_content="${send_content}${markdown_linefeed}${markdown_tab}${wanstatustime}" + fi + + if [ ! -z "$client_list" ] && [ "$client_list" -eq "1" ]; then + wait + local IPLIST=`cat ${dir}ipAddress 2>/dev/null|awk '{print $1}'` + [ -z "$IPLIST" ] && local send_content="${send_content}${markdown_splitline}${titlel4} ${titlebold}${titlered}当前无在线设备${titleend}${titleboldend}" || local send_content="${send_content}${markdown_splitline}${titlel4} ${titlebold}${titleblue}在线设备${titleend}${titleboldend}" + for ip in $IPLIST; do + local time_up=`cat ${dir}ipAddress|grep -w ${ip}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1` + local time1=`date +%s` + local time1=$(time_for_humans `expr ${time1} - ${time_up}`) + local ip_mac=`getmac ${ip}` + local ip_name=`getname ${ip} ${ip_mac}` + local ip_total=`usage get ${ip_mac}`;[ ! -z "$ip_total" ] && local ip_total="总计流量:${ip_total} " + local ip_name=`cut_str $ip_name 18` + local send_content="${send_content}${markdown_linefeed}${markdown_tab}${greenfont}【${ip_name}】${fontend} ${ip}${markdown_linefeed}${markdown_tab}${ip_total}在线 ${time1}" + unset ip_total time_down time_up time1 ip_mac ip_name + done + fi + [ ! -z "$device_name" ] && local send_title="【$device_name】${send_title}" + local send_title=`echo "$send_title"|sed $'s/\ / /g'|sed $'s/\"/%22/g'|sed $'s/\#/%23/g'|sed $'s/\&/%26/g'|sed $'s/\,/%2C/g'|sed $'s/\//%2F/g'|sed $'s/\:/%3A/g'|sed $'s/\;/%3B/g'|sed $'s/\=/%3D/g'|sed $'s/\@/%40/g'` + [ -z "$send_content" ] && local send_content="${markdown_splitline}${titlel4} ${titlered}我遇到了一个难题${titleend}${markdown_linefeed}${markdown_tab}定时发送选项错误,你没有选择需要发送的项目,该怎么办呢${markdown_splitline}" + local nowtime=`date "+%Y-%m-%d %H:%M:%S"` + pushbot_send="curl -s \"https://oapi.dingtalk.com/robot/send?access_token=${dd_webhook}\" -H 'Content-Type: application/json' -d '{\"msgtype\": \"markdown\",\"markdown\": {\"title\":\"${send_title}\",\"text\":\"${titlel4} ${send_title}${markdown_linefeed}${nowtime}${markdown_linefeed}${send_content}\"}}'" + wechatent_send="curl -s \"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${we_webhook}\" -H 'Content-Type: application/json' -d '{\"msgtype\": \"markdown\",\"markdown\": {\"title\":\"${send_title}\",\"content\":\"${titlel4} ${send_title}${markdown_linefeed}${nowtime}${markdown_linefeed}${send_content}\"}}'" + feishu_send="curl -X POST https://open.feishu.cn/open-apis/bot/v2/hook/${fs_webhook} -H 'Content-Type: application/json' -d '{\"msg_type\": \"post\",\"content\": {\"post\": {\"zh_cn\": {\"title\": \"${send_title}\",\"content\": [[{\"tag\": \"text\",\"text\": \"${nowtime}${markdown_linefeed}${send_content}\"}]]}}}}'" + [ "$send_disturb" -eq "0" ] && [ -z "$send_we" ] && eval $pushbot_send >/dev/null 2>&1 + [ "$send_disturb" -eq "0" ] && [ ! -z "$send_we" ] && [ "$send_we" -eq "1" ] && eval $wechatent_send >/dev/null 2>&1 + [ "$send_disturb" -eq "0" ] && [ ! -z "$send_we" ] && [ "$send_we" -eq "2" ] && curl -s "http://pushplus.plus/send?token=${pp_token}" -d "&channel=${pp_channel}&webhook=${pp_webhook}&topic=${pp_topic}&title=${send_title}&content=${nowtime}${markdown_linefeed}${send_content}&template=markdown" >/dev/null 2>&1 + [ "$send_disturb" -eq "0" ] && [ ! -z "$send_we" ] && [ "$send_we" -eq "3" ] && eval $feishu_send >/dev/null 2>&1 + [ "$send_disturb" -eq "0" ] && [ ! -z "$send_we" ] && [ "$send_we" -eq "4" ] && curl -s "${bark_srv}/${bark_token}/${send_title}/${nowtime}${markdown_linefeed}${send_content}?isArchive=1" >/dev/null 2>&1 + deltemp + echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}定时推送任务完成" >> ${logfile} +} + +# 初始化 +read_config +deltemp +pushbot_cron + +# 限制并发进程 +[ -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 + +# 启动参数 +if [ "$1" ] ;then + [ $1 == "send" ] && send + [ $1 == "soc" ] && echo `soc_temp` > ${dir}soc_tmp + [ $1 == "client" ] && get_client + exit +fi + +# 载入在线设备 +pushbot_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 && pushbot_first && deltemp +echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】初始化完成" >> ${logfile} + +# 循环 +while [ "$pushbot_enable" -eq "1" ]; do + deltemp + usage update + pushbot_disturb;disturb=$? + + # 外网IP变化检测 + if [ ! -z "$pushbot_ipv4" ] && [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv4" -ne "0" ] || [ "$pushbot_ipv6" -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 + pushbot_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" ] && [ -z "$content_current_device" ] || [ "$content_current_device" -eq "0" ] && current_device + + # 无人值守任务 + [ ! -f "${dir}send_enable.lock" ] && unattended + + # CPU 检测 + [ ! -f "${dir}send_enable.lock" ] && cpu_load + + # 异常流量检测 + [ ! -f "${dir}send_enable.lock" ] && get_client_usage + + if [ ! -f "${dir}send_enable.lock" ] && [ ! -z "$title" ] && [ ! -z "$content" ]; then + [ -z "$content_nowtime" ] || [ "$content_nowtime" -eq "0" ] && nowtime=`date "+%Y-%m-%d %H:%M:%S"` + [ ! -z "$device_name" ] && title="【$device_name】$title" + title=`echo "$title"|sed $'s/\ / /g'|sed $'s/\"/%22/g'|sed $'s/\#/%23/g'|sed $'s/\&/%26/g'|sed $'s/\,/%2C/g'|sed $'s/\//%2F/g'|sed $'s/\:/%3A/g'|sed $'s/\;/%3B/g'|sed $'s/\=/%3D/g'|sed $'s/\@/%40/g'` + [ ! -z "$content_content" ] && [ "$content_content" -eq "1" ] && content="" + pushbot_send="curl -s \"https://oapi.dingtalk.com/robot/send?access_token=${dd_webhook}\" -H 'Content-Type: application/json' -d '{\"msgtype\": \"markdown\",\"markdown\": {\"title\":\"${title}\",\"text\":\"${titlel4} ${titlebold}${title}${titleboldend}${markdown_linefeed}${nowtime}${markdown_linefeed}${content}${markdown_linefeed}${titlebold}${title}${titleboldend}\"}}'" + wechatent_send="curl -s \"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${we_webhook}\" -H 'Content-Type: application/json' -d '{\"msgtype\": \"markdown\",\"markdown\": {\"title\":\"${title}\",\"content\":\"${titlel4} ${titlebold}${title}${titleboldend}${markdown_linefeed}${nowtime}${markdown_linefeed}${content}${markdown_linefeed}${titlebold}${title}${titleboldend}\"}}'" + feishu_send="curl -X POST https://open.feishu.cn/open-apis/bot/v2/hook/${fs_webhook} -H 'Content-Type: application/json' -d '{\"msg_type\": \"post\",\"content\": {\"post\": {\"zh_cn\": {\"title\": \"${title}\",\"content\": [[{\"tag\": \"text\",\"text\": \"${nowtime}${markdown_linefeed}${content}\"}]]}}}}'" + [ "$disturb" -eq "0" ] && [ -z "$send_we" ] && eval $pushbot_send >/dev/null 2>&1 + [ "$disturb" -eq "0" ] && [ ! -z "$send_we" ] && [ "$send_we" -eq "1" ] && eval $wechatent_send >/dev/null 2>&1 + [ "$disturb" -eq "0" ] && [ ! -z "$send_we" ] && [ "$send_we" -eq "2" ] && curl -s "http://pushplus.plus/send?token=${pp_token}" -d "&channel=${pp_channel}&webhook=${pp_webhook}&topic=${pp_topic}&title=${title}&content=${nowtime}${markdown_linefeed}${content}&template=markdown" >/dev/null 2>&1 + [ "$disturb" -eq "0" ] && [ ! -z "$send_we" ] && [ "$send_we" -eq "3" ] && eval $feishu_send 2>&1 + [ "$disturb" -eq "0" ] && [ ! -z "$send_we" ] && [ "$send_we" -eq "4" ] && curl -s "${bark_srv}/${bark_token}/${title}/${nowtime}${markdown_linefeed}${content}?isArchive=1" >/dev/null 2>&1 + fi + + while [ -f "${dir}send_enable.lock" ]; do + sleep $sleeptime + done + sleep $sleeptime +done diff --git a/package/lean/luci-app-pushbot/root/usr/share/rpcd/acl.d/luci-app-pushbot.json b/package/lean/luci-app-pushbot/root/usr/share/rpcd/acl.d/luci-app-pushbot.json new file mode 100644 index 000000000..d33e80946 --- /dev/null +++ b/package/lean/luci-app-pushbot/root/usr/share/rpcd/acl.d/luci-app-pushbot.json @@ -0,0 +1,11 @@ +{ + "luci-app-pushbot": { + "description": "Grant UCI access for luci-app-pushbot", + "read": { + "uci": [ "pushbot" ] + }, + "write": { + "uci": [ "pushbot" ] + } + } +}