├── .github └── workflows │ └── build-package-onx86.yml ├── Makefile ├── README.md ├── luasrc ├── controller │ └── pushbot.lua ├── model │ └── cbi │ │ └── pushbot │ │ ├── advanced.lua │ │ ├── client.lua │ │ ├── log.lua │ │ └── setting.lua └── view │ └── pushbot │ ├── pushbot_log.htm │ └── pushbot_status.htm └── root ├── etc ├── config │ └── pushbot ├── init.d │ └── pushbot └── uci-defaults │ └── luci-pushbot └── usr ├── bin └── pushbot │ ├── api │ ├── bark.json │ ├── dingding.json │ ├── diy.json │ ├── ent_wechat.json │ ├── feishu.json │ ├── ip_blacklist │ ├── ipv4.list │ ├── ipv6.list │ ├── pushdeer.json │ └── pushplus.json │ └── pushbot └── share └── rpcd └── acl.d └── luci-app-pushbot.json /.github/workflows/build-package-onx86.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019-2020 P3TERX 3 | # 4 | # This is free software, licensed under the MIT License. 5 | # See /LICENSE for more information. 6 | # 7 | # https://github.com/P3TERX/Actions-OpenWrt 8 | # Description: Build OpenWrt using GitHub Actions 9 | # 10 | 11 | name: Build luci-app-pushbot-x86 12 | 13 | on: 14 | repository_dispatch: 15 | workflow_dispatch: 16 | inputs: 17 | ssh: 18 | description: 'SSH connection to Actions' 19 | required: false 20 | default: 'false' 21 | # schedule: 22 | # - cron: 10 14 * * 5 23 | 24 | env: 25 | SDK_URL: https://downloads.openwrt.org/releases/22.03.0-rc5/targets/x86/64/openwrt-sdk-22.03.0-rc5-x86-64_gcc-11.2.0_musl.Linux-x86_64.tar.xz 26 | PackageName: luci-app-pushbot 27 | PackageSource_URL: https://github.com/zzsj0928/luci-app-pushbot 28 | UPLOAD_Package: true 29 | UPLOAD_COWTRANSFER: false 30 | UPLOAD_WETRANSFER: true 31 | UPLOAD_RELEASE: true 32 | TZ: Asia/Shanghai 33 | UPLOAD_ZZNAS: false 34 | ftp_username: ${{ secrets.FTP_USERNAME }} 35 | ftp_psw: ${{ secrets.FTP_PSW }} 36 | ftp_ip: ${{ secrets.FTP_IP }} 37 | TargetPath: OpenwrtImgs/packages/luci-app-pushbot 38 | upload_file: luci-app-pushbot_* 39 | whkey: ${{ secrets.WEBHOOK }} 40 | 41 | jobs: 42 | build: 43 | runs-on: ubuntu-latest 44 | 45 | steps: 46 | - name: Checkout 47 | uses: actions/checkout@main 48 | 49 | - name: Initialization environment 50 | env: 51 | DEBIAN_FRONTEND: noninteractive 52 | run: | 53 | sudo rm -rf /etc/apt/sources.list.d/* /usr/share/dotnet /usr/local/lib/android /opt/ghc 54 | sudo -E apt-get -qq update 55 | sudo -E apt-get -qq install $(curl -fsSL git.io/depends-ubuntu-2004) 56 | sudo -E apt-get -qq autoremove --purge 57 | sudo -E apt-get -qq clean 58 | sudo timedatectl set-timezone "$TZ" 59 | sudo mkdir -p /workdir 60 | sudo chown $USER:$GROUPS /workdir 61 | 62 | - name: Clone source code 63 | working-directory: /workdir 64 | run: | 65 | df -hT $PWD 66 | wget $SDK_URL 67 | mkdir /workdir/openwrt 68 | tar xf openwrt-sdk-* -C /workdir/openwrt --strip-components 1 69 | ln -sf /workdir/openwrt $GITHUB_WORKSPACE/openwrt 70 | 71 | - name: Update feeds 72 | run: cd openwrt && ./scripts/feeds update -a 73 | 74 | - name: Install feeds 75 | run: cd openwrt && ./scripts/feeds install -a 76 | 77 | - name: Load custom configuration 78 | run: | 79 | cd openwrt 80 | git clone $PackageSource_URL package/$PackageName 81 | make defconfig 82 | echo "CONFIG_PACKAGE_$PackageName=y" >> ./.config 83 | 84 | 85 | - name: SSH connection to Actions 86 | uses: P3TERX/ssh2actions@v1.0.0 87 | if: (github.event.inputs.ssh == 'true' && github.event.inputs.ssh != 'false') || contains(github.event.action, 'ssh') 88 | env: 89 | TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }} 90 | TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }} 91 | 92 | - name: Compile the package 93 | id: compile 94 | run: | 95 | send_dingding="curl -s \"https://oapi.dingtalk.com/robot/send?access_token=${whkey}\" -H 'Content-Type: application/json' -d '{\"msgtype\": \"markdown\",\"markdown\": {\"title\":" 96 | send_content0="【${PackageName}】正在启动编译!请稍后大约4小时..." 97 | markdown_splitline="\n\n---\n\n" 98 | GITHUB_WORKFLOW_URL=https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID 99 | nowtime=`date "+%Y-%m-%d %H:%M:%S"` 100 | eval "$send_dingding \"${send_content0}\",\"text\":\"${nowtime} $markdown_splitline #### ${send_content0}\n\n[点此链接查看](${GITHUB_WORKFLOW_URL})\"}}'" 101 | 102 | 103 | cd openwrt 104 | echo -e "$(nproc) thread compile" 105 | make package/$PackageName/compile V=s 106 | echo "::set-output name=status::success" 107 | 108 | - name: Check space usage 109 | if: (!cancelled()) 110 | run: df -hT 111 | 112 | - name: Organize files 113 | id: organize 114 | if: env.UPLOAD_Package == 'true' && !cancelled() 115 | run: | 116 | cd openwrt/bin/packages/*/base 117 | echo "PackagePath=$PWD" >> $GITHUB_ENV 118 | echo "::set-output name=status::success" 119 | 120 | - name: Upload package 121 | uses: actions/upload-artifact@main 122 | if: steps.organize.outputs.status == 'success' && !cancelled() 123 | with: 124 | name: ${{ env.upload_file }} 125 | path: ${{ env.PackagePath }} 126 | 127 | - name: Upload package to cowtransfer 128 | id: cowtransfer 129 | if: steps.organize.outputs.status == 'success' && env.UPLOAD_COWTRANSFER == 'true' && !cancelled() 130 | run: | 131 | curl -fsSL git.io/file-transfer | sh 132 | ./transfer cow --block 2621440 -s -p 64 --no-progress ${PackagePath}/${upload_file} 2>&1 | tee cowtransfer.log 133 | echo "::warning file=cowtransfer.com::$(cat cowtransfer.log | grep https)" 134 | echo "::set-output name=url::$(cat cowtransfer.log | grep https | cut -f3 -d" ")" 135 | 136 | - name: Upload firmware to WeTransfer 137 | id: wetransfer 138 | if: steps.organize.outputs.status == 'success' && env.UPLOAD_WETRANSFER == 'true' && !cancelled() 139 | run: | 140 | curl -fsSL git.io/file-transfer | sh 141 | ./transfer wet -s -p 16 --no-progress ${PackagePath}/${upload_file} 2>&1 | tee wetransfer.log 142 | echo "::warning file=wetransfer.com::$(cat wetransfer.log | grep https)" 143 | echo "::set-output name=url::$(cat wetransfer.log | grep https | cut -f3 -d" ")" 144 | 145 | - name: Upload firmware to my NAS 146 | id: zz-nas 147 | if: steps.organize.outputs.status == 'success' && env.UPLOAD_ZZNAS == 'true' && !cancelled() 148 | run: | 149 | send_dingding="curl -s \"https://oapi.dingtalk.com/robot/send?access_token=${whkey}\" -H 'Content-Type: application/json' -d '{\"msgtype\": \"markdown\",\"markdown\": {\"title\":" 150 | send_content1="【${PackageName}】编译成功!正在上传固件到NAS..." 151 | send_content2="【${PackageName}】编译成功!固件成功上传到NAS。" 152 | markdown_splitline="\n\n---\n\n" 153 | GITHUB_WORKFLOW_URL=https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID 154 | nowtime=`date "+%Y-%m-%d %H:%M:%S"` 155 | eval "$send_dingding \"${send_content1}\",\"text\":\"${nowtime} $markdown_splitline #### ${send_content1}\n\n[点此链接查看](${GITHUB_WORKFLOW_URL})\"}}'" 156 | 157 | cd openwrt/bin/packages/*/base 158 | echo $ftp_psw > /tmp/rsync.psw && chmod 600 /tmp/rsync.psw 159 | rsync -avrzP $upload_file_1 $ftp_username@$ftp_ip::$TargetPath/$(date +"%Y.%m.%d-%H%M")/ --password-file=/tmp/rsync.psw 160 | echo "::warning file=zz-nas.com::All Released Files Uploaded to ZZ-NAS" 161 | 162 | nowtime=`date "+%Y-%m-%d %H:%M:%S"` 163 | eval "$send_dingding \"${send_content2}\",\"text\":\"${nowtime} $markdown_splitline #### ${send_content2}\n\n[点此链接查看](${GITHUB_WORKFLOW_URL})\"}}'" 164 | 165 | - name: Generate release tag 166 | id: tag 167 | if: env.UPLOAD_RELEASE == 'true' && !cancelled() 168 | run: | 169 | echo "::set-output name=release_tag::$(date +"%Y.%m.%d-%H%M")" 170 | touch release.txt 171 | [ $UPLOAD_COWTRANSFER = true ] && echo "🔗 [Cowtransfer](${{ steps.cowtransfer.outputs.url }})" >> release.txt 172 | [ $UPLOAD_WETRANSFER = true ] && echo "🔗 [WeTransfer](${{ steps.wetransfer.outputs.url }})" >> release.txt 173 | echo "::set-output name=status::success" 174 | 175 | - name: Upload package to release 176 | uses: softprops/action-gh-release@v1 177 | if: steps.tag.outputs.status == 'success' && !cancelled() 178 | env: 179 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 180 | with: 181 | tag_name: ${{ steps.tag.outputs.release_tag }} 182 | body_path: release.txt 183 | files: ${{ env.PackagePath }}/${{ env.upload_file }} 184 | 185 | - name: Delete workflow runs 186 | uses: GitRML/delete-workflow-runs@main 187 | with: 188 | retain_days: 1 189 | keep_minimum_runs: 3 190 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include $(TOPDIR)/rules.mk 2 | 3 | PKG_NAME:=luci-app-pushbot 4 | PKG_VERSION:=3.60 5 | PKG_RELEASE:=1 6 | 7 | PKG_MAINTAINER:=tty228 zzsj0928 8 | 9 | LUCI_TITLE:=LuCI support for Pushbot 10 | LUCI_PKGARCH:=all 11 | LUCI_DEPENDS:=+iputils-arping +curl +jq 12 | 13 | define Package/$(PKG_NAME)/conffiles 14 | /etc/config/pushbot 15 | /usr/bin/pushbot/api/diy.json 16 | /usr/bin/pushbot/api/ipv4.list 17 | /usr/bin/pushbot/api/ipv6.list 18 | endef 19 | 20 | include $(TOPDIR)/feeds/luci/luci.mk 21 | 22 | # call BuildPackage - OpenWrt buildroot signature 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 改名公告 2 | #### 2021年04月25日 起luci-app-serverchand 改名为 luci-app-pushbot 3 | 4 | 如需拉取编译 5 | 请把: 6 | 7 | `# git clone https://github.com/zzsj0928/luci-app-serverchand package/luci-app-serverchand` 8 | 9 | 改为 10 | 11 | `git clone https://github.com/zzsj0928/luci-app-pushbot package/luci-app-pushbot` 12 | 13 | 并把 .config 中 14 | 15 | `CONFIG_PACKAGE_luci-app-serverchand=y` 16 | 17 | 改为 18 | 19 | `CONFIG_PACKAGE_luci-app-pushbot=y` 20 | 21 | 注意:本次改名需要提前备份serverchand配置,并于PushBot中重新配置。 22 | 23 | 再次谢谢各位支持 24 | 25 | # 申明 26 | - 本插件由[tty228/luci-app-serverchan](https://github.com/tty228/luci-app-serverchan)原创. 27 | - 因微信推送存在诸多弊端(无法分开聊天工具与功能性消息推送,通知内不显示内容,内容需要点开才能查看等), 28 | - 故由 然后七年 @zzsj0928 重新修改为本插件,为钉钉机器人API使用。 29 | - 本插件工作在:openwrt 30 | - 本插件支持:钉钉推送,企业微信推送,PushPlus推送,微信推送,企业微信应用推送,飞书推送,钉钉机器人推送,企业微信机器人推送,飞书机器人推送,一对多推送,Bark推送(仅iOS),PushDeer,PushDeer自架 31 | - 自20210911之后的版本,支持Bark群组,群组名默认为设备名 32 | - 自20210901之后的版本,增加依赖jq,请重新编译或在安装前同步安装jq 33 | 34 | # 显示效果 35 | ## 通知栏:直接显示推送主题,一目了然,按设备不同,分组显示 36 | 37 | 38 | ## 消息列表:直接显示最新推送的标题 39 | 40 | 41 | ## 消息内容:直接显示所有推送信息,不用二次点开再查看 42 | 43 | 44 | # 下载 45 | - [luci-app-pushbot](https://github.com/zzsj0928/luci-app-pushbot/releases) 46 | 47 | 48 | ----------------------------------------------------- 49 | ##################################################### 50 | ----------------------------------------------------- 51 | 52 | # 以下为原插件简介: 53 | 54 | # 简介 55 | - 用于 OpenWRT/LEDE 路由器上进行 Server酱 微信/Telegram 推送的插件 56 | - 基于 serverchan 提供的接口发送信息,Server酱说明:http://sc.ftqq.com/1.version 57 | - **基于斐讯 k3 制作,不同系统不同设备,请自行修改部分代码,无测试条件无法重现的 bug 不考虑修复** 58 | - 依赖 iputils-arping + curl 命令,安装前请 `opkg update`,小内存路由谨慎安装 59 | - 使用主动探测设备连接的方式检测设备在线状态,以避免WiFi休眠机制,主动探测较为耗时,**如遇设备休眠频繁,请自行调整超时设置** 60 | - 流量统计功能依赖 wrtbwmon ,自行选装或编译,该插件与 Routing/NAT 、Flow Offloading 冲突,开启无法获取流量,自行选择,L大版本直接编译 luci-app-wrtbwmon 61 | 62 | #### 主要功能 63 | - 路由 ip/ipv6 变动推送 64 | - 设备别名 65 | - 设备上线推送 66 | - 设备离线推送及流量使用情况 67 | - CPU 负载、温度监视 68 | - 定时推送设备运行状态 69 | - MAC 白名单、黑名单、按接口检测设备 70 | - 免打扰 71 | - 无人值守任务 72 | 73 | #### 说明 74 | - 潘多拉系统、或不支持 sh 的系统,请将脚本开头 `#!/bin/sh` 改为 `#!/bin/bash`,或手动安装 `sh` 75 | - 追新是没有意义的,没有问题没必要更新,上班事情忙完了,摸鱼又不会摸,只能靠写几行 bug ,才能缓解无聊这样子 76 | 77 | #### 已知问题 78 | - 直接关闭接口时,该接口的离线设备会忽略检测 79 | - 部分设备无法读取到设备名,脚本使用 `cat /var/dhcp.leases` 命令读取设备名,如果 dhcp 中不存在设备名,则无法读取设备名(如二级路由设备、静态ip设备),请使用设备名备注 80 | 81 | # Download 82 | - [luci-app-serverchan](https://github.com/tty228/luci-app-serverchan/releases) 83 | - [wrtbwmon](https://github.com/brvphoenix/wrtbwmon) 84 | - [luci-app-wrtbwmon](https://github.com/brvphoenix/luci-app-wrtbwmon) 85 | 86 | #### ps 87 | - 新功能看情况开发 88 | - 王者荣耀新赛季,不思进取中 89 | - 欢迎各种代码提交 90 | - 提交bug时请尽量带上设备信息,日志与描述(如执行`/usr/bin/serverchan/serverchan`后的提示、日志信息、/tmp/serverchan/ipAddress 文件信息) 91 | - 三言两句恕我无能为力 92 | - 武汉加油 93 | 94 | -------------------------------------------------------------------------------- /luasrc/controller/pushbot.lua: -------------------------------------------------------------------------------- 1 | module("luci.controller.pushbot",package.seeall) 2 | 3 | function index() 4 | if not nixio.fs.access("/etc/config/pushbot") then 5 | return 6 | end 7 | 8 | entry({"admin", "services", "pushbot"}, alias("admin", "services", "pushbot", "setting"),_("全能推送"), 30).dependent = true 9 | entry({"admin", "services", "pushbot", "setting"}, cbi("pushbot/setting"),_("配置"), 40).leaf = true 10 | entry({"admin", "services", "pushbot", "advanced"}, cbi("pushbot/advanced"),_("高级设置"), 50).leaf = true 11 | entry({"admin", "services", "pushbot", "client"}, form("pushbot/client"), "在线设备", 80) 12 | entry({"admin", "services", "pushbot", "log"}, form("pushbot/log"),_("日志"), 99).leaf = true 13 | entry({"admin", "services", "pushbot", "get_log"}, call("get_log")).leaf = true 14 | entry({"admin", "services", "pushbot", "clear_log"}, call("clear_log")).leaf = true 15 | entry({"admin", "services", "pushbot", "status"}, call("act_status")).leaf = true 16 | end 17 | 18 | function act_status() 19 | local e={} 20 | e.running=luci.sys.call("busybox ps|grep -v grep|grep -c pushbot >/dev/null")==0 21 | luci.http.prepare_content("application/json") 22 | luci.http.write_json(e) 23 | end 24 | 25 | function get_log() 26 | luci.http.write(luci.sys.exec( 27 | "[ -f '/tmp/pushbot/pushbot.log' ] && cat /tmp/pushbot/pushbot.log")) 28 | end 29 | 30 | function clear_log() 31 | luci.sys.call("echo '' > /tmp/pushbot/pushbot.log") 32 | end 33 | -------------------------------------------------------------------------------- /luasrc/model/cbi/pushbot/advanced.lua: -------------------------------------------------------------------------------- 1 | local nt = require "luci.sys".net 2 | local fs=require"nixio.fs" 3 | 4 | m=Map("pushbot",translate("提示"), 5 | translate("如果你不了解这些选项的含义,请不要修改这些选项。")) 6 | 7 | s = m:section(TypedSection, "pushbot", "高级设置") 8 | s.anonymous = true 9 | s.addremove = false 10 | 11 | a=s:option(Value,"up_timeout",translate('设备上线检测超时(s)')) 12 | a.default = "2" 13 | a.optional=false 14 | a.datatype="uinteger" 15 | 16 | a=s:option(Value,"down_timeout",translate('设备离线检测超时(s)')) 17 | a.default = "20" 18 | a.optional=false 19 | a.datatype="uinteger" 20 | 21 | a=s:option(Value,"timeout_retry_count",translate('离线检测次数')) 22 | a.default = "2" 23 | a.optional=false 24 | a.datatype="uinteger" 25 | a.description = translate("若无二级路由设备,信号强度良好,可以减少以上数值
因夜间 wifi 休眠较为玄学,遇到设备频繁推送断开,烦请自行调整参数
..╮(╯_╰)╭..") 26 | 27 | a=s:option(Value,"thread_num",translate('最大并发进程数')) 28 | a.default = "3" 29 | a.datatype="uinteger" 30 | 31 | a=s:option(Value, "soc_code", "自定义温度读取命令") 32 | a.rmempty = true 33 | a:value("",translate("默认")) 34 | a:value("pve",translate("PVE 虚拟机")) 35 | a.description = translate("请尽量避免使用特殊符号,如双引号、$、!等,执行结果需为数字,用于温度对比") 36 | 37 | a=s:option(Value,"pve_host",translate("宿主机地址")) 38 | a.rmempty=true 39 | a.default="10.0.0.2" 40 | a.description = translate("请确认已经设置好密钥登陆,否则会引起脚本无法运行等错误!
PVE 安装 sensors 命令自行百度
密钥登陆例:
opkg update #更新列表
opkg install openssh-client openssh-keygen #安装openssh客户端
ssh-keygen -t rsa # 生成密钥文件(自行设定密码等信息)
ssh root@10.0.0.2 \"tee -a ~/.ssh/id_rsa.pub\" < ~/.ssh/id_rsa.pub # 传送公钥到 PVE
ssh root@10.0.0.2 \"cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys\" # 写入公钥到 PVE
ssh -i ~/.ssh/id_rsa root@10.0.0.2 sensors # 测试温度命令") 41 | a:depends({soc_code="pve"}) 42 | 43 | a=s:option(Value,"pve_port",translate("SSH端口")) 44 | a.rmempty=true 45 | a.default="22" 46 | a.description = translate("默认为22,如有自定义,请填写自定义SSH端口") 47 | a:depends({soc_code="pve"}) 48 | 49 | a=s:option(Button,"soc",translate("测试温度命令")) 50 | a.inputtitle = translate("输出信息") 51 | a.write = function() 52 | luci.sys.call("/usr/bin/pushbot/pushbot soc") 53 | luci.http.redirect(luci.dispatcher.build_url("admin","services","pushbot","advanced")) 54 | end 55 | 56 | if nixio.fs.access("/tmp/pushbot/soc_tmp") then 57 | e=s:option(TextValue,"soc_tmp") 58 | e.rows=2 59 | e.readonly=true 60 | e.cfgvalue = function() 61 | return luci.sys.exec("cat /tmp/pushbot/soc_tmp && rm -f /tmp/pushbot/soc_tmp") 62 | end 63 | end 64 | 65 | a=s:option(Flag,"err_enable",translate("无人值守任务")) 66 | a.default=0 67 | a.rmempty=true 68 | a.description = translate("请确认脚本可以正常运行,否则可能造成频繁重启等错误!") 69 | 70 | a=s:option(Flag,"err_sheep_enable",translate("仅在免打扰时段重拨")) 71 | a.default=0 72 | a.rmempty=true 73 | a.description = translate("避免白天重拨 ddns 域名等待解析,此功能不影响断网检测
因夜间跑流量问题,该功能可能不稳定") 74 | a:depends({err_enable="1"}) 75 | 76 | a= s:option(DynamicList, "err_device_aliases", translate("关注列表")) 77 | a.rmempty = true 78 | a.description = translate("只会在列表中设备都不在线时才会执行
免打扰时段一小时后,关注设备五分钟低流量(约100kb/m)将视为离线") 79 | nt.mac_hints(function(mac, name) a :value(mac, "%s (%s)" %{ mac, name }) end) 80 | a:depends({err_enable="1"}) 81 | 82 | a=s:option(ListValue,"network_err_event",translate("网络断开时")) 83 | a.default="" 84 | a:depends({err_enable="1"}) 85 | a:value("",translate("无操作")) 86 | a:value("1",translate("重启路由器")) 87 | a:value("2",translate("重新拨号")) 88 | a:value("3",translate("修改相关设置项,尝试自动修复网络")) 89 | a.description = translate("选项 1 选项 2 不会修改设置,并最多尝试 2 次。
选项 3 会将设置项备份于 /usr/bin/pushbot/configbak 目录,并在失败后还原。
【!!无法保证兼容性!!】不熟悉系统设置项,不会救砖请勿使用") 90 | 91 | a=s:option(ListValue,"system_time_event",translate("定时重启")) 92 | a.default="" 93 | a:depends({err_enable="1"}) 94 | a:value("",translate("无操作")) 95 | a:value("1",translate("重启路由器")) 96 | a:value("2",translate("重新拨号")) 97 | 98 | a= s:option(Value, "autoreboot_time", "系统运行时间大于") 99 | a.rmempty = true 100 | a.default = "24" 101 | a.datatype="uinteger" 102 | a:depends({system_time_event="1"}) 103 | a.description = translate("单位为小时") 104 | 105 | a=s:option(Value, "network_restart_time", "网络在线时间大于") 106 | a.rmempty = true 107 | a.default = "24" 108 | a.datatype="uinteger" 109 | a:depends({system_time_event="2"}) 110 | a.description = translate("单位为小时") 111 | 112 | a=s:option(Flag,"public_ip_event",translate("重拨尝试获取公网 ip")) 113 | a.default=0 114 | a.rmempty=true 115 | a:depends({err_enable="1"}) 116 | a.description = translate("重拨时不会推送 ip 变动通知,并会导致你的域名无法及时更新 ip 地址
请确认你可以通过重拨获取公网 ip,否则这不仅徒劳无功还会引起频繁断网
移动等大内网你就别挣扎了!!") 117 | 118 | a= s:option(Value, "public_ip_retry_count", "当天最大重试次数") 119 | a.rmempty = true 120 | a.default = "10" 121 | a.datatype="uinteger" 122 | a:depends({public_ip_event="1"}) 123 | 124 | return m 125 | -------------------------------------------------------------------------------- /luasrc/model/cbi/pushbot/client.lua: -------------------------------------------------------------------------------- 1 | f = SimpleForm("pushbot") 2 | luci.sys.call("/usr/bin/pushbot/pushbot client") 3 | f.reset = false 4 | f.submit = false 5 | f:append(Template("pushbot/pushbot_client")) 6 | return f 7 | -------------------------------------------------------------------------------- /luasrc/model/cbi/pushbot/log.lua: -------------------------------------------------------------------------------- 1 | f = SimpleForm("pushbot") 2 | f.reset = false 3 | f.submit = false 4 | f:append(Template("pushbot/pushbot_log")) 5 | return f 6 | -------------------------------------------------------------------------------- /luasrc/model/cbi/pushbot/setting.lua: -------------------------------------------------------------------------------- 1 | 2 | local nt = require "luci.sys".net 3 | local fs=require"nixio.fs" 4 | local e=luci.model.uci.cursor() 5 | local net = require "luci.model.network".init() 6 | local sys = require "luci.sys" 7 | local ifaces = sys.net:devices() 8 | 9 | m=Map("pushbot",translate("PushBot"), 10 | translate("「全能推送」,英文名「PushBot」,是一款从服务器推送报警信息和日志到各平台的工具。
支持钉钉推送,企业微信推送,PushPlus推送。
本插件由tty228/luci-app-serverchan创建,然后七年修改为全能推送自用。

如果你在使用中遇到问题,请到这里提交:") 11 | .. [[]] 12 | .. translate("github 项目地址") 13 | .. [[]] 14 | ) 15 | 16 | m:section(SimpleSection).template = "pushbot/pushbot_status" 17 | 18 | s=m:section(NamedSection,"pushbot","pushbot",translate("")) 19 | s:tab("basic", translate("基本设置")) 20 | s:tab("content", translate("推送内容")) 21 | s:tab("crontab", translate("定时推送")) 22 | s:tab("disturb", translate("免打扰")) 23 | s.addremove = false 24 | s.anonymous = true 25 | 26 | --基本设置 27 | a=s:taboption("basic", Flag,"pushbot_enable",translate("启用")) 28 | a.default=0 29 | a.rmempty = true 30 | 31 | --精简模式 32 | a = s:taboption("basic", MultiValue, "lite_enable", translate("精简模式")) 33 | a:value("device", translate("精简当前设备列表")) 34 | a:value("nowtime", translate("精简当前时间")) 35 | a:value("content", translate("只推送标题")) 36 | a.widget = "checkbox" 37 | a.default = nil 38 | a.optional = true 39 | 40 | --推送模式 41 | a=s:taboption("basic", ListValue,"jsonpath",translate("推送模式")) 42 | a.default="/usr/bin/pushbot/api/dingding.json" 43 | a.rmempty = true 44 | a:value("/usr/bin/pushbot/api/dingding.json",translate("钉钉")) 45 | a:value("/usr/bin/pushbot/api/ent_wechat.json",translate("企业微信")) 46 | a:value("/usr/bin/pushbot/api/feishu.json",translate("飞书")) 47 | a:value("/usr/bin/pushbot/api/bark.json",translate("Bark")) 48 | a:value("/usr/bin/pushbot/api/pushplus.json",translate("PushPlus")) 49 | a:value("/usr/bin/pushbot/api/pushdeer.json",translate("PushDeer")) 50 | a:value("/usr/bin/pushbot/api/diy.json",translate("自定义推送")) 51 | 52 | a=s:taboption("basic", Value,"dd_webhook",translate('Webhook'), translate("钉钉机器人 Webhook")..",只输入access_token=后面的即可
调用代码获取点击这里

") 53 | a.rmempty = true 54 | a:depends("jsonpath","/usr/bin/pushbot/api/dingding.json") 55 | 56 | a=s:taboption("basic", Value, "we_webhook", translate("Webhook"),translate("企业微信机器人 Webhook")..",只输入key=后面的即可
调用代码获取点击这里

") 57 | a.rmempty = true 58 | a:depends("jsonpath","/usr/bin/pushbot/api/ent_wechat.json") 59 | 60 | a=s:taboption("basic", Value,"pp_token",translate('PushPlus Token'), translate("PushPlus Token").."
调用代码获取点击这里

") 61 | a.rmempty = true 62 | a:depends("jsonpath","/usr/bin/pushbot/api/pushplus.json") 63 | 64 | a=s:taboption("basic", ListValue,"pp_channel",translate('PushPlus Channel')) 65 | a.rmempty = true 66 | a:depends("jsonpath","/usr/bin/pushbot/api/pushplus.json") 67 | a:value("wechat",translate("wechat:PushPlus微信公众号")) 68 | a:value("cp",translate("cp:企业微信应用")) 69 | a:value("webhook",translate("webhook:第三方webhook")) 70 | a:value("sms",translate("sms:短信")) 71 | a:value("mail",translate("mail:邮箱")) 72 | a.description = translate("第三方webhook:企业微信、钉钉、飞书、server酱
sms短信/mail邮箱:PushPlus暂未开放
具体channel设定参见:点击这里") 73 | 74 | a=s:taboption("basic", Value,"pp_webhook",translate('PushPlus Custom Webhook'), translate("PushPlus 自定义Webhook").."
第三方webhook或企业微信调用
具体自定义Webhook设定参见:点击这里

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

") 85 | a.rmempty = true 86 | a:depends("pp_topic_enable","1") 87 | 88 | a=s:taboption("basic", Value,"pushdeer_key",translate('PushDeer Key'), translate("PushDeer Key").."
调用代码获取点击这里

") 89 | a.rmempty = true 90 | a:depends("jsonpath","/usr/bin/pushbot/api/pushdeer.json") 91 | 92 | a=s:taboption("basic", Flag,"pushdeer_srv_enable",translate("自建 PushDeer 服务器")) 93 | a.default=0 94 | a.rmempty = true 95 | a:depends("jsonpath","/usr/bin/pushbot/api/pushdeer.json") 96 | 97 | a=s:taboption("basic", Value,"pushdeer_srv",translate('PushDeer Server'), translate("PushDeer 自建服务器地址").."
如https://your.domain:port
具体自建服务器设定参见:点击这里

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

") 102 | a.rmempty = true 103 | a:depends("jsonpath","/usr/bin/pushbot/api/feishu.json") 104 | 105 | a=s:taboption("basic", Value,"bark_token",translate('Bark Token'), translate("Bark Token").."
调用代码获取点击这里

") 106 | a.rmempty = true 107 | a:depends("jsonpath","/usr/bin/pushbot/api/bark.json") 108 | 109 | a=s:taboption("basic", Flag,"bark_srv_enable",translate("自建 Bark 服务器")) 110 | a.default=0 111 | a.rmempty = true 112 | a:depends("jsonpath","/usr/bin/pushbot/api/bark.json") 113 | 114 | a=s:taboption("basic", Value,"bark_srv",translate('Bark Server'), translate("Bark 自建服务器地址").."
如https://your.domain:port
具体自建服务器设定参见:点击这里

") 115 | a.rmempty = true 116 | a:depends("bark_srv_enable","1") 117 | 118 | a=s:taboption("basic", Value,"bark_sound",translate('Bark Sound'), translate("Bark 通知声音").."
如silence.caf
具体设定参见:点击这里

") 119 | a.rmempty = true 120 | a.default = "silence.caf" 121 | a:depends("jsonpath","/usr/bin/pushbot/api/bark.json") 122 | 123 | a=s:taboption("basic", Flag,"bark_icon_enable",translate(" Bark 通知图标")) 124 | a.default=0 125 | a.rmempty = true 126 | a:depends("jsonpath","/usr/bin/pushbot/api/bark.json") 127 | 128 | a=s:taboption("basic", Value,"bark_icon",translate('Bark Icon'), translate("Bark 通知图标").."(仅 iOS15 或以上支持)
如http://day.app/assets/images/avatar.jpg
具体设定参见:点击这里

") 129 | a.rmempty = true 130 | a.default = "http://day.app/assets/images/avatar.jpg" 131 | a:depends("bark_icon_enable","1") 132 | 133 | a=s:taboption("basic", Value,"bark_level",translate('Bark Level'), translate("Bark 时效性通知").."
可选参数值:
active:不设置时的默认值,系统会立即亮屏显示通知。
timeSensitive:时效性通知,可在专注状态下显示通知。
passive:仅将通知添加到通知列表,不会亮屏提醒。") 134 | a.rmempty = true 135 | a.default = "active" 136 | a:depends("jsonpath","/usr/bin/pushbot/api/bark.json") 137 | 138 | a=s:taboption("basic", TextValue, "diy_json", translate("自定义推送")) 139 | a.optional = false 140 | a.rows = 28 141 | a.wrap = "soft" 142 | a.cfgvalue = function(self, section) 143 | return fs.readfile("/usr/bin/pushbot/api/diy.json") 144 | end 145 | a.write = function(self, section, value) 146 | fs.writefile("/usr/bin/pushbot/api/diy.json", value:gsub("\r\n", "\n")) 147 | end 148 | a:depends("jsonpath","/usr/bin/pushbot/api/diy.json") 149 | 150 | a=s:taboption("basic", Button,"__add",translate("发送测试")) 151 | a.inputtitle=translate("发送") 152 | a.inputstyle = "apply" 153 | function a.write(self, section) 154 | luci.sys.call("cbi.apply") 155 | luci.sys.call("/usr/bin/pushbot/pushbot test &") 156 | end 157 | 158 | a=s:taboption("basic", Value,"device_name",translate('本设备名称')) 159 | a.rmempty = true 160 | a.description = translate("在推送信息标题中会标识本设备名称,用于区分推送信息的来源设备") 161 | 162 | a=s:taboption("basic", Value,"sleeptime",translate('检测时间间隔')) 163 | a.rmempty = true 164 | a.optional = false 165 | a.default = "60" 166 | a.datatype = "and(uinteger,min(10))" 167 | a.description = translate("越短的时间时间响应越及时,但会占用更多的系统资源") 168 | 169 | a=s:taboption("basic", ListValue,"oui_data",translate("MAC设备信息数据库")) 170 | a.rmempty = true 171 | a.default="" 172 | a:value("",translate("关闭")) 173 | a:value("1",translate("简化版")) 174 | a:value("2",translate("完整版")) 175 | a:value("3",translate("网络查询")) 176 | a.description = translate("需下载 4.36m 原始数据,处理后完整版约 1.2M,简化版约 250kb
若无梯子,请勿使用网络查询") 177 | 178 | a=s:taboption("basic", Flag,"oui_dir",translate("下载到内存")) 179 | a.rmempty = true 180 | a:depends("oui_data","1") 181 | a:depends("oui_data","2") 182 | a.description = translate("懒得做自动更新了,下载到内存中,重启会重新下载
若无梯子,还是下到机身吧") 183 | 184 | a=s:taboption("basic", Flag,"reset_regularly",translate("每天零点重置流量数据")) 185 | a.rmempty = true 186 | 187 | a=s:taboption("basic", Flag,"debuglevel",translate("开启日志")) 188 | a.rmempty = true 189 | 190 | a= s:taboption("basic", DynamicList, "device_aliases", translate("设备别名")) 191 | a.rmempty = true 192 | a.description = translate("
请输入设备 MAC 和设备别名,用“-”隔开,如:
XX:XX:XX:XX:XX:XX-我的手机") 193 | 194 | --设备状态 195 | a=s:taboption("content", ListValue,"pushbot_ipv4",translate("IPv4 变更通知")) 196 | a.rmempty = true 197 | a.default="" 198 | a:value("",translate("关闭")) 199 | a:value("1",translate("通过接口获取")) 200 | a:value("2",translate("通过URL获取")) 201 | 202 | a = s:taboption("content", ListValue, "ipv4_interface", translate("接口名称")) 203 | a.rmempty = true 204 | a:depends({pushbot_ipv4="1"}) 205 | for _, iface in ipairs(ifaces) do 206 | if not (iface == "lo" or iface:match("^ifb.*")) then 207 | local nets = net:get_interface(iface) 208 | nets = nets and nets:get_networks() or {} 209 | for k, v in pairs(nets) do 210 | nets[k] = nets[k].sid 211 | end 212 | nets = table.concat(nets, ",") 213 | a:value(iface, ((#nets > 0) and "%s (%s)" % {iface, nets} or iface)) 214 | end 215 | end 216 | a.description = translate("
一般选择 wan 接口,多拨环境请自行选择") 217 | 218 | a=s:taboption("content", TextValue, "ipv4_list", translate("IPv4 API列表")) 219 | a.optional = false 220 | a.rows = 8 221 | a.wrap = "soft" 222 | a.cfgvalue = function(self, section) 223 | return fs.readfile("/usr/bin/pushbot/api/ipv4.list") 224 | end 225 | a.write = function(self, section, value) 226 | fs.writefile("/usr/bin/pushbot/api/ipv4.list", value:gsub("\r\n", "\n")) 227 | end 228 | a.description = translate("
会因服务器稳定性、连接频繁等原因导致获取失败
如接口可以正常获取 IP,不推荐使用
从以上列表中随机地址访问") 229 | a:depends({pushbot_ipv4="2"}) 230 | 231 | a=s:taboption("content", ListValue,"pushbot_ipv6",translate("IPv6 变更通知")) 232 | a.rmempty = true 233 | a.default="disable" 234 | a:value("0",translate("关闭")) 235 | a:value("1",translate("通过接口获取")) 236 | a:value("2",translate("通过URL获取")) 237 | 238 | a = s:taboption("content", ListValue, "ipv6_interface", translate("接口名称")) 239 | a.rmempty = true 240 | a:depends({pushbot_ipv6="1"}) 241 | for _, iface in ipairs(ifaces) do 242 | if not (iface == "lo" or iface:match("^ifb.*")) then 243 | local nets = net:get_interface(iface) 244 | nets = nets and nets:get_networks() or {} 245 | for k, v in pairs(nets) do 246 | nets[k] = nets[k].sid 247 | end 248 | nets = table.concat(nets, ",") 249 | a:value(iface, ((#nets > 0) and "%s (%s)" % {iface, nets} or iface)) 250 | end 251 | end 252 | a.description = translate("
一般选择 wan 接口,多拨环境请自行选择") 253 | 254 | a=s:taboption("content", TextValue, "ipv6_list", translate("IPv6 API列表")) 255 | a.optional = false 256 | a.rows = 8 257 | a.wrap = "soft" 258 | a.cfgvalue = function(self, section) 259 | return fs.readfile("/usr/bin/pushbot/api/ipv6.list") 260 | end 261 | a.write = function(self, section, value) 262 | fs.writefile("/usr/bin/pushbot/api/ipv6.list", value:gsub("\r\n", "\n")) 263 | end 264 | a.description = translate("
会因服务器稳定性、连接频繁等原因导致获取失败
如接口可以正常获取 IP,不推荐使用
从以上列表中随机地址访问") 265 | a:depends({pushbot_ipv6="2"}) 266 | 267 | a=s:taboption("content", Flag,"pushbot_up",translate("设备上线通知")) 268 | a.default=1 269 | a.rmempty = true 270 | 271 | a=s:taboption("content", Flag,"pushbot_down",translate("设备下线通知")) 272 | a.default=1 273 | a.rmempty = true 274 | 275 | a=s:taboption("content", Flag,"cpuload_enable",translate("CPU 负载报警")) 276 | a.default=1 277 | a.rmempty = true 278 | 279 | a= s:taboption("content", Value, "cpuload", "负载报警阈值") 280 | a.default = 2 281 | a.rmempty = true 282 | a:depends({cpuload_enable="1"}) 283 | 284 | a=s:taboption("content", Flag,"temperature_enable",translate("CPU 温度报警")) 285 | a.default=1 286 | a.rmempty = true 287 | a.description = translate("请确认设备可以获取温度,如需修改命令,请移步高级设置") 288 | 289 | a= s:taboption("content", Value, "temperature", "温度报警阈值") 290 | a.rmempty = true 291 | a.default = "80" 292 | a.datatype="uinteger" 293 | a:depends({temperature_enable="1"}) 294 | a.description = translate("
设备报警只会在连续五分钟超过设定值时才会推送
而且一个小时内不会再提醒第二次") 295 | 296 | a=s:taboption("content", Flag,"client_usage",translate("设备异常流量")) 297 | a.default=0 298 | a.rmempty = true 299 | 300 | a= s:taboption("content", Value, "client_usage_max", "每分钟流量限制") 301 | a.default = "10M" 302 | a.rmempty = true 303 | a:depends({client_usage="1"}) 304 | a.description = translate("设备异常流量警报(byte),你可以追加 K 或者 M") 305 | 306 | a=s:taboption("content", Flag,"client_usage_disturb",translate("异常流量免打扰")) 307 | a.default=1 308 | a.rmempty = true 309 | a:depends({client_usage="1"}) 310 | 311 | a = s:taboption("content", DynamicList, "client_usage_whitelist", translate("异常流量关注列表")) 312 | nt.mac_hints(function(mac, name) a:value(mac, "%s (%s)" %{ mac, name }) end) 313 | a.rmempty = true 314 | a:depends({client_usage_disturb="1"}) 315 | a.description = translate("请输入设备 MAC") 316 | 317 | --LoginNoti 318 | a=s:taboption("content", Flag,"web_logged",translate("Web 登录提醒")) 319 | a.default=0 320 | a.rmempty = true 321 | 322 | a=s:taboption("content", Flag,"ssh_logged",translate("SSH 登录提醒")) 323 | a.default=0 324 | a.rmempty = true 325 | 326 | a=s:taboption("content", Flag,"web_login_failed",translate("Web 错误尝试提醒")) 327 | a.default=0 328 | a.rmempty = true 329 | 330 | a=s:taboption("content", Flag,"ssh_login_failed",translate("SSH 错误尝试提醒")) 331 | a.default=0 332 | a.rmempty = true 333 | 334 | a= s:taboption("content", Value, "login_max_num", "错误尝试次数") 335 | a.default = "3" 336 | a.datatype="and(uinteger,min(1))" 337 | a:depends("web_login_failed","1") 338 | a:depends("ssh_login_failed","1") 339 | a.description = translate("超过次数后推送提醒") 340 | 341 | a=s:taboption("content", Flag,"web_login_black",translate("自动拉黑")) 342 | a.default=0 343 | a.rmempty = true 344 | a:depends("web_login_failed","1") 345 | a:depends("ssh_login_failed","1") 346 | a.description = translate("直到重启前都不会重置次数,请先添加白名单") 347 | 348 | a= s:taboption("content", Value, "ip_black_timeout", "拉黑时间(秒)") 349 | a.default = "86400" 350 | a.datatype="and(uinteger,min(0))" 351 | a:depends("web_login_black","1") 352 | a.description = translate("0 为永久拉黑,慎用
如不幸误操作,请更改设备 IP 进入 LUCI 界面清空规则") 353 | 354 | a=s:taboption("content", DynamicList, "ip_white_list", translate("白名单 IP 列表")) 355 | a.datatype = "ipaddr" 356 | a.rmempty = true 357 | luci.ip.neighbors({family = 4}, function(entry) 358 | if entry.reachable then 359 | a:value(entry.dest:string()) 360 | end 361 | end) 362 | a:depends("web_logged","1") 363 | a:depends("ssh_logged","1") 364 | a:depends("web_login_failed","1") 365 | a:depends("ssh_login_failed","1") 366 | a.description = translate("忽略白名单登陆提醒和拉黑操作,暂不支持掩码位表示") 367 | 368 | a=s:taboption("content", TextValue, "ip_black_list", translate("IP 黑名单列表")) 369 | a.optional = false 370 | a.rows = 8 371 | a.wrap = "soft" 372 | a.cfgvalue = function(self, section) 373 | return fs.readfile("/usr/bin/pushbot/api/ip_blacklist") 374 | end 375 | a.write = function(self, section, value) 376 | fs.writefile("/usr/bin/pushbot/api/ip_blacklist", value:gsub("\r\n", "\n")) 377 | end 378 | a:depends("web_login_black","1") 379 | 380 | --定时推送 381 | a=s:taboption("crontab", ListValue,"crontab",translate("定时任务设定")) 382 | a.rmempty = true 383 | a.default="" 384 | a:value("",translate("关闭")) 385 | a:value("1",translate("定时发送")) 386 | a:value("2",translate("间隔发送")) 387 | 388 | a=s:taboption("crontab", ListValue,"regular_time",translate("发送时间")) 389 | a.rmempty = true 390 | for t=0,23 do 391 | a:value(t,translate("每天"..t.."点")) 392 | end 393 | a.default=8 394 | a.datatype=uinteger 395 | a:depends("crontab","1") 396 | 397 | a=s:taboption("crontab", ListValue,"regular_time_2",translate("发送时间")) 398 | a.rmempty = true 399 | a:value("",translate("关闭")) 400 | for t=0,23 do 401 | a:value(t,translate("每天"..t.."点")) 402 | end 403 | a.default="关闭" 404 | a.datatype=uinteger 405 | a:depends("crontab","1") 406 | 407 | a=s:taboption("crontab", ListValue,"regular_time_3",translate("发送时间")) 408 | a.rmempty = true 409 | 410 | a:value("",translate("关闭")) 411 | for t=0,23 do 412 | a:value(t,translate("每天"..t.."点")) 413 | end 414 | a.default="关闭" 415 | a.datatype=uinteger 416 | a:depends("crontab","1") 417 | 418 | a=s:taboption("crontab", ListValue,"interval_time",translate("发送间隔")) 419 | a.rmempty = true 420 | for t=1,23 do 421 | a:value(t,translate(t.."小时")) 422 | end 423 | a.default=6 424 | a.datatype=uinteger 425 | a:depends("crontab","2") 426 | a.description = translate("
从 00:00 开始,每 * 小时发送一次") 427 | 428 | a= s:taboption("crontab", Value, "send_title", translate("推送标题")) 429 | a:depends("crontab","1") 430 | a:depends("crontab","2") 431 | a.placeholder = "OpenWrt By tty228 路由状态:" 432 | a.description = translate("
使用特殊符号可能会造成发送失败") 433 | 434 | a=s:taboption("crontab", Flag,"router_status",translate("系统运行情况")) 435 | a.default=1 436 | a:depends("crontab","1") 437 | a:depends("crontab","2") 438 | 439 | a=s:taboption("crontab", Flag,"router_temp",translate("设备温度")) 440 | a.default=1 441 | a:depends("crontab","1") 442 | a:depends("crontab","2") 443 | 444 | a=s:taboption("crontab", Flag,"router_wan",translate("WAN信息")) 445 | a.default=1 446 | a:depends("crontab","1") 447 | a:depends("crontab","2") 448 | 449 | a=s:taboption("crontab", Flag,"client_list",translate("客户端列表")) 450 | a.default=1 451 | a:depends("crontab","1") 452 | a:depends("crontab","2") 453 | 454 | a=s:taboption("crontab", Value,"google_check_timeout",translate("全球互联检测超时时间")) 455 | a.rmempty = true 456 | a.optional = false 457 | a.default = "10" 458 | a.datatype = "and(uinteger,min(3))" 459 | a.description = translate("过短的时间可能导致检测不准确") 460 | 461 | e=s:taboption("crontab", Button,"_add",translate("手动发送")) 462 | e.inputtitle=translate("发送") 463 | e:depends("crontab","1") 464 | e:depends("crontab","2") 465 | e.inputstyle = "apply" 466 | function e.write(self, section) 467 | luci.sys.call("cbi.apply") 468 | luci.sys.call("/usr/bin/pushbot/pushbot send &") 469 | end 470 | 471 | --免打扰 472 | a=s:taboption("disturb", ListValue,"pushbot_sheep",translate("免打扰时段设置"),translate("在指定整点时间段内,暂停推送消息
免打扰时间中,定时推送也会被阻止。")) 473 | a.rmempty = true 474 | 475 | a:value("",translate("关闭")) 476 | a:value("1",translate("模式一:脚本挂起")) 477 | a:value("2",translate("模式二:静默模式")) 478 | a.description = translate("模式一停止一切检测,包括无人值守。") 479 | a=s:taboption("disturb", ListValue,"starttime",translate("免打扰开始时间")) 480 | a.rmempty = true 481 | 482 | for t=0,23 do 483 | a:value(t,translate("每天"..t.."点")) 484 | end 485 | a.default=0 486 | a.datatype=uinteger 487 | a:depends({pushbot_sheep="1"}) 488 | a:depends({pushbot_sheep="2"}) 489 | a=s:taboption("disturb", ListValue,"endtime",translate("免打扰结束时间")) 490 | a.rmempty = true 491 | 492 | for t=0,23 do 493 | a:value(t,translate("每天"..t.."点")) 494 | end 495 | a.default=8 496 | a.datatype=uinteger 497 | a:depends({pushbot_sheep="1"}) 498 | a:depends({pushbot_sheep="2"}) 499 | 500 | a=s:taboption("disturb", ListValue,"macmechanism",translate("MAC过滤")) 501 | a:value("",translate("disable")) 502 | a:value("allow",translate("忽略列表内设备")) 503 | a:value("block",translate("仅通知列表内设备")) 504 | a:value("interface",translate("仅通知此接口设备")) 505 | a.rmempty = true 506 | 507 | 508 | a = s:taboption("disturb", DynamicList, "pushbot_whitelist", translate("忽略列表")) 509 | nt.mac_hints(function(mac, name) a :value(mac, "%s (%s)" %{ mac, name }) end) 510 | a.rmempty = true 511 | a:depends({macmechanism="allow"}) 512 | a.description = translate("AA:AA:AA:AA:AA:AA\\|BB:BB:BB:BB:BB:B 可以将多个 MAC 视为同一用户
任一设备在线后不再推送,设备全部离线时才会推送,避免双 wifi 频繁推送") 513 | 514 | a = s:taboption("disturb", DynamicList, "pushbot_blacklist", translate("关注列表")) 515 | nt.mac_hints(function(mac, name) a:value(mac, "%s (%s)" %{ mac, name }) end) 516 | a.rmempty = true 517 | a:depends({macmechanism="block"}) 518 | a.description = translate("AA:AA:AA:AA:AA:AA\\|BB:BB:BB:BB:BB:B 可以将多个 MAC 视为同一用户
任一设备在线后不再推送,设备全部离线时才会推送,避免双 wifi 频繁推送") 519 | 520 | a = s:taboption("disturb", ListValue, "pushbot_interface", translate("接口名称")) 521 | a:depends({macmechanism="interface"}) 522 | a.rmempty = true 523 | 524 | for _, iface in ipairs(ifaces) do 525 | if not (iface == "lo" or iface:match("^ifb.*")) then 526 | local nets = net:get_interface(iface) 527 | nets = nets and nets:get_networks() or {} 528 | for k, v in pairs(nets) do 529 | nets[k] = nets[k].sid 530 | end 531 | nets = table.concat(nets, ",") 532 | a:value(iface, ((#nets > 0) and "%s (%s)" % {iface, nets} or iface)) 533 | end 534 | end 535 | 536 | a=s:taboption("disturb", ListValue,"macmechanism2",translate("MAC过滤2")) 537 | a:value("",translate("disable")) 538 | a:value("MAC_online",translate("列表内任意设备在线时免打扰")) 539 | a:value("MAC_offline",translate("列表内设备都离线后免打扰")) 540 | a.rmempty = true 541 | 542 | a = s:taboption("disturb", DynamicList, "MAC_online_list", translate("在线免打扰列表")) 543 | nt.mac_hints(function(mac, name) a:value(mac, "%s (%s)" %{ mac, name }) end) 544 | a.rmempty = true 545 | a:depends({macmechanism2="MAC_online"}) 546 | 547 | a = s:taboption("disturb", DynamicList, "MAC_offline_list", translate("任意离线免打扰列表")) 548 | nt.mac_hints(function(mac, name) a:value(mac, "%s (%s)" %{ mac, name }) end) 549 | a.rmempty = true 550 | a:depends({macmechanism2="MAC_offline"}) 551 | 552 | return m 553 | -------------------------------------------------------------------------------- /luasrc/view/pushbot/pushbot_log.htm: -------------------------------------------------------------------------------- 1 | <% 2 | local dsp = require "luci.dispatcher" 3 | -%> 4 | 5 | 29 |
30 | <%:自动刷新%> 31 | 32 | 33 |
34 | -------------------------------------------------------------------------------- /luasrc/view/pushbot/pushbot_status.htm: -------------------------------------------------------------------------------- 1 | 17 | 18 |
19 |

20 | <%:Collecting data...%> 21 |

22 |
23 | -------------------------------------------------------------------------------- /root/etc/config/pushbot: -------------------------------------------------------------------------------- 1 | 2 | config pushbot 'pushbot' 3 | option pushbot_enable '0' 4 | option sleeptime '60' 5 | option pushbot_ipv6 '0' 6 | option pushbot_up '1' 7 | option pushbot_down '1' 8 | option cpuload_enable '1' 9 | option cpuload '2' 10 | option temperature_enable '0' 11 | -------------------------------------------------------------------------------- /root/etc/init.d/pushbot: -------------------------------------------------------------------------------- 1 | #!/bin/sh /etc/rc.common 2 | 3 | START=99 4 | STOP=10 5 | 6 | start() { 7 | state=`pgrep -f "/usr/bin/pushbot/pushbot"` 8 | if [ ! -z "$state" ]; then 9 | restart 10 | else 11 | /usr/bin/pushbot/pushbot & 12 | fi 13 | echo "pushbot is starting now ..." 14 | } 15 | 16 | stop() { 17 | kill -9 `pgrep -f "/usr/bin/pushbot/pushbot"` 2>/dev/null 18 | echo "pushbot exit ..." 19 | } 20 | 21 | restart(){ 22 | stop 23 | sleep 1 24 | start 25 | echo "restarted." 26 | } 27 | -------------------------------------------------------------------------------- /root/etc/uci-defaults/luci-pushbot: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | uci -q batch <<-EOF >/dev/null 4 | delete ucitrack.@pushbot[-1] 5 | add ucitrack pushbot 6 | set ucitrack.@pushbot[-1].init=pushbot 7 | commit ucitrack 8 | EOF 9 | 10 | rm -rf /tmp/luci-* 11 | exit 0 12 | -------------------------------------------------------------------------------- /root/usr/bin/pushbot/api/bark.json: -------------------------------------------------------------------------------- 1 | { 2 | "_api": "这是Bark推送 post 模板信息 api 文件", 3 | "_api": "【Bark推送】", 4 | 5 | "url": "${bark_srv}/push", 6 | "data": "@${tempjsonpath}", 7 | "content_type": "Content-Type: application/json; charset=utf-8", 8 | "str_title_start": "【", 9 | "str_title_end": "】", 10 | "str_linefeed": "\\n", 11 | "str_splitline": "\\n\\n", 12 | "str_space": " ", 13 | "str_tab": " ", 14 | "table_tab": "", 15 | "font_green": "", 16 | "font_green2": "", 17 | "font_red": "", 18 | "font_blue": "", 19 | "font_purple": "", 20 | "font_end": "", 21 | "font_end2": "", 22 | "percentsym": "", 23 | "boldstar": "", 24 | "type": { 25 | "device_key": "\"${bark_token}\"", 26 | "title": "\"${1}\"", 27 | "body": "\"${nowtime}${str_linefeed}${2}\"", 28 | "ext_params": { 29 | "group": "\"${device_name}\"", 30 | "isArchive": "1", 31 | "icon": "\"${bark_icon}\"", 32 | "level": "\"${bark_level}\"" 33 | }, 34 | "sound": "\"${bark_sound}\"" 35 | } 36 | } -------------------------------------------------------------------------------- /root/usr/bin/pushbot/api/dingding.json: -------------------------------------------------------------------------------- 1 | { 2 | "_api": "这是 Pushbot:钉钉 api 文件", 3 | "_api": "【钉钉推送】", 4 | 5 | "url": "\"https://oapi.dingtalk.com/robot/send?access_token=${dd_webhook}\"", 6 | "data": "@${tempjsonpath}", 7 | "content_type": "Content-Type:application/json", 8 | "str_title_start": "**", 9 | "str_title_end": "**", 10 | "str_linefeed": "\\n\\n", 11 | "str_splitline": "\\n\\n---\\n\\n", 12 | "str_space": " ", 13 | "str_tab": " ", 14 | "table_tab": "", 15 | "font_green": "", 16 | "font_green2": "", 17 | "font_red": "", 18 | "font_blue": "", 19 | "font_purple": "", 20 | "font_end": "", 21 | "font_end2": "", 22 | "percentsym": "", 23 | "boldstar": "**", 24 | "type": 25 | { 26 | "msgtype": "\"markdown\"", 27 | "markdown": { 28 | "title": "\"${1}\"", 29 | "text": "\"${str_title_start}${font_purple}${1}${font_end}${str_title_end}${str_linefeed}${nowtime}${str_linefeed}${2}${str_linefeed}${font_purple}${1}${font_end}\"" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /root/usr/bin/pushbot/api/diy.json: -------------------------------------------------------------------------------- 1 | { 2 | "_//": "-------------------------------------------------------------------------------", 3 | "_readme": "这是 自定义 api 文件,这里以 telegram 为例", 4 | "_readme": "特殊符号请使用斜杠转义,变量使用 ${var} 表示", 5 | "_//": "-------------------------------------------------------------------------------", 6 | "_api": "【DIY 推送】", 7 | "_url": "api 地址", 8 | "_data": "生成的 json 文件路径,一般不需要改,如 api 不支持 json,请参考 serverchan 推送接口", 9 | "_content_type": "post 内容类型,这里为 json", 10 | "_//": "-------------------------------------------------------------------------------", 11 | "_str_title_start": "标题粗体字开始符号", 12 | "_str_title_end": "标题粗体字结束符号", 13 | "_str_linefeed": "换行符号", 14 | "_str_splitline": "换行+分隔符", 15 | "_str_space": "空格", 16 | "_str_tab": "TAB(用在行首,生成文字区块)", 17 | "_//": "-------------------------------------------------------------------------------", 18 | "_type": 19 | { 20 | "_readme": "type 对象因为需要转义变量,前后必须使用 斜杠+双引号 转义", 21 | "_readme": "参照上文说明,填写下文相关参数" 22 | }, 23 | "_//": "-------------------------------------------------------------------------------", 24 | 25 | "url": "https://api.telegram.org/bot${tg_token}/sendMessage", 26 | "data": "@${tempjsonpath}", 27 | "content_type": "Content-Type: application/json", 28 | "str_title_start": "", 29 | "str_title_end": "", 30 | "str_linefeed": "\\n", 31 | "str_splitline": "\\n----\\n", 32 | "str_space": " ", 33 | "str_tab": " ", 34 | "table_tab": "", 35 | "font_green": "", 36 | "font_green2": "", 37 | "font_red": "", 38 | "font_blue": "", 39 | "font_purple": "", 40 | "font_end": "", 41 | "font_end2": "", 42 | "percentsym": "25", 43 | "boldstar": "**", 44 | "type": 45 | { 46 | "text":"\"${str_title_start}${1}${str_title_end}${str_splitline}${nowtime}${2}\"", 47 | "chat_id":"\"${chat_id}\"", 48 | "parse_mode":"\"HTML\"" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /root/usr/bin/pushbot/api/ent_wechat.json: -------------------------------------------------------------------------------- 1 | { 2 | "_api": "这是企业微信 markdown 模板信息 api 文件", 3 | "_api": "【企业微信】", 4 | 5 | "url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${we_webhook}", 6 | "data": "@${tempjsonpath}", 7 | "content_type": "Content-Type: application/json", 8 | "str_title_start": "#### ", 9 | "str_title_end": "", 10 | "str_linefeed": "\\n", 11 | "str_splitline": "\\n------\\n", 12 | "str_space": " ", 13 | "str_tab": " ", 14 | "table_tab": "", 15 | "font_green": "", 16 | "font_green2": "", 17 | "font_red": "", 18 | "font_blue": "", 19 | "font_purple": "", 20 | "font_end": "", 21 | "font_end2": "", 22 | "percentsym": "", 23 | "boldstar": "**", 24 | "type": 25 | { 26 | "msgtype": "\"markdown\"", 27 | "markdown": { 28 | "title": "\"${1}\"", 29 | "content": "\"${str_title_start}${font_purple}${1}${font_end}${str_title_end}${str_linefeed}${nowtime}${str_linefeed}${2}\"" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /root/usr/bin/pushbot/api/feishu.json: -------------------------------------------------------------------------------- 1 | { 2 | "_api": "这是飞书推送 post 模板信息 api 文件", 3 | "_api": "【飞书推送】", 4 | 5 | "url": "https://open.feishu.cn/open-apis/bot/v2/hook/${fs_webhook}", 6 | "data": "@${tempjsonpath}", 7 | "content_type": "Content-Type: application/json", 8 | "str_title_start": "**", 9 | "str_title_end": "**", 10 | "str_linefeed": "\\n", 11 | "str_splitline": "\\n\\n", 12 | "str_space": " ", 13 | "str_tab": " ", 14 | "table_tab": "", 15 | "font_green": "", 16 | "font_green": "", 17 | "font_red": "", 18 | "font_blue": "", 19 | "font_purple": "", 20 | "font_end": "", 21 | "font_end2": "", 22 | "percentsym": "", 23 | "boldstar": "**", 24 | "type": 25 | { 26 | "msg_type": "\"interactive\"", 27 | "card": { 28 | "config": { 29 | "wide_screen_mode": "true" 30 | }, 31 | "header": { 32 | "template": "\"purple\"", 33 | "title": { 34 | "content": "\"${1}\"", 35 | "tag": "\"plain_text\"" 36 | } 37 | }, 38 | "elements": [ 39 | { 40 | "tag": "\"div\"", 41 | "text": { 42 | "content": "\"${nowtime}${str_linefeed}${2}\"", 43 | "tag": "\"lark_md\"" 44 | } 45 | }, 46 | { 47 | "tag": "\"hr\"" 48 | }, 49 | { 50 | "elements": [ 51 | { 52 | "content": "\"来自${device_name}\"", 53 | "tag": "\"lark_md\"" 54 | } 55 | ], 56 | "tag": "\"note\"" 57 | } 58 | ] 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /root/usr/bin/pushbot/api/ip_blacklist: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /root/usr/bin/pushbot/api/ipv4.list: -------------------------------------------------------------------------------- 1 | www.cip.cc 2 | ipv4.ddnspod.com 3 | ifcfg.cn 4 | speed.neu.edu.cn/getIP.php 5 | ddns.oray.com/checkip 6 | www.net.cn/static/customercare/yourip.asp 7 | -------------------------------------------------------------------------------- /root/usr/bin/pushbot/api/ipv6.list: -------------------------------------------------------------------------------- 1 | ip.sb 2 | ipv6.ddnspod.com 3 | api-ipv6.ip.sb/ip 4 | speed.neu6.edu.cn/getIP.php 5 | v6.myip.la/json 6 | -------------------------------------------------------------------------------- /root/usr/bin/pushbot/api/pushdeer.json: -------------------------------------------------------------------------------- 1 | { 2 | "_api": "这是 PushDeer推送 api 文件", 3 | "_api": "【PushDeer推送】", 4 | 5 | "url": "${pushdeer_srv}/message/push", 6 | "data": "@${tempjsonpath}", 7 | "content_type": "Content-Type:application/json", 8 | "str_title_start": "**【", 9 | "str_title_end": "】**", 10 | "str_linefeed": "\\n\\n", 11 | "str_splitline": "\\n\\n---\\n\\n", 12 | "str_space": " ", 13 | "str_tab": " ", 14 | "table_tab": "┋", 15 | "font_green": "", 16 | "font_green2": "", 17 | "font_red": "", 18 | "font_blue": "", 19 | "font_purple": "", 20 | "font_end": "", 21 | "font_end2": "", 22 | "percentsym": "", 23 | "boldstar": "**", 24 | "type": 25 | { 26 | "pushkey": "\"${pushdeer_key}\"", 27 | "type": "\"markdown\"", 28 | "text": "\"${1}\"", 29 | "desp": "\"${nowtime}${str_linefeed}${2}\"" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /root/usr/bin/pushbot/api/pushplus.json: -------------------------------------------------------------------------------- 1 | { 2 | "_api": "这是 Pushbot:PushPlus api 文件", 3 | "_api": "【PushPlus推送】", 4 | 5 | "url": "http://www.pushplus.plus/send", 6 | "data": "@${tempjsonpath}", 7 | "content_type": "Content-Type:application/json", 8 | "str_title_start": "#### ", 9 | "str_title_end": "", 10 | "str_linefeed": "\\n\\n", 11 | "str_splitline": "\\n----\\n", 12 | "str_space": " ", 13 | "str_tab": " ", 14 | "table_tab": "", 15 | "font_green": "", 16 | "font_green2": "", 17 | "font_red": "", 18 | "font_blue": "", 19 | "font_purple": "", 20 | "font_end": "", 21 | "font_end2": "", 22 | "percentsym": "", 23 | "boldstar": "", 24 | "type": 25 | { 26 | "token": "\"${pp_token}\"", 27 | "channel": "\"${pp_channel}\"", 28 | "webhook": "\"${pp_webhook}\"", 29 | "topic": "\"${pp_topic}\"", 30 | "title": "\"${1}\"", 31 | "content": "\"${2}\"", 32 | "template": "\"markdown\"" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /root/usr/bin/pushbot/pushbot: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 读取设置文件 4 | function get_config(){ 5 | while [[ "$*" != "" ]]; do 6 | eval ${1}='`uci get pushbot.pushbot.$1`' 2>/dev/null 7 | shift 8 | done 9 | } 10 | 11 | # 初始化设置信息 12 | function read_config(){ 13 | get_config "pushbot_enable" "lite_enable" "device_name" "sleeptime" "oui_dir" "oui_data" "reset_regularly" "debuglevel" "device_aliases" \ 14 | "pushbot_ipv4" "ipv4_interface" "pushbot_ipv6" "ipv6_interface" "pushbot_up" "pushbot_down" "cpuload_enable" "cpuload" "temperature_enable" "temperature" \ 15 | "regular_time" "regular_time_2" "regular_time_3" "interval_time" \ 16 | "client_usage" "client_usage_max" "client_usage_disturb" "client_usage_whitelist" \ 17 | "web_logged" "ssh_logged" "web_login_failed" "ssh_login_failed" "login_max_num" "web_login_black" "ip_white_list" "ip_black_timeout" \ 18 | "pushbot_sheep" "starttime" "endtime" "pushbot_whitelist" "pushbot_blacklist" "pushbot_interface" "MAC_online_list" "MAC_offline_list" \ 19 | "up_timeout" "down_timeout" "timeout_retry_count" "thread_num" "soc_code" "pve_host" "pve_port"\ 20 | "err_enable" "err_sheep_enable" "err_device_aliases" "network_err_event" "system_time_event" "autoreboot_time" "network_restart_time" "public_ip_event" "public_ip_retry_count" \ 21 | "jsonpath" "dd_webhook" "we_webhook" "pp_token" "pp_channel" "pp_webhook" "pp_topic_enable" "pp_topic" "fs_webhook" "pushdeer_key" "pushdeer_srv_enable" "pushdeer_srv" "bark_srv_enable" "bark_srv" "bark_token" "bark_sound" "bark_icon" "bark_icon_enable" "bark_level" 22 | 23 | for str_version in "wrtbwmon" "iputils-arping" "curl" "iw"; do 24 | eval `echo ${str_version:0:2}"_version"`=`opkg list-installed|grep -w ^${str_version}|awk '{print $3}'` 2>/dev/null 25 | done 26 | dir="/tmp/pushbot/" && mkdir -p ${dir} 27 | tempjsonpath="/tmp/pushbot/temp.json" 28 | ip_blacklist_path="/usr/bin/pushbot/api/ip_blacklist" 29 | [ ! -z "$oui_dir" ] && [ "$oui_dir" -eq "1" ] && oui_base="${dir}oui_base.txt" || oui_base="/usr/bin/pushbot/oui_base.txt" 30 | debuglevel=`echo "$debuglevel"` && [ -z "$debuglevel" ] && logfile="/dev/null" || logfile="${dir}pushbot.log" 31 | pushbot_blacklist=`echo "$pushbot_blacklist"|sed 's/ /\n/g'` 2>/dev/null 32 | pushbot_whitelist=`echo "$pushbot_whitelist"|sed 's/ /\n/g'` 2>/dev/null 33 | device_aliases=`echo "$device_aliases"|sed 's/ /\n/g'|sed 's/-/ /'` 2>/dev/null 34 | err_device_aliases=`echo "$err_device_aliases"|sed 's/ /\n/g'` 2>/dev/null 35 | client_usage_whitelist=`echo "$client_usage_whitelist"|sed 's/ /\n/g'` 2>/dev/null 36 | ip_white_list=`echo "$ip_white_list"|sed 's/ /\n/g'` 2>/dev/null 37 | mark_mac_list="${MAC_online_list} ${MAC_offline_list}" 38 | mark_mac_list=`echo "$mark_mac_list"|sed 's/ /\n/g'|sed 's/-/ /'` 2>/dev/null 39 | ipv4_urllist=`cat /usr/bin/pushbot/api/ipv4.list` 2>/dev/null 40 | ipv6_urllist=`cat /usr/bin/pushbot/api/ipv6.list` 2>/dev/null 41 | [ -z "$pushbot_ipv4" ] && pushbot_ipv4=0 42 | [ -z "$pushbot_ipv6" ] && pushbot_ipv6=0 43 | [ "$iw_version" ] && wlan_interface=`iw dev|grep Interface|awk '{print $2}'` >/dev/null 2>&1 44 | [ -z "$up_timeout" ] || [ "$up_timeout" -eq "0" ] && up_timeout="2" 45 | [ -z "$down_timeout" ] || [ "$down_timeout" -eq "0" ] && down_timeout="20";down_timeout=`expr ${down_timeout} / 2 + 1` 46 | [ -z "$timeout_retry_count" ] && timeout_retry_count="2";[ "$timeout_retry_count" -eq "0" ] && timeout_retry_count="1" 47 | [ ! -z "$bark_token" ] && [ -z "$bark_srv" ] && bark_srv="https://api.day.app" 48 | [ ! -z "$pushdeer_key" ] && [ -z "$pushdeer_srv" ] && pushdeer_srv="https://api2.pushdeer.com" 49 | 50 | # 字符串读取 51 | str_title_start=`/usr/bin/jq -r '.str_title_start' ${jsonpath}` 52 | str_title_end=`/usr/bin/jq -r '.str_title_end' ${jsonpath}` 53 | str_linefeed=`/usr/bin/jq -r '.str_linefeed' ${jsonpath}` 54 | str_splitline=`/usr/bin/jq -r '.str_splitline' ${jsonpath}` 55 | str_space=`/usr/bin/jq -r '.str_space' ${jsonpath}` 56 | str_tab=`/usr/bin/jq -r '.str_tab' ${jsonpath}` 57 | font_red=`/usr/bin/jq -r '.font_red' ${jsonpath}` 58 | font_green=`/usr/bin/jq -r '.font_green' ${jsonpath}` 59 | font_green2=`/usr/bin/jq -r '.font_green2' ${jsonpath}` 60 | font_blue=`/usr/bin/jq -r '.font_blue' ${jsonpath}` 61 | font_purple=`/usr/bin/jq -r '.font_purple' ${jsonpath}` 62 | font_end=`/usr/bin/jq -r '.font_end' ${jsonpath}` 63 | font_end2=`/usr/bin/jq -r '.font_end2' ${jsonpath}` 64 | percentsym=`/usr/bin/jq -r '.percentsym' ${jsonpath}` 65 | boldstar=`/usr/bin/jq -r '.boldstar' ${jsonpath}` 66 | table_tab=`/usr/bin/jq -r '.tabletab' ${jsonpath}` 67 | ( echo "$lite_enable"|grep -q "content" ) && str_title_start="" && str_title_end="" && str_splitline="" && str_linefeed="" && str_tab="" 68 | } 69 | 70 | 71 | 72 | # 初始化 73 | function pushbot_init(){ 74 | enable_detection 75 | if [ -f "/usr/bin/pushbot/errlog" ]; then 76 | cat /usr/bin/pushbot/errlog > ${logfile} 77 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】载入上次重启前日志" >> ${logfile} 78 | echo "--------------------------------------------------------" >> ${logfile} 79 | fi 80 | down_oui & 81 | deltemp 82 | get_syslog 83 | add_ip_black 84 | 85 | 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 86 | [ ! -f "/usr/sbin/wrtbwmon" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】未安装 wrtbwmon ,流量统计不可用" >> ${logfile} 87 | [ -z "$ip_version" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】无法获取依赖项 iputils-arping 版本号,请确认插件是否正常运行" >> ${logfile} 88 | [ -z "$cu_version" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】无法获取依赖项 curl 版本号,请确认插件是否正常运行" >> ${logfile} 89 | [ -z "${dd_webhook}${pp_token}${we_webhook}${fs_webhook}${bark_token}${pushdeer_key}" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】请填写正确的Token/Webhook " >> ${logfile} && return 1 90 | local interfacelist=`getinterfacelist` && [ -z "$interfacelist" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】无法正确获取接口信息,请确认插件是否正常运行" >> ${logfile} 91 | return 0 92 | } 93 | 94 | # 推送 95 | function diy_send(){ 96 | ( ! echo "$lite_enable"|grep -q "content" ) && ( ! echo "$lite_enable"|grep -q "nowtime" ) && local nowtime=`date "+%Y-%m-%d %H:%M:%S"` 97 | local diyurl=`/usr/bin/jq -r .url ${3}` && local diyurl=`eval echo ${diyurl}` 98 | local type=`/usr/bin/jq -r '.type' ${3}` && local type=`eval echo ${type}` 99 | local data=`/usr/bin/jq -r '.data' ${3}` && local data=`eval echo ${data}` 100 | local content_type=`/usr/bin/jq -r '.content_type' ${3}` 101 | /usr/bin/jq ".type + $type" ${jsonpath} > ${tempjsonpath} 102 | /usr/bin/jq -r '.[]' ${tempjsonpath}|grep -w "null" && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】参数值错误,请检查设置项 `/usr/bin/jq -r '.' ${tempjsonpath}|grep "null"`" >> ${logfile} && return 1 103 | [ -f ${tempjsonpath} ] && local logrow=$(grep -c "" ${tempjsonpath}) || local logrow="0" 104 | [ $logrow -eq "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】json 文件生成失败,请检查文件格式" >> ${logfile} && return 1 105 | /usr/bin/jq -r '.[]' ${tempjsonpath}|grep "null" && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】参数变量生成失败,请检查设置项 `/usr/bin/jq -r '.' ${tempjsonpath}|grep "null"`" >> ${logfile} 106 | 107 | curl -X POST -H "$content_type" -d "${data}" "${diyurl}" 108 | } 109 | 110 | # 下载设备MAC厂商信息 111 | function down_oui(){ 112 | [ -f ${oui_base} ] && local logrow=$(grep -c "" ${oui_base}) || local logrow="0" 113 | [ $logrow -lt "10" ] && rm -f ${oui_base} >/dev/null 2>&1 114 | if [ ! -z "$oui_data" ] && [ "$oui_data" -ne "3" ] && [ ! -f ${oui_base} ]; then 115 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】设备MAC厂商信息不存在,重新下载" >> ${logfile} 116 | wget --no-check-certificate -t 3 -T 15 -O ${dir}oui.txt https://standards-oui.ieee.org/oui/oui.txt >/dev/null 2>&1 117 | if [ -f ${dir}oui.txt ] && [ "$oui_data" -eq "1" ]; then 118 | 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\|\ 119 | fiberhome\|fujitsu\|grentech\|h3c\|hisense\|hiwifi\|honghai\|honghao\|hp\|htc\|huawei\|intel\|jinli\|jse\|lenovo\|lg\|liteon\|malata\|meizu\|mercury\|meru\|moto\|netcore\|\ 120 | netgear\|nokia\|omron\|oneplus\|oppo\|philips\|router_unkown\|samsung\|shanzhai\|sony\|start_net\|sunyuanda\|tcl\|tenda\|texas\|tianyu\|tp-link\|ubq\|undefine\|VMware\|\ 121 | 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} 122 | fi 123 | if [ -f ${dir}oui.txt ] && [ "$oui_data" -eq "2" ]; then 124 | 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} 125 | fi 126 | rm -f ${dir}oui.txt >/dev/null 2>&1 127 | fi 128 | } 129 | 130 | # 清理临时文件 131 | function deltemp(){ 132 | unset title content ipAddress_logrow online_list online_mac mac_online_status 133 | rm -f ${dir}title ${dir}content ${dir}tmp_downlist ${dir}send_enable.lock ${tempjsonpath} >/dev/null 2>&1 134 | LockFile unlock 135 | [ -f ${logfile} ] && local logrow=$(grep -c "" ${logfile}) || local logrow="0" 136 | [ $logrow -gt 500 ] && sed -i '1,100d' ${logfile} && echo "`date "+%Y-%m-%d %H:%M:%S"` 【清理】日志超出上限,删除前 100 条" >> ${logfile} 137 | } 138 | 139 | # 检测程序开关 140 | function enable_detection(){ 141 | [ ! "$1" ] && local time_n=1 142 | for i in `seq 1 $time_n`; do 143 | get_config pushbot_enable;[ -z "$pushbot_enable" ] || [ "$pushbot_enable" -eq "0" ] && `/etc/init.d/pushbot stop` || sleep 1 144 | done 145 | } 146 | 147 | # 获取 ip 148 | function getip(){ 149 | [ ! "$1" ] && return 150 | if [ $1 == "wanipv4" ] ;then 151 | [ ! -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}') 152 | [ -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}') 153 | echo "$wanIP" 154 | elif [ $1 == "hostipv4" ] ;then 155 | function get_hostipv4() 156 | { 157 | local url_number=`echo "$ipv4_urllist"|wc -l` 158 | local ipv4_URL=`echo "$ipv4_urllist"| sed -n "$(rand 1 $url_number)p"|sed -e 's/\r//g'` 159 | [ ! -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}) 160 | echo $hostIP|grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'|head -n1 161 | } 162 | local hostIP=`get_hostipv4` 163 | [ -z "$hostIP" ] && local hostIP=`get_hostipv4` 164 | [ -z "$hostIP" ] && local hostIP=`get_hostipv4` 165 | echo $hostIP # 重试,偷懒,有空再优化 166 | elif [ $1 == "wanipv6" ] ;then 167 | [ ! -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}') 168 | [ -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}') 169 | echo "$wanIPv6" 170 | elif [ $1 == "hostipv6" ] ;then 171 | function get_hostipv6() 172 | { 173 | local urlv6_number=`echo "$ipv6_urllist"|wc -l` 174 | local ipv6_URL=`echo "$ipv6_urllist"| sed -n "$(rand 1 $urlv6_number)p"|sed -e 's/\r//g'` 175 | [ ! -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}) 176 | echo $hostIPv6|grep -oE '([\da-fA-F0-9]{1,4}(:{1,2})){1,15}[\da-fA-F0-9]{1,4}'|head -n1 177 | } 178 | local hostIPv6=`get_hostipv6` 179 | [ -z "$hostIPv6" ] && local hostIPv6=`get_hostipv6` 180 | [ -z "$hostIPv6" ] && local hostIPv6=`get_hostipv6` 181 | echo $hostIPv6 # 重试,偷懒,有空再优化 182 | fi 183 | } 184 | 185 | # 获取接口信息 186 | function getinterfacelist(){ 187 | [ `ubus list|grep -w -i "network.interface.wan"|wc -l` -ge "1" ] && ubus call network.interface.wan status && return 188 | [ `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 189 | } 190 | 191 | # 获取接口在线时间 192 | function getinterfaceuptime(){ 193 | getinterfacelist|grep \"uptime\"|sed $'s/\"uptime": //g'|sed $'s/\,//g' 194 | } 195 | 196 | # 查询 mac 地址 197 | function getmac(){ 198 | ( echo "$tmp_mac"|grep -q "unknown" ) && unset tmp_mac # 为unknown时重新读取 199 | [ -f "${dir}ipAddress" ] && [ -z "$tmp_mac" ] && local tmp_mac=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $2}'|grep -v "^$"|sort -u|head -n1` 200 | [ -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` 201 | [ -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` 202 | [ -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` 203 | [ -z "$tmp_mac" ] && local tmp_mac="unknown" 204 | echo "$tmp_mac" 205 | } 206 | 207 | # 查询主机名 208 | function getname(){ 209 | [ -z "$tmp_name" ] && local tmp_name=`echo "$device_aliases"|grep -i $2|awk '{print $2}'|grep -v "^$"|sort -u|head -n1` 210 | [ -f "${dir}ipAddress" ] && [ -z "$tmp_name" ] && local tmp_name=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $3}'|grep -v "^$"|sort -u|head -n1` 211 | [ -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` 212 | ( ! echo "$tmp_name"|grep -q -w "unknown\|*" ) && [ ! -z "$tmp_name" ] && echo "$tmp_name" && return || unset tmp_name # 为unknown时重新读取 213 | [ -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` 214 | ( ! echo "$tmp_name"|grep -q -w "unknown\|*" ) && [ ! -z "$tmp_name" ] && echo "$tmp_name" && return || unset tmp_name # 为unknown时重新读取 215 | [ -z "$dhcp_config" ] && dhcp_config=`uci show dhcp|grep "ip\|mac\|name"` 216 | for dhcp_config_str in "host" "domain"; do 217 | 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 218 | [ ! -z "$dhcp_ip_n" ] && [ -z "$tmp_name" ] && local tmp_name=`uci get dhcp.${dhcp_ip_n}.name` 2>/dev/null 219 | 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 220 | [ ! -z "$dhcp_mac_n" ] && [ -z "$tmp_name" ] && local tmp_name=`uci get dhcp.${dhcp_ip_n}.name` 2>/dev/null 221 | [ ! -z "$tmp_name" ] && break 222 | done 223 | ( ! echo "$tmp_name"|grep -q -w "unknown\|*" ) && [ ! -z "$tmp_name" ] && echo "$tmp_name" && return || unset tmp_name # 为unknown时重新读取 224 | [ -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') 225 | [ ! -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'|sed 's/ /_/g') 226 | [ -z "$tmp_name" ] && local tmp_name="unknown" 227 | echo "$tmp_name" 228 | } 229 | 230 | # 查询设备接口 231 | function getinterface(){ 232 | [ -f "${dir}ipAddress" ] && local ip_interface=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $5}'|grep -v "^$"|sort -u|head -n1` 233 | [ -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` 234 | if [ -z "$ip_interface" ] && [ ! -z "$wlan_interface" ]; then 235 | for interface in $wlan_interface; do 236 | 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 237 | [ ! -z "$ip_interface" ] && echo "$ip_interface" && return 238 | done 239 | fi 240 | [ -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` 241 | echo "$ip_interface" 242 | } 243 | 244 | # ping 245 | function getping(){ 246 | [ "$iw_version" ] && local wlan_online=`iw dev ${ip_interface} station dump|grep -i -w ${ip_mac}|grep Station` >/dev/null 2>&1 247 | [ "$wlan_online" ] && return 0 248 | for i in `seq 1 ${3}`; do 249 | ( ! 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 250 | ( ! echo "$ip_ms"|grep -q "ms" ) && local ip_ms=`ping -c 5 -w ${2} ${1}|grep -v '100% packet loss'` 2>/dev/null 251 | ( ! echo "$ip_ms"|grep -q "ms" ) && sleep 1 252 | done 253 | ( echo "$ip_ms"|grep -q "ms" ) 254 | } 255 | 256 | # CPU 占用率 257 | function getcpu(){ 258 | local AT=$(cat /proc/stat|grep "^cpu "|awk '{print $2+$3+$4+$5+$6+$7+$8 " " $2+$3+$4+$7+$8}') 259 | sleep 3 260 | local BT=$(cat /proc/stat|grep "^cpu "|awk '{print $2+$3+$4+$5+$6+$7+$8 " " $2+$3+$4+$7+$8}') 261 | printf "%.01f%%" $(echo ${AT} ${BT}|awk '{print (($4-$2)/($3-$1))*100}') 262 | } 263 | 264 | # 获取SOC温度 (取所有传感器温度最大值) 265 | function soc_temp(){ 266 | [ -z "$soc_code" ] && local soctemp=`sensors 2>/dev/null|grep °C|sed -nr 's#^.*:.*\+(.*)°C .*#\1#gp'|sort -nr|head -n1` 267 | [ -z "$soc_code" ] && [ -z "$soctemp" ] && local soctemp=`cat /sys/class/thermal/thermal_zone*/temp 2>/dev/null|sort -nr|head -n1|cut -c-2` 268 | [ "$soc_code" == "pve" ] && [ ! -z "$pve_host" ] && local soctemp=`ssh -i ~/.ssh/id_rsa root@${pve_host} -p ${pve_port} sensors 2>/dev/null|grep °C|sed -nr 's#^.*:.*\+(.*)°C .*#\1#gp'|sort -nr|head -n1` 269 | [ ! -z "$soctemp" ] && echo "$soctemp" && return 270 | [ ! -z "$soc_code" ] && eval `echo "$soc_code"` 2>/dev/null 271 | } 272 | 273 | # 流量数据 274 | function usage(){ 275 | [ ! -f "/usr/sbin/wrtbwmon" ] || [ ! "$1" ] && return 276 | if [ $1 == "update" ] ;then 277 | function version_le() { test "$(echo "$@"|tr " " "\n"|sort -n|head -n 1)" == "$1"; } 278 | function version_ge() { test "$(echo "$@"|tr " " "\n"|sort -r|head -n 1)" == "$1"; } 279 | [ ! -z "$wr_version" ] && ( version_ge "${wr_version}" "1.2.0" ) && wrtbwmon -f ${dir}usage.db 2>/dev/null && return 280 | [ ! -z "$wr_version" ] && ( version_le "${wr_version}" "1.0.0" ) || [ -z "$wr_version" ] && wrtbwmon update ${dir}usage.db 2>/dev/null && return 281 | elif [ $1 == "get" ] ;then 282 | [ ! -f "${dir}usage.db" ] && [ ! "$3" ] && echo `bytes_for_humans 0` && return 283 | [ ! -f "${dir}usage.db" ] && [ "$3" ] && echo 0 && return 284 | [ -z "$total_n" ] && total_n=`cat ${dir}usage.db|head -n1|grep "total"|sed 's/,/\n/g'|awk '/total/{print NR}'` 2>/dev/null 285 | [ -z "$total_n" ] && total_n="6" 286 | [ "$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 287 | [ -z "$tmptotal" ] && local tmptotal="0" 288 | [ ! "$3" ] && echo `bytes_for_humans ${tmptotal}` || echo "$tmptotal" 289 | elif [ $1 == "down" ] ;then 290 | [ "$2" ] && sed -i "/,${2},/d" ${dir}usage.db 2>/dev/null 291 | fi 292 | } 293 | 294 | # 流量数据单位换算 295 | function bytes_for_humans { 296 | [ ! "$1" ] && return 297 | [ "$1" -gt 1073741824 ] && echo "`awk 'BEGIN{printf "%.2f\n",'$1'/'1073741824'}'` G" && return 298 | [ "$1" -gt 1048576 ] && echo "`awk 'BEGIN{printf "%.2f\n",'$1'/'1048576'}'` M" && return 299 | [ "$1" -gt 1024 ] && echo "`awk 'BEGIN{printf "%.2f\n",'$1'/'1024'}'` K" && return 300 | echo "${1} bytes" 301 | } 302 | 303 | # 设备异常流量检测 304 | function get_client_usage(){ 305 | [ -z "$client_usage" ] && return 306 | [ "$client_usage" -ne "1" ] && return 307 | [ -z "$client_usage_max" ] && return 308 | [ -z "$get_client_usage_time" ] && get_client_usage_time=`date +%s` 309 | ( echo $client_usage_max|sed -r 's/.*(.)$/\1/'|grep -q "K\|k" ) && client_usage_max=`expr ${client_usage_max%?} \* 1024` 310 | ( echo $client_usage_max|sed -r 's/.*(.)$/\1/'|grep -q "M\|m" ) && client_usage_max=`expr ${client_usage_max%?} \* 1048576` 311 | ( echo $client_usage_max|sed -r 's/.*(.)$/\1/'|grep -q "G\|g" ) && client_usage_max=`expr ${client_usage_max%?} \* 1073741824` 312 | [ -z "$client_usage_disturb" ] && client_usage_disturb="0" 313 | [ "$client_usage_disturb" -eq "0" ] && [ -f "${dir}ipAddress" ] && local MACLIST=`cat ${dir}ipAddress|awk '{print $2}'|grep -v "^$"|sort -u` 314 | [ "$client_usage_disturb" -eq "1" ] && [ ! -z "$client_usage_whitelist" ] && local MACLIST=`echo "$client_usage_whitelist"` 315 | [ -z "$MACLIST" ] && return 316 | 317 | if [ "$((`date +%s`-$get_client_usage_time))" -ge "60" ]; then 318 | > ${dir}client_usage_aliases 319 | for mac in $MACLIST; do 320 | ( ! cat ${dir}ipAddress|grep -q -i -w $mac|grep -v "^$"|sort -u|head -n1 ) && continue 321 | echo "$mac" `usage get ${mac} bytes` >> ${dir}client_usage_aliases 322 | [ -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 323 | [ -z "$get_client_usage_bytes" ] && get_client_usage_bytes="0" 324 | if [ "$((`usage get ${mac} bytes`-$get_client_usage_bytes))" -ge "$client_usage_max" ]; then 325 | local ip=`cat ${dir}ipAddress|grep -i -w $mac|awk '{print $1}'|grep -v "^$"|sort -u|head -n1` 326 | local ip_name=`getname ${ip} ${mac}` 327 | local tmp_usage=$(bytes_for_humans $(expr `usage get ${mac} bytes` - ${get_client_usage_bytes})) 328 | local time_up=`cat ${dir}ipAddress|grep -w ${ip}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1` 329 | 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}" 330 | local time1=`date +%s` 331 | local time1=$(time_for_humans `expr ${time1} - ${time_up}`) 332 | if [ -z "$title" ]; then 333 | title="${ip_name} 流量异常" 334 | content="${content}${str_splitline}${str_title_start}${font_red} 设备流量异常${font_end}${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}" 335 | elif ( echo "$title"|grep -q "流量异常" ); then 336 | title="${ip_name} ${title}" 337 | 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}" 338 | else 339 | title="设备状态变化" 340 | content="${content}${str_splitline}${str_title_start}${font_red} 设备流量异常${font_end}${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}" 341 | fi 342 | fi 343 | done 344 | cat ${dir}client_usage_aliases > ${dir}old_client_usage_aliases 345 | get_client_usage_time=`date +%s` 346 | fi 347 | } 348 | 349 | # 时间单位换算 350 | function time_for_humans { 351 | [ ! "$1" ] && return 352 | if [ "$1" -lt 60 ]; then 353 | echo "${1} 秒" 354 | elif [ "$1" -lt 3600 ]; then 355 | local usetime_min=`expr $1 / 60` 356 | local usetime_sec=`expr $usetime_min \* 60` 357 | local usetime_sec=`expr $1 - $usetime_sec` 358 | echo "${usetime_min} 分 ${usetime_sec} 秒" 359 | elif [ "$1" -lt 86400 ]; then 360 | local usetime_hour=`expr $1 / 3600` 361 | local usetime_min=`expr $usetime_hour \* 3600` 362 | local usetime_min=`expr $1 - $usetime_min` 363 | local usetime_min=`expr $usetime_min / 60` 364 | echo "${usetime_hour} 小时 ${usetime_min} 分" 365 | else 366 | local usetime_day=`expr $1 / 86400` 367 | local usetime_hour=`expr $usetime_day \* 86400` 368 | local usetime_hour=`expr $1 - $usetime_hour` 369 | local usetime_hour=`expr $usetime_hour / 3600` 370 | echo "${usetime_day} 天 ${usetime_hour} 小时" 371 | fi 372 | } 373 | 374 | # 计算字符真实长度 375 | function length_str { 376 | [ ! "$1" ] && return 377 | local length_zh=`echo "$1"|awk '{print gensub(/[\u4e00-\u9FA5A-Za-z0-9_]/,"","g",$0)}'|awk -F "" '{print NF}'` 378 | local length_en=`echo "$1"|awk '{print gensub(/[^\u4e00-\u9FA5A-Za-z0-9_]/,"","g",$0)}'|awk -F "" '{print NF}'` 379 | echo `expr $length_zh / 3 \* 2 + $length_en` 380 | } 381 | 382 | # 截取字符,避免中文乱码 383 | function cut_str { 384 | [ ! "$1" ] && return 385 | [ ! "$2" ] && return 386 | [ `length_str $1` -le "$2" ] && echo "$1" && return 387 | local temp_length=$2 388 | while [ $(length_str `echo "$1"|cut -c -$temp_length`) -lt "$2" ]; do 389 | temp_length=`expr $temp_length + 1` 390 | done 391 | while [ $(printf "%d" \'`echo "$1"|cut -c $temp_length`) -ge "128" ] && [ $(printf "%d" \'`echo "$1"|cut -c $temp_length`) -lt "224" ]; do 392 | temp_length=`expr $temp_length + 1` 393 | done 394 | temp_length=`expr $temp_length - 1` 395 | echo $(echo "$1"|cut -c -$temp_length)"..." 396 | } 397 | 398 | # 随机数 399 | function rand(){ 400 | local min=$1 401 | local max=$(($2- $min + 1)) 402 | local num=$(date +%s%N) 403 | echo $(($num % $max + $min)) 404 | } 405 | 406 | # 在线设备列表 407 | function pushbot_first(){ 408 | [ -f "${dir}ipAddress" ] && local IPLIST=`cat ${dir}ipAddress|awk '{print $1}'|grep -v "^$"|sort -u` 409 | for ip in $IPLIST; do 410 | read -u 5 411 | { 412 | down $ip 413 | echo "" >&5 414 | }& 415 | done 416 | wait 417 | unset ip IPLIST 418 | 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}'` 419 | for ip in $IPLIST; do 420 | read -u 5 421 | { 422 | up $ip 423 | echo "" >&5 424 | }& 425 | done 426 | wait 427 | } 428 | # 创建计划任务 429 | function pushbot_cron(){ 430 | function del_cron(){ 431 | ( 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 432 | } 433 | function re_cron(){ 434 | /etc/init.d/cron stop 435 | /etc/init.d/cron start 436 | } 437 | del_cron 438 | if [ -z "$pushbot_enable" ]; then 439 | re_cron 440 | return 441 | fi 442 | 443 | # 重置流量 444 | if [ ! -z "$reset_regularly" ] && [ "$reset_regularly" -eq "1" ]; then 445 | 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 446 | 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 447 | fi 448 | [ ! -z "$regular_time_2" ] && local regular_time_2=",${regular_time_2}" 449 | [ ! -z "$regular_time_3" ] && local regular_time_3=",${regular_time_3}" 450 | # 定时发送 451 | if [ ! -z "$regular_time" ] || [ ! -z "$regular_time_2" ] || [ ! -z "$regular_time_3" ]; then 452 | 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 453 | # 间隔发送 454 | elif [ ! -z "$interval_time" ]; then 455 | 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 456 | fi 457 | re_cron 458 | } 459 | 460 | # 免打扰检测 461 | function pushbot_disturb(){ 462 | [ -z "$pushbot_sheep" ] || [ -z "$starttime" ] || [ -z "$endtime" ] && return 0 463 | 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 464 | unset sheep_starttime 465 | rm -f ${dir}sheep_usage ${dir}old_sheep_usage 2>/dev/null 466 | disturb_text=`/usr/bin/jq -r '._api' ${jsonpath}` 467 | return 0 468 | else 469 | [ -z "$sheep_starttime" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【免打扰】夜深了,该休息了" >> ${logfile} && sheep_starttime=`date +%s` 470 | if [ "$pushbot_sheep" -eq "1" ] ;then 471 | while [ `date +%H` -lt "$endtime" ]; do 472 | enable_detection 473 | sleep $sleeptime 474 | done 475 | elif [ "$pushbot_sheep" -eq "2" ] ;then 476 | disturb_text="【免打扰】" 477 | return 1 478 | fi 479 | fi 480 | } 481 | 482 | # 文件锁 483 | function LockFile(){ 484 | if [ $1 = "lock" ] ;then 485 | [ ! -f "${dir}pushbot.lock" ] && > ${dir}pushbot.lock && return 486 | while [ -f "${dir}pushbot.lock" ]; do 487 | enable_detection 1 488 | done 489 | LockFile lock 490 | fi 491 | [ $1 = "unlock" ] && rm -f ${dir}pushbot.lock >/dev/null 2>&1 492 | return 0 493 | } 494 | 495 | # 检测黑白名单 496 | function blackwhitelist(){ 497 | [ ! "$1" ] && return 1 498 | [ -z "$pushbot_whitelist" ] && [ -z "$pushbot_blacklist" ] && [ -z "$pushbot_interface" ] && [ -z "$MAC_online_list" ] && [ -z "$MAC_offline_list" ] && return 0 499 | [ ! -z "$pushbot_whitelist" ] && ( echo "$pushbot_whitelist"|grep -q -i -w $1 ) && return 1 500 | [ ! -z "$pushbot_blacklist" ] && ( ! echo "$pushbot_blacklist"|grep -q -i -w $1 ) && return 1 501 | [ ! -z "$pushbot_interface" ] && ( ! echo `getinterface ${1}`|grep -q -i -w $pushbot_interface ) && return 1 502 | [ ! -z "$MAC_online_list" ] && [ ! -z "$mac_online_status" ] && return 1 503 | [ ! -z "$MAC_online_list" ] && ( echo "$MAC_online_list"|grep -q -i -w $1 ) && return 1 504 | [ ! -z "$MAC_offline_list" ] && [ -z "$mac_online_status" ] && return 1 505 | return 0 506 | } 507 | 508 | function get_client(){ 509 | if [ -f "${dir}ipAddress" ]; then 510 | while read line; do 511 | local js_str="${js_str}
" 512 | local js_str="${js_str}
<%:`echo "$line"|awk '{print $3}'`%>
" 513 | local tmp_mac=`echo "$line"|awk '{print $2}'` 514 | local js_str="${js_str}
<%:${tmp_mac}%>
" 515 | local js_str="${js_str}
<%:`echo "$line"|awk '{print $1}'`%>
" 516 | local tmp_usage=`usage get ${tmp_mac}` 517 | local js_str="${js_str}
<%:${tmp_usage}%>
" 518 | local tmp_uptime=`echo "$line"|awk '{print $4}'` 519 | local tmp_timenow=`date +%s` 520 | local tmp_uptime=$(time_for_humans `expr ${tmp_timenow} - ${tmp_uptime}`) 521 | local js_str="${js_str}
<%:${tmp_uptime}%>
" 522 | done < ${dir}ipAddress 523 | fi 524 | cat>/usr/lib/lua/luci/view/pushbot/pushbot_client.htm<<%:在线设备列表%>
<%:客户端名%>
<%:MAC%>
<%:IP%>
<%:总计流量%>
<%:在线时间%>
526 | $js_str 527 |
528 | EOF 529 | } 530 | 531 | # 重启网络服务 532 | function network_restart(){ 533 | cat>${dir}network_restart</dev/null 2>&1 & 536 | /etc/init.d/firewall restart >/dev/null 2>&1 & 537 | /etc/init.d/dnsmasq restart >/dev/null 2>&1 & 538 | EOF 539 | chmod 0755 ${dir}network_restart && ${dir}network_restart 540 | rm -f ${dir}network_restart >/dev/null 2>&1 541 | } 542 | 543 | # 查看无人值守任务设备是否在线 544 | function geterrdevicealiases(){ 545 | [ -z "$err_device_aliases" ] && return 546 | [ -f ${dir}ipAddress ] && local logrow=$(grep -c "" ${dir}ipAddress) || local logrow="0";[ $logrow -eq "0" ] && return 547 | local MACLIST=`cat ${dir}ipAddress|awk '{print $2}'|grep -v "^$"|sort -u` 548 | for mac in $MACLIST; do 549 | [ -z "$err_mac" ] && [ ! -z "$mac" ] && local err_mac=`echo "$err_device_aliases"|grep -i $mac|grep -v "^$"|sort -u|head -n1` 550 | done 551 | # 进入免打扰时间已经超过一小时 552 | if [ ! -z "$sheep_starttime" ] && [ "$((`date +%s`-$sheep_starttime))" -ge "3600" ]; then 553 | > ${dir}sheep_usage 554 | local MACLIST=`echo "$err_device_aliases"|grep -v "^$"|sort -u` 555 | for mac in $MACLIST; do 556 | [ ! -z "$mac" ] && local tmptotal=`usage get ${mac} bytes` 557 | [ ! -z "$tmptotal" ] && awk 'BEGIN{printf "%.0f\n",'$tmptotal'/'204800'}' 2>/dev/null >> ${dir}sheep_usage 558 | done 559 | old_sheep_usage=`cat ${dir}old_sheep_usage` 2>/dev/null 560 | sheep_usage=`cat ${dir}sheep_usage` 2>/dev/null 561 | [ "$old_sheep_usage" == "$sheep_usage" ] && [ -z "$sheep_nousage_starttime" ] && sheep_nousage_starttime=`date +%s` 562 | [ "$old_sheep_usage" != "$sheep_usage" ] && unset sheep_nousage_starttime && cat ${dir}sheep_usage 2>/dev/null > ${dir}old_sheep_usage 563 | [ ! -z "$sheep_nousage_starttime" ] && [ "$((`date +%s`-$sheep_nousage_starttime))" -ge "300" ] && unset err_mac 564 | fi 565 | [ -z "$err_mac" ] 566 | } 567 | 568 | # 无人值守任务 569 | function unattended(){ 570 | [ -z "$err_enable" ] || [ "$err_enable" -ne "1" ] && return 571 | [ ! -z "$err_sheep_enable" ] && [ "$err_sheep_enable" -eq "1" ] && [ -z "$sheep_starttime" ] && return 572 | geterrdevicealiases;[ $? -eq "1" ] && return 573 | 574 | if [ ! -z "$system_time_event" ]; then 575 | local interfaceuptime=`getinterfaceuptime` 576 | 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 577 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【无人值守任务】重启路由器咯" >> ${logfile} 578 | cat ${logfile} > /usr/bin/pushbot/errlog 579 | sleep 2 && reboot && exit 580 | 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 581 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【无人值守任务】重新拨号咯" >> ${logfile} 582 | ifup wan >/dev/null 2>&1 583 | sleep 60 584 | fi 585 | fi 586 | 587 | [ -z "$public_ip_today" ] && public_ip_today=`date +"%d"` 588 | [ -z "$public_ip_count" ] && public_ip_count="0" 589 | [ $public_ip_today -ne `date +"%d"` ] && public_ip_today=`date +"%d"` && public_ip_count=1 590 | if [ ! -z "$public_ip_event" ] && [ ! -z "$public_ip_retry_count" ] && [ "$public_ip_count" -le "$public_ip_retry_count" ]; then 591 | public_ip_count=`expr $public_ip_count + 1` 592 | local wanIP=`getip wanipv4` 593 | local hostIP=`getip hostipv4` 594 | if [ ! -z "$wanIP" ] && [ ! -z "$hostIP" ] && ( ! echo "$wanIP"|grep -q -w ${hostIP} );then 595 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【无人值守任务】重拨尝试获取公网 ip,当前第 $public_ip_count 次 " >> ${logfile} 596 | ifup wan >/dev/null 2>&1 597 | sleep 60 598 | local wanIP=`getip wanipv4` && local hostIP=`getip hostipv4` 599 | [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -eq "1" ] && local IPv4=${wanIP} 600 | [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -eq "2" ] && local IPv4=${hostIP} 601 | [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -eq "1" ] && local IPv6=`getip wanipv6` 602 | [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -eq "2" ] && local IPv6=`getip hostipv6` 603 | [ ! -z "$wanIP" ] && [ ! -z "$hostIP" ] && ( ! echo "$wanIP"|grep -q -w ${hostIP} ) && echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $last_IPv6 >> ${dir}ip 604 | fi 605 | fi 606 | } 607 | 608 | # 检测网络状态 609 | function rand_geturl(){ 610 | function getcheck(){ 611 | local urllist="https://www.163.com https://www.qq.com https://www.baidu.com https://www.qidian.com https://www.douban.com" 612 | local url_number=`expr $(echo "$urllist"|grep -o ' '|wc -l) + 1` 613 | local url_str=`echo "$urllist"|awk -v i=$(rand 1 $url_number) '{print $i}'` 614 | 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` 615 | } 616 | local check=`getcheck` 617 | while [ -z "$check" ] || [ "$check" -ne "200" ]; do 618 | local check=`getcheck` 619 | if [ ! -z "$check" ] && [ "$check" -eq "200" ]; then 620 | [ ! -z "$network_enable" ] && [ "$network_enable" -eq "404" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【网络状态】网络恢复正常.." >> ${logfile} 621 | local network_enable="200" 622 | else 623 | [ -z "$network_enable" ] || [ "$network_enable" -eq "200" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】当前网络不通!停止检测! " >> ${logfile} 624 | local network_enable="404" 625 | [ -z "$network_err_time" ] && network_err_time=`date +%s` 626 | if [ ! -z "$network_err_event" ] && [ "$((`date +%s`-$network_err_time))" -ge "600" ]; then 627 | > ${dir}send_enable.lock && pushbot_first && deltemp 628 | geterrdevicealiases 629 | if [ "$?" -eq "0" ]; then 630 | [ -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 631 | [ ! -z ${retry_count} ] && retry_count=0;retry_count=`expr $retry_count + 1` 632 | if [ "$network_err_event" -eq "1" ] ;then 633 | if [ "$retry_count" -lt "3" ] ;then 634 | echo "$retry_count" > /usr/bin/pushbot/autoreboot_count 635 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】正在尝试重启路由,当前第 $retry_count 次 " >> ${logfile} 636 | cat ${logfile} > /usr/bin/pushbot/errlog 637 | sleep 2 && reboot && exit 638 | fi 639 | [ "$retry_count" -eq "3" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】已经重启路由2次,修复失败,请主人自行修复哦" >> ${logfile} 640 | elif [ "$network_err_event" -eq "2" ] ;then 641 | [ "$retry_count" -lt "3" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】正在尝试重启网络,当前第 $retry_count 次 " >> ${logfile} && ifup wan >/dev/null 2>&1 642 | [ "$retry_count" -eq "3" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】已经重启网络2次,修复失败,请主人自行修复哦 " >> ${logfile} 643 | elif [ "$network_err_event" -eq "3" ] ;then 644 | if [ "$retry_count" -eq "1" ] ;then 645 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】正在尝试修复网络,当前第 1 次,重启网络服务中 " >> ${logfile} && network_restart 646 | elif [ "$retry_count" -eq "2" ] ;then 647 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】正在尝试修复网络,当前第 2 次,关闭可能造成网络断开的软件" >> ${logfile} 648 | [ `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 649 | [ `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 650 | [ `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 651 | local shadowsocksr_enabled=`uci get shadowsocksr.@global[0].global_server 2>/dev/null|grep nil` 652 | local shadowsocksr_run_mode=`uci get shadowsocksr.@global[0].run_mode 2>/dev/null|grep all` 653 | [ -z "$shadowsocksr_enabled" ] && [ ! -z "$shadowsocksr_run_mode" ] && /etc/init.d/shadowsocksr stop >/dev/null 2>&1 654 | sleep 60 && network_restart 655 | elif [ "$retry_count" -eq "3" ] ;then 656 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】正在尝试修复网络,当前第 3 次,备份设置项,并修改相关设置" >> ${logfile} 657 | mkdir -p /usr/bin/pushbot/configbak 658 | cp -p -f /etc/config/network /usr/bin/pushbot/configbak/network 659 | cp -p -f /etc/config/dhcp /usr/bin/pushbot/configbak/dhcp 660 | cp -p -f /etc/config/firewall /usr/bin/pushbot/configbak/firewall 661 | cp -p -f /etc/firewall.user /usr/bin/pushbot/configbak/firewall.user 662 | uci set network.wan.peerdns='0' 663 | uci delete network.wan.dns 664 | uci add_list network.wan.dns='223.5.5.5' 665 | uci add_list network.wan.dns='119.29.29.29' 666 | uci delete network.wan.mtu 667 | uci commit network 668 | uci set dhcp.@dnsmasq[0].port='53' 669 | uci set dhcp.@dnsmasq[0].resolvfile='/tmp/resolv.conf.auto' 670 | uci delete dhcp.@dnsmasq[0].server 671 | uci delete dhcp.@dnsmasq[0].noresolv 672 | uci commit dhcp 673 | uci delete firewall.redirect 674 | >/etc/firewall.user 675 | uci commit firewall 676 | sleep 60 && network_restart 677 | elif [ "$retry_count" -eq "4" ] ;then 678 | echo "$retry_count" > /usr/bin/pushbot/autoreboot_count 679 | cat ${logfile} > /usr/bin/pushbot/errlog 680 | sleep 2 && reboot && exit 681 | elif [ "$retry_count" -eq "5" ] ;then 682 | echo "$retry_count" > /usr/bin/pushbot/autoreboot_count 683 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!!】修复失败,还原设置中,请自行检查网络设置" >> ${logfile} 684 | cp -p -f /usr/bin/pushbot/configbak/network /etc/config/network 685 | cp -p -f /usr/bin/pushbot/configbak/dhcp /etc/config/dhcp 686 | cp -p -f /usr/bin/pushbot/configbak/firewall /etc/config/firewall 687 | cp -p -f /usr/bin/pushbot/configbak/firewall.user /etc/firewall.user 688 | cat ${logfile} > /usr/bin/pushbot/errlog 689 | sleep 2 && reboot && exit 690 | fi 691 | fi 692 | fi 693 | elif [ -f /usr/bin/pushbot/autoreboot_count ]; then 694 | network_err_time=`expr $network_err_time - 600` && sleep 60 695 | fi 696 | enable_detection 697 | sleep $sleeptime 698 | fi 699 | continue 700 | done 701 | rm -f /usr/bin/pushbot/autoreboot_count >/dev/null 2>&1 702 | } 703 | 704 | # 检测 ip 状况 705 | function ip_changes(){ 706 | [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -eq "1" ] && local IPv4=`getip wanipv4` 707 | [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -eq "2" ] && local IPv4=`getip hostipv4` 708 | [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -eq "1" ] && local IPv6=`getip wanipv6` 709 | [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -eq "2" ] && local IPv6=`getip hostipv6` 710 | 711 | if [ -f ${dir}ip ]; then 712 | local last_IPv4=$(cat "${dir}ip"|grep IPv4|awk '{print $2}'|grep -v "^$"|sort -u|head -n1) 713 | local last_IPv6=$(cat "${dir}ip"|grep IPv6|awk '{print $2}'|grep -v "^$"|sort -u|head -n1) 714 | if [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -ne "0" ] && [ ! -z "$IPv4" ] && ( ! echo ${IPv4}|grep -w -q ${last_IPv4} ); then 715 | echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}当前IP:${IPv4}" >> ${logfile} 716 | echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $last_IPv6 >> ${dir}ip 717 | title="IP 地址变化" 718 | content="${content}${str_splitline}${str_title_start}${font_green} IP 地址变化${font_end}${str_title_end}${str_linefeed}${str_tab}当前 IP:${IPv4}" 719 | elif [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -ne "0" ] && [ -z "$IPv4" ]; then 720 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】获取 IPv4 地址失败" >> ${logfile} 721 | fi 722 | 723 | if [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -ne "0" ] && [ ! -z "$IPv6" ] && ( ! echo "$IPv6"|grep -w -q ${last_IPv6} ); then 724 | echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}当前IPv6:${IPv6}" >> ${logfile} 725 | echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $IPv6 >> ${dir}ip 726 | [ -z "$title" ] && title="IPv6 地址变化" 727 | [ ! -z "$title" ] && title="IP 地址变化" 728 | content="${content}${str_splitline}${str_title_start}${font_green} IPv6 地址变化${font_end}${str_title_end}${str_linefeed}${str_tab}当前 IPv6:${IPv6}" 729 | elif [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -ne "0" ] && [ -z "$IPv6" ]; then 730 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】获取 IPv6 地址失败" >> ${logfile} 731 | fi 732 | 733 | else 734 | echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}路由器已经重启!" >> ${logfile} 735 | [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -ne "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 当前IP: ${IPv4}" >> ${logfile} 736 | [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -ne "0" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 当前IPv6: ${IPv6}" >> ${logfile} 737 | echo IPv4 $IPv4 > ${dir}ip && echo -e IPv6 $IPv6 >> ${dir}ip 738 | title="路由器重新启动" 739 | content="${content}${str_splitline}${str_title_start}${font_green} 路由器重新启动${font_end}${str_title_end}" 740 | [ ! -z "$pushbot_ipv4" ] && [ "$pushbot_ipv4" -ne "0" ] && content="${content}${str_linefeed}${str_tab}当前IP:${IPv4}" 741 | [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -ne "0" ] && content="${content}${str_linefeed}${str_tab}当前IPv6:${IPv6}" 742 | fi 743 | 744 | if [ ! -z "$content" ] ;then 745 | [ -z "$ddns_enabled" ] && ddns_enabled=$(uci show ddns|grep "enabled"|grep "1") 746 | [ -z "$ddns_enabled" ] && ddns_logrow=0 || ddns_logrow=$(echo "$ddns_enabled"|wc -l) 747 | if [ $ddns_logrow -ge 1 ]; then 748 | /etc/init.d/ddns restart >/dev/null 2>&1 749 | fi 750 | [ -z "$zerotier_enabled" ] && zerotier_enabled=$(uci get zerotier.sample_config.enabled) 751 | if [ ! -z "$zerotier_enabled" ] && [ $zerotier_enabled -eq "1" ] ; then 752 | /etc/init.d/zerotier restart >/dev/null 2>&1 753 | fi 754 | fi 755 | } 756 | 757 | # 检测设备上线 758 | function up(){ 759 | [ -f ${dir}ipAddress ] && ( cat ${dir}ipAddress|grep -q -w $1 ) && return 760 | local ip_mac=`getmac $1` 761 | local ip_name=`getname ${1} ${ip_mac}` 762 | local ip_interface=`getinterface ${ip_mac}` 763 | getping ${1} ${up_timeout} "1";local ping_online=$? 764 | if [ "$ping_online" -eq "0" ]; then 765 | LockFile lock 766 | [ ! -z "$pushbot_blacklist" ] && local tmp_mac=`echo "${pushbot_blacklist}"|grep -w -i ${ip_mac}` 767 | [ ! -z "$pushbot_whitelist" ] && local tmp_mac=`echo "${pushbot_whitelist}"|grep -w -i ${ip_mac}` 768 | if [ ! -z "$tmp_mac" ] && ( cat ${dir}ipAddress|grep -q -w -i ${tmp_mac} ); then 769 | usage down $1 770 | echo "$1 ${ip_mac} ${ip_name} `date +%s` ${ip_interface}" >> ${dir}ipAddress 771 | LockFile unlock && return 772 | elif [ ! -z "$tmp_mac" ] && [ -f "${dir}tmp_downlist" ] && ( cat ${dir}tmp_downip|grep -q -w -i ${tmp_mac} ); then 773 | local tmp_downip=`cat ${dir}tmp_downlist|grep -w -i ${tmp_mac}|awk '{print $1}'|grep -v "^$"|sort -u|head -n1` 774 | usage down $tmp_downip 775 | sed -i "/^${tmp_downip} /d" ${dir}tmp_downlist 776 | LockFile unlock && return 777 | fi 778 | [ -f "${dir}tmp_downlist" ] && local tmp_downip=`cat ${dir}tmp_downlist|grep -w ${1}|grep -v "^$"|sort -u|head -n1` 779 | if [ ! -z "$tmp_downip" ]; then 780 | cat ${dir}tmp_downlist|grep -w ${1}|grep -v "^$"|sort -u|head -n1 >> ${dir}ipAddress 781 | sed -i "/^${1} /d" ${dir}tmp_downlist 782 | else 783 | usage down $1 784 | echo "$1 ${ip_mac} ${ip_name} `date +%s` ${ip_interface}" >> ${dir}ipAddress 785 | blackwhitelist ${ip_mac};local ip_blackwhite=$? 786 | [ -f "${dir}send_enable.lock" ] || [ -z "$pushbot_up" ] || [ -z "$ip_blackwhite" ] && LockFile unlock && return 787 | [ ! -z "$pushbot_up" ] && [ "$pushbot_up" -ne "1" ] && LockFile unlock && return 788 | [ -z "$ip_blackwhite" ] || [ "$ip_blackwhite" -ne "0" ] && LockFile unlock && return 789 | [ -f "${dir}title" ] && local title=`cat ${dir}title` 790 | [ -f "${dir}content" ] && local content=`cat ${dir}content` 791 | if [ -z "$title" ]; then 792 | local title="$ip_name 连接了你的路由器" 793 | local content="${str_splitline}${str_title_start}${font_green} 新设备连接${font_end}${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}" 794 | elif ( echo ${title}|grep -q "连接了你的路由器" ); then 795 | local title="${ip_name} ${title}" 796 | 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}" 797 | else 798 | local title="设备状态变化" 799 | local content="${str_splitline}${str_title_start}${font_green} 新设备连接${font_end}${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}" 800 | fi 801 | echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}新设备 ${ip_name} ${1} 连接了">> ${logfile} 802 | #[ ! -z "$pushbot_blacklist" ] && local title="你偷偷关注的设备上线了" 803 | [ ! -z "$title" ] && echo "$title" >${dir}title 804 | [ ! -z "$content" ] && echo -n "$content" >>${dir}content 805 | fi 806 | fi 807 | LockFile unlock 808 | } 809 | 810 | # 检测设备离线 811 | function down(){ 812 | local ip_mac=`getmac $1` 813 | local ip_name=`getname ${1} ${ip_mac}` 814 | local ip_interface=`getinterface ${ip_mac}` 815 | getping ${1} ${down_timeout} ${timeout_retry_count};local ping_online=$? 816 | if [ "$ping_online" -eq "1" ]; then 817 | LockFile lock 818 | [ ! -f "${dir}send_enable.lock" ] && cat ${dir}ipAddress|grep -w ${1}|grep -v "^$"|sort -u|head -n1 >> ${dir}tmp_downlist 819 | sed -i "/^${1} /d" ${dir}ipAddress 820 | LockFile unlock 821 | else 822 | local tmp_name=`cat ${dir}ipAddress|grep -w ${1}|awk '{print $3}'|grep -v "^$"|sort -u|head -n1` 823 | if [ "$ip_name" != "$tmp_name" ]; then 824 | LockFile lock 825 | 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}") 826 | sed -i "/^${1} /d" ${dir}ipAddress 827 | echo "$tmp_str" >> ${dir}ipAddress 828 | LockFile unlock 829 | fi 830 | fi 831 | } 832 | 833 | # 设备离线通知 834 | function down_send(){ 835 | [ ! -f "${dir}tmp_downlist" ] && return 836 | local IPLIST=`cat ${dir}tmp_downlist|awk '{print $1}'` 837 | for ip in $IPLIST; do 838 | local ip_mac=`getmac ${ip}` 839 | blackwhitelist ${ip_mac};local ip_blackwhite=$? 840 | [ -z "$pushbot_down" ] || [ -z "$ip_blackwhite" ] && continue 841 | [ ! -z "$pushbot_down" ] && [ "$pushbot_down" -ne "1" ] && continue 842 | [ -z "$ip_blackwhite" ] || [ "$ip_blackwhite" -ne "0" ] && continue 843 | [ ! -z "$pushbot_blacklist" ] && local tmp_mac=`echo "${pushbot_blacklist}"|grep -w -i ${ip_mac}` 844 | [ ! -z "$pushbot_whitelist" ] && local tmp_mac=`echo "${pushbot_whitelist}"|grep -w -i ${ip_mac}` 845 | [ ! -z "$tmp_mac" ] && ( cat ${dir}ipAddress|grep -q -w -i ${tmp_mac} ) && continue 846 | local ip_name=`getname ${ip} ${ip_mac}` 847 | local time_up=`cat ${dir}tmp_downlist|grep -w ${ip}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1` 848 | 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}" 849 | local time1=`date +%s` 850 | local time1=$(time_for_humans `expr ${time1} - ${time_up}`) 851 | if [ -z "$title" ]; then 852 | title="${ip_name} 断开连接" 853 | content="${content}${str_splitline}${str_title_start}${font_red} 设备断开连接${font_end}${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}" 854 | elif ( echo "$title"|grep -q "断开连接" ); then 855 | title="${ip_name} ${title}" 856 | 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}" 857 | else 858 | title="设备状态变化" 859 | content="${content}${str_splitline}${str_title_start}${font_red} 设备断开连接${font_end}${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}" 860 | fi 861 | echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}设备 ${ip_name} ${ip} 断开连接 " >> ${logfile} 862 | done 863 | rm -f ${dir}tmp_downlist >/dev/null 2>&1 864 | } 865 | 866 | # 当前设备列表 867 | function current_device(){ 868 | ( echo "$lite_enable"|grep -q "content" ) || ( echo "$lite_enable"|grep -q "device" ) && return 869 | [ -f ${dir}ipAddress ] && local logrow=$(grep -c "" ${dir}ipAddress) || local logrow="0";[ $logrow -eq "0" ] && return 870 | [ -f ${dir}usage.db ] && local ip_total_db="总计流量${str_space}${str_space}${str_space}${str_space}" 871 | content="${content}${str_splitline}${str_title_start}${font_blue} 现有在线设备 ${logrow} 台,具体如下${font_end}${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}${boldstar}客户端名${boldstar}" 872 | local IPLIST=`cat ${dir}ipAddress|awk '{print $1}'` 873 | for ip in $IPLIST; do 874 | local ip_mac=`getmac ${ip}` 875 | local ip_total=`usage get ${ip_mac}` 876 | local ip_name=`getname ${ip} ${ip_mac}` 877 | local ip_name=`cut_str $ip_name 15` 878 | if [ "${#ip}" -lt "15" ]; then 879 | local n=`expr 15 - ${#ip}` 880 | for i in `seq 1 $n`; do 881 | local ip="${ip}${str_space}" 882 | done 883 | unset i n 884 | fi 885 | if [ ! -z "$ip_total" ]; then 886 | local n=`expr 11 - ${#ip_total}` 887 | for i in `seq 1 $n`; do 888 | local ip_total="${ip_total}${str_space}" 889 | done 890 | fi 891 | content="${content}${str_linefeed}${str_tab}${ip}${ip_total}${boldstar}${font_green2}${ip_name}${font_end2}${boldstar}" 892 | unset i n ip_total ip_mac ip_name 893 | done 894 | } 895 | 896 | # 检测 cpu 状态 897 | function cpu_load(){ 898 | if [ ! -z "$temperature_enable" ] && [ "$temperature_enable" -eq "1" ] && [ ! -z "$temperature" ]; then 899 | [ -z "$temperature_time" ] && temperature_time=`date +%s` 900 | local cpu_wendu=`soc_temp`; 901 | [ -z "$cpu_wendu" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】无法读取设备温度,请检查命令" >> ${logfile} 902 | 903 | if [ `expr $cpu_wendu \> $temperature` -eq "1" ]; then 904 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!警报!!】 CPU 温度过高: ${cpu_wendu}" >> ${logfile} 905 | else 906 | temperature_time=`date +%s` 907 | fi 908 | 909 | if [ "$((`date +%s`-$temperature_time))" -ge "300" ] && [ -z "$temperaturecd_time" ]; then 910 | title="CPU 温度过高!" 911 | temperaturecd_time=`date +%s` 912 | echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text} CPU 温度过高: ${cpu_wendu}" >> ${logfile} 913 | content="${content}${str_splitline}${str_title_start}${font_red} CPU 温度过高${font_end}${str_title_end}${str_linefeed}${str_tab}CPU 温度已连续五分钟超过预设${str_linefeed}${str_tab}接下来一小时不再提示${str_linefeed}${str_tab}当前温度:${cpu_wendu}℃" 914 | elif [ ! -z "$temperaturecd_time" ] && [ "$((`date +%s`-$temperaturecd_time))" -ge "3300" ] ;then 915 | unset temperaturecd_time 916 | fi 917 | fi 918 | 919 | if [ ! -z "$cpuload_enable" ] && [ "$cpuload_enable" -eq "1" ] && [ ! -z "$cpuload" ]; then 920 | [ -z "$cpuload_time" ] && cpuload_time=`date +%s` 921 | local cpu_fuzai=`cat /proc/loadavg|awk '{print $1}'` 2>/dev/null 922 | [ -z "$cpu_fuzai" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】无法读取设备负载,请检查命令" >> ${logfile} 923 | 924 | if [ `expr $cpu_fuzai \> $cpuload` -eq "1" ]; then 925 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!警报!!】 CPU 负载过高: ${cpu_fuzai}" >> ${logfile} 926 | cputop log 927 | else 928 | cpuload_time=`date +%s` 929 | fi 930 | 931 | if [ "$((`date +%s`-$cpuload_time))" -ge "300" ] && [ -z "$cpucd_time" ]; then 932 | unset getlogtop 933 | if [ ! -z "$title" ] && ( echo "$title"|grep -q "过高" ); then 934 | title="设备报警!" 935 | else 936 | title="CPU 负载过高!" 937 | fi 938 | cpucd_time=`date +%s` 939 | echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text} CPU 负 载过高: ${cpu_fuzai}" >> ${logfile} 940 | content="${content}${str_splitline}${font_red}CPU 负载过高${font_end}${str_linefeed}${str_tab}CPU 负载已连续五分钟超过预设${str_linefeed}${str_tab}接下来一小时不再提示${str_linefeed}${str_tab}当前负载:${cpu_fuzai}" 941 | cputop 942 | elif [ ! -z "$cpucd_time" ] && [ "$((`date +%s`-$cpucd_time))" -ge "3300" ] ;then 943 | unset cpucd_time 944 | fi 945 | fi 946 | } 947 | 948 | function cputop(){ 949 | [ -z "$1" ] && content="${content}${str_splitline}${str_title_start} 当前 CPU 占用前三的进程${str_title_end}" 950 | local gettop=`top -bn 1|grep -v "top -bn 1"` 951 | for i in `seq 5 7`; do 952 | local top_name=`echo "${gettop}"|awk 'NR=='${i}|awk '{print ($8 ~ /\/bin\/sh|\/bin\/bash/) ? $9 : $8}'` 953 | local top_load=`echo "${gettop}"|awk 'NR=='${i}|awk '{print $7}'` 954 | local temp_top="${top_name} ${top_load}" 955 | [ ! -z "$1" ] && local logtop="$logtop $temp_top" 956 | [ -z "$1" ] && content="${content}${str_linefeed}${str_tab}${temp_top}" 957 | done 958 | unset i 959 | [ ! -z "$1" ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!警报!!】 CPU 占用前三: ${logtop}" >> ${logfile} 960 | } 961 | 962 | # 生成日志监控文件,避免后台影响 wait 语句 963 | function get_syslog(){ 964 | kill -9 `pgrep -f "logread -f -p notice"` 2>/dev/null 965 | [ -z "$web_logged" ] && [ -z "$ssh_logged" ] && [ -z "$web_login_failed" ] && [ -z "$ssh_login_failed" ] && return 966 | rm -f ${dir}login_monitor >/dev/null 2>&1 967 | 968 | cat>${dir}get_syslog<> ${dir}login_monitor & 971 | EOF 972 | chmod 0755 ${dir}get_syslog && ${dir}get_syslog 973 | rm -f ${dir}get_syslog >/dev/null 2>&1 974 | } 975 | 976 | # 登录提醒通知 977 | function login_send(){ 978 | [ -z "$web_logged" ] && [ -z "$ssh_logged" ] && [ -z "$web_login_failed" ] && [ -z "$ssh_login_failed" ] && return 979 | [ ! -f ${dir}login_monitor ] && return 980 | cat ${dir}login_monitor|grep -i "accepted login"|awk '{print $4" "$NF}' >> ${dir}web_login 981 | cat ${dir}login_monitor|grep -i "Password auth succeeded\|Pubkey auth succeeded"|grep -Eo "[0-9]{2}:[0-9]{2}:[0-9]{2}.*[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"|awk '{print $1" "$NF" "$5}' >> ${dir}ssh_login 982 | cat ${dir}login_monitor|grep -i "failed login"|grep -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" >> ${dir}web_failed 983 | cat ${dir}login_monitor|grep -i "Bad password attempt\|Login attempt for nonexistent user from"|grep -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" >> ${dir}ssh_failed 984 | echo "" > ${dir}login_monitor 985 | add_ip_black 986 | 987 | local login_ip_list=`cat ${dir}web_login|awk '{print $2}'|grep -v "^$"|sort -u|head -n1` 988 | for login_ip in $login_ip_list; do 989 | [ -z "$login_ip" ] && continue 990 | echo "$ip_white_list"|grep -w -q "$login_ip" && continue 991 | local web_login_time=`cat ${dir}web_login|grep -w ${login_ip}|awk '{print $1}'|grep -v "^$"|sort -u|head -n1` 992 | local web_login_mode=`cat ${dir}web_login|grep -w ${login_ip}|awk '{print $3}'|grep -v "^$"|sort -u|head -n1` 993 | if [ ! -z "$web_logged" ] && [ "$web_logged" -eq "1" ]; then 994 | if [ -z "$title" ]; then 995 | title="${login_ip} 通过 Web 登录了路由器" 996 | content="${content}${str_splitline}${str_title_start}${font_green} 登录信息${font_end}${str_title_end}${str_linefeed}${str_tab}时间:${str_space}${str_space}${str_space}${str_space}${str_space}${web_login_time}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_mode}" 997 | elif ( echo "$title"|grep -q "登录了路由器" ); then 998 | title="${login_ip} ${title}" 999 | content="${content}${str_splitline}${str_tab}时间:${str_space}${str_space}${str_space}${str_space}${str_space}${web_login_time}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_mode}" 1000 | else 1001 | title="设备状态变化" 1002 | content="${content}${str_splitline}${str_title_start}${font_green} 登录成功来源${font_end}${str_title_end}${str_linefeed}${str_tab}时间:${str_space}${str_space}${str_space}${str_space}${str_space}${web_login_time}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_mode}" 1003 | fi 1004 | fi 1005 | echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}设备 ${login_ip} 通过 web ${web_login_mode} 登录了路由器 " >> ${logfile} 1006 | done 1007 | echo "" > ${dir}web_login 1008 | unset login_ip login_ip_list 1009 | 1010 | local login_ip_list=`cat ${dir}ssh_login|awk '{print $2}'|grep -v "^$"|sort -u|head -n1` 1011 | for login_ip in $login_ip_list; do 1012 | [ -z "$login_ip" ] && continue 1013 | echo "$ip_white_list"|grep -w -q "$login_ip" && continue 1014 | local ssh_login_time=`cat ${dir}ssh_login|grep -w ${login_ip}|awk '{print $1}'|grep -v "^$"|sort -u|head -n1` 1015 | local ssh_login_mode=`cat ${dir}ssh_login|grep -w ${login_ip}|awk '{print $3}'|grep -v "^$"|sort -u|head -n1` 1016 | [ ! -z "$ssh_login_mode" ] && local content_mode="${str_linefeed}${str_tab}登录方式: ${str_space}${str_space}${str_space}${str_space}${ssh_login_mode}" 1017 | if [ ! -z "$ssh_logged" ] && [ "$ssh_logged" -eq "1" ]; then 1018 | if [ -z "$title" ]; then 1019 | title="${login_ip} 通过 SSH 登录了路由器" 1020 | content="${content}${str_splitline}${str_title_start}${font_green} 登录成功来源${font_end}${str_title_end}${str_linefeed}${str_tab}时间:${str_space}${str_space}${str_space}${str_space}${str_space}${ssh_login_time}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_mode}" 1021 | elif ( echo "$title"|grep -q "登录了路由器" ); then 1022 | title="${login_ip} ${title}" 1023 | content="${content}${str_splitline}${str_tab}时间:${str_space}${str_space}${str_space}${str_space}${str_space}${ssh_login_time}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_mode}" 1024 | else 1025 | title="设备状态变化" 1026 | content="${content}${str_splitline}${str_title_start}${font_green} 登录成功来源${str_title_end}${str_linefeed}${str_tab}时间:${str_space}${str_space}${str_space}${str_space}${str_space}${ssh_login_time}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}${content_mode}" 1027 | fi 1028 | fi 1029 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【info】设备 ${login_ip} 通过 SSH ${ssh_login_mode} 登录了路由器 " >> ${logfile} 1030 | done 1031 | echo "" > ${dir}ssh_login 1032 | unset login_ip login_ip_list 1033 | 1034 | local login_ip_list=`cat ${dir}web_failed|awk '{print $1}'|grep -v "^$"|sort -u|head -n1` 1035 | for login_ip in $login_ip_list; do 1036 | [ -z "$login_ip" ] && continue 1037 | echo "$ip_white_list"|grep -w -q "$login_ip" && continue 1038 | local web_login_sum=`cat ${dir}web_failed|grep -w "${login_ip}"|wc -l` 1039 | if [ "$web_login_sum" -ge "$login_max_num" ] ;then 1040 | if [ ! -z "$web_login_failed" ] && [ "$web_login_failed" -eq "1" ]; then 1041 | if [ -z "$title" ]; then 1042 | title="${login_ip} 通过 Web 频繁尝试登录" 1043 | content="${content}${str_splitline}${str_title_start}${font_red} 登录失败来源${font_end}${str_title_end}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}" 1044 | elif ( echo "$title"|grep -q "频繁尝试登录" ); then 1045 | title="${login_ip} ${title}" 1046 | content="${content}${str_splitline}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}" 1047 | else 1048 | title="设备状态变化" 1049 | content="${content}${str_splitline}${str_title_start}${font_red} 登录失败来源${font_end}${str_title_end}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}" 1050 | fi 1051 | fi 1052 | sed -i "/^${login_ip}$/d" ${dir}web_failed 1053 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】设备 ${login_ip} 通过 Web 频繁尝试登录" >> ${logfile} 1054 | add_ip_black $login_ip 1055 | fi 1056 | done 1057 | unset login_ip 1058 | 1059 | local login_ip_list=`cat ${dir}ssh_failed|awk '{print $1}'|grep -v "^$"|sort -u|head -n1` 1060 | for login_ip in $login_ip_list; do 1061 | [ -z "$login_ip" ] && continue 1062 | echo "$ip_white_list"|grep -w -q "$login_ip" && continue 1063 | local ssh_login_sum=`cat ${dir}ssh_failed|grep -w "${login_ip}"|wc -l` 1064 | if [ "$ssh_login_sum" -ge "$login_max_num" ] ;then 1065 | if [ ! -z "$ssh_login_failed" ] && [ "$ssh_login_failed" -eq "1" ]; then 1066 | if [ -z "$title" ]; then 1067 | title="${login_ip} 通过 SSH 频繁尝试登录" 1068 | content="${content}${str_splitline}${str_title_start}${font_red} 登录失败来源${font_end}${str_title_end}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}" 1069 | elif ( echo "$title"|grep -q "频繁尝试登录" ); then 1070 | title="${login_ip} ${title}" 1071 | content="${content}${str_splitline}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}" 1072 | else 1073 | title="设备状态变化" 1074 | content="${content}${str_splitline}${str_title_start}${font_red} 登录失败来源${font_end}${str_title_end}${str_linefeed}${str_tab}设备 IP: ${str_space}${str_space}${str_space}${str_space}${login_ip}" 1075 | fi 1076 | fi 1077 | sed -i "/^${login_ip}$/d" ${dir}ssh_failed 1078 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】设备 ${login_ip} 通过 SSH 频繁尝试登录" >> ${logfile} 1079 | add_ip_black $login_ip 1080 | fi 1081 | done 1082 | unset login_ip 1083 | 1084 | } 1085 | 1086 | # 添加黑名单 1087 | function add_ip_black(){ 1088 | [ -f "${ip_blacklist_path}" ] && local logrow=$(grep -c "" ${ip_blacklist_path}) || local logrow="0" 1089 | [ ! -f "${ip_blacklist_path}" ] && local logrow="0" 1090 | [ ! -z "$web_login_black" ] && [ "$web_login_black" -eq "0" ] || [ -z "$web_login_black" ] && local logrow="0" 1091 | ipset flush ip_blacklist >/dev/null 2>&1 1092 | 1093 | if [ $logrow -le "0" ]; then 1094 | iptables -D INPUT -m set --match-set ip_blacklist src -j DROP >/dev/null 2>&1 1095 | ipset destroy ip_blacklist >/dev/null 2>&1 1096 | return 1097 | fi 1098 | 1099 | ipset list ip_blacklist >/dev/null 2>&1 || ipset create ip_blacklist hash:ip timeout ${ip_black_timeout} >/dev/null 2>&1 1100 | iptables -C INPUT -m set --match-set ip_blacklist src -j DROP >/dev/null 2>&1 || iptables -I INPUT -m set --match-set ip_blacklist src -j DROP >/dev/null 2>&1 1101 | echo "$1" >> ${ip_blacklist_path} 1102 | for ip_black in `cat ${ip_blacklist_path}`; do 1103 | ip_black=`echo "$ip_black"|grep -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"` 1104 | ipset -! add ip_blacklist $ip_black >/dev/null 2>&1 1105 | done 1106 | ipset list ip_blacklist|grep -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" > ${ip_blacklist_path} 1107 | } 1108 | 1109 | # 发送定时数据 1110 | function send(){ 1111 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【定时数据】创建定时任务" >> ${logfile} 1112 | pushbot_disturb;local send_disturb=$? 1113 | get_config "send_title" "router_status" "router_temp" "router_wan" "client_list" "google_check_timeout" 1114 | 1115 | [ -z "$send_title" ] && local send_title="路由状态:" 1116 | [ -z "$google_check_timeout" ] && local google_check_timeout="10" 1117 | [ ! -z "$1" ] && local send_title="发送测试:" && local 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" 1118 | [ -z "$1" ] && [ ! -z "$client_list" ] && [ "$client_list" -eq "1" ] && > ${dir}send_enable.lock && pushbot_first & 1119 | 1120 | if [ -z "$1" ] && [ ! -z "$router_status" ] && [ "$router_status" -eq "1" ]; then 1121 | local systemload=`cat /proc/loadavg|awk '{print $1" "$2" "$3}'` 1122 | local cpuload=`getcpu` 1123 | local ramload=`free -m|sed -n '2p'|awk '{printf "%.2f%%\n",($3/$2)*100}'` 1124 | local Qwai=`curl -o /dev/null --connect-timeout ${google_check_timeout} -s -w %{http_code} www.google.com` 1125 | if [[ "$Qwai" -eq "200" ]] || [[ "$Qwai" -eq "301" ]] || [[ "$Qwai" -eq "302" ]]; then 1126 | local Qwai_status="已连通!" 1127 | else 1128 | local Qwai_status="已断开!" 1129 | fi 1130 | 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 1131 | local send_content="${send_content}${str_splitline}${str_title_start}${font_blue} 系统运行状态${font_end}${str_title_end}" 1132 | local send_content="${send_content}${str_linefeed}${str_tab}平均负载:${systemload}" 1133 | local send_content="${send_content}${str_linefeed}${str_tab}CPU占用:${cpuload}${percentsym}" 1134 | local send_content="${send_content}${str_linefeed}${str_tab}内存占用:${ramload}${percentsym}" 1135 | local send_content="${send_content}${str_linefeed}${str_tab}全球互联:${Qwai_status}" 1136 | local send_content="${send_content}${str_linefeed}${str_tab}${systemstatustime}" 1137 | fi 1138 | 1139 | if [ -z "$1" ] && [ ! -z "$router_temp" ] && [ "$router_temp" -eq "1" ]; then 1140 | local cputemp=`soc_temp` 1141 | [ ! -z "$cputemp" ] && local send_content="${send_content}${str_splitline}${str_title_start}${font_blue} 设备温度${font_end}${str_title_end}${str_linefeed}${str_tab}CPU:${cputemp}℃" 1142 | [ -z "$cputemp" ] && local send_content="${send_content}${str_splitline}${str_title_start}${font_red} 设备温度${font_end}${str_title_end}${str_linefeed}${str_tab}无法获取设备温度" 1143 | fi 1144 | 1145 | if [ -z "$1" ] && [ ! -z "$router_wan" ] && [ "$router_wan" -eq "1" ]; then 1146 | local send_wanIP=`getip wanipv4`;local send_hostIP=`getip hostipv4` 1147 | local send_content="${send_content}${str_splitline}${str_title_start}${font_blue} WAN 口信息${font_end}${str_title_end}${str_linefeed}${str_tab}接口ip:${send_wanIP}" 1148 | local send_content="${send_content}${str_linefeed}${str_tab}外网ip:${send_hostIP}" 1149 | if [ ! -z "$pushbot_ipv6" ] && [ "$pushbot_ipv6" -ne "0" ]; then 1150 | local send_wanIPv6=`getip wanipv6`;local send_hostIPv6=`getip hostipv6` 1151 | local send_content="${send_content}${str_linefeed}${str_tab}ipv6 :${send_wanIPv6}" 1152 | local send_content="${send_content}${str_linefeed}${str_tab}外网v6:${send_hostIPv6}" 1153 | fi 1154 | ( ! echo "$send_wanIP"|grep -q -w ${send_hostIP} ) && local send_content="${send_content}${str_linefeed}${str_tab}外网 ip 与接口 ip 不一致,你的 ip 不是公网 ip" 1155 | local interfaceuptime=`getinterfaceuptime` 1156 | [ ! -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 1157 | local send_content="${send_content}${str_linefeed}${str_tab}${wanstatustime}" 1158 | fi 1159 | 1160 | if [ -z "$1" ] && [ ! -z "$client_list" ] && [ "$client_list" -eq "1" ]; then 1161 | wait 1162 | local IPLIST=`cat ${dir}ipAddress 2>/dev/null|awk '{print $1}'` 1163 | [ -f ${dir}ipAddress ] && local logrow=$(grep -c "" ${dir}ipAddress) || local logrow="0" 1164 | [ "$logrow" -eq "0" ] && local send_content="${send_content}${str_splitline}${str_title_start}${font_red} 当前无在线设备${font_end}${str_title_end}" || local send_content="${send_content}${str_splitline}${str_title_start}${font_blue} 现有在线设备 ${logrow} 台${font_end}${str_title_end}" 1165 | for ip in $IPLIST; do 1166 | local time_up=`cat ${dir}ipAddress|grep -w ${ip}|awk '{print $4}'|grep -v "^$"|sort -u|head -n1` 1167 | local time1=`date +%s` 1168 | local time1=$(time_for_humans `expr ${time1} - ${time_up}`) 1169 | local ip_mac=`getmac ${ip}` 1170 | local ip_name=`getname ${ip} ${ip_mac}` 1171 | local ip_total=`usage get ${ip_mac}`;[ ! -z "$ip_total" ] && local ip_total="总计流量:${ip_total} " 1172 | local ip_name=`cut_str $ip_name 18` 1173 | local send_content="${send_content}${str_linefeed}${str_tab}${font_green2}【${ip_name}】${font_end2} ${ip}${str_linefeed}${str_tab}${ip_total}在线 ${time1}" 1174 | unset ip_total time_down time_up time1 ip_mac ip_name 1175 | done 1176 | fi 1177 | 1178 | [ ! -z "$device_name" ] && local send_title="【$device_name】${send_title}" 1179 | [ -z "$send_content" ] && local send_content="${str_splitline}${str_title_start} 我遇到了一个难题${str_title_end}${str_linefeed}${str_tab}定时发送选项错误,你没有选择需要发送的项目,该怎么办呢${str_splitline}" 1180 | [ "$send_disturb" -eq "0" ] && diy_send "${send_title}" "${send_content}" "${jsonpath}" >/dev/null 2>&1 1181 | [ $? -eq 1 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】定时推送失败,请检查网络或设置信息" >> ${logfile} || echo "`date "+%Y-%m-%d %H:%M:%S"` ${disturb_text}定时推送任务完成" >> ${logfile} 1182 | deltemp 1183 | } 1184 | 1185 | # 初始化 1186 | read_config 1187 | deltemp 1188 | pushbot_cron 1189 | 1190 | # 限制并发进程 1191 | [ -z "$thread_num" ] || [ "$thread_num" -eq "0" ] && thread_num=5 1192 | [ -e ${dir}fd1 ] || mkfifo ${dir}fd1 1193 | exec 5<>${dir}fd1 1194 | rm -f ${dir}fd1 >/dev/null 2>&1 1195 | for i in `seq 1 $thread_num`; do 1196 | echo >&5 1197 | done 1198 | unset i 1199 | 1200 | # 启动参数 1201 | if [ "$1" ] ;then 1202 | [ $1 == "send" ] && send 1203 | [ $1 == "soc" ] && echo `soc_temp` > ${dir}soc_tmp 1204 | [ $1 == "client" ] && get_client 1205 | [ $1 == "test" ] && send test 1206 | exit 1207 | fi 1208 | 1209 | # 载入在线设备 1210 | pushbot_init;[ $? -eq 1 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】读取设置出错,请检查设置项 " >> ${logfile} && exit 1211 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】载入在线设备" >> ${logfile} 1212 | > ${dir}send_enable.lock && pushbot_first && deltemp 1213 | echo "`date "+%Y-%m-%d %H:%M:%S"` 【初始化】初始化完成" >> ${logfile} 1214 | 1215 | # 循环 1216 | while [ "$pushbot_enable" -eq "1" ]; do 1217 | deltemp 1218 | usage update 1219 | pushbot_disturb;disturb=$? 1220 | 1221 | # 外网IP变化检测 1222 | [ -f ${dir}ipAddress ] && ipAddress_logrow=$(grep -c "" ${dir}ipAddress) || ipAddress_logrow="0"; 1223 | if [ $ipAddress_logrow -ne "0" ]; then 1224 | online_list=`cat ${dir}ipAddress|awk '{print $2}'|grep -v "^$"|sort -u` 1225 | for online_mac in $online_list; do 1226 | [ ! -z "$online_mac" ] && mac_online_status="`echo "$mark_mac_list"|grep -i $online_mac|grep -v "^$"|sort -u|head -n1`${mac_online_status}" 1227 | done 1228 | fi 1229 | 1230 | if [ "$pushbot_ipv4" -ne "0" ] || [ "$pushbot_ipv6" -ne "0" ]; then 1231 | rand_geturl 1232 | ip_changes 1233 | fi 1234 | 1235 | # 设备列表 1236 | if [ ! -f "${dir}send_enable.lock" ]; then 1237 | [ ! -z "$title" ] && echo "$title" > ${dir}title 1238 | [ ! -z "$content" ] && echo "$content" > ${dir}content 1239 | pushbot_first 1240 | [ -f "${dir}title" ] && title=`cat ${dir}title` && rm -f ${dir}title >/dev/null 2>&1 1241 | [ -f "${dir}content" ] && content=`cat ${dir}content` && rm -f ${dir}content >/dev/null 2>&1 1242 | fi 1243 | 1244 | # 离线缓存区推送 1245 | [ ! -f "${dir}send_enable.lock" ] && down_send 1246 | 1247 | # 当前设备列表 1248 | [ ! -z "$content" ] && [ ! -f "${dir}send_enable.lock" ] && current_device 1249 | 1250 | # 无人值守任务 1251 | [ ! -f "${dir}send_enable.lock" ] && unattended 1252 | 1253 | # CPU 检测 1254 | [ ! -f "${dir}send_enable.lock" ] && cpu_load 1255 | 1256 | # 异常流量检测 1257 | [ ! -f "${dir}send_enable.lock" ] && get_client_usage 1258 | 1259 | # 登录提醒通知 1260 | [ ! -f "${dir}send_enable.lock" ] && login_send 1261 | 1262 | # 通知 1263 | if [ ! -f "${dir}send_enable.lock" ] && [ ! -z "$title" ] && [ ! -z "$content" ]; then 1264 | [ ! -z "$device_name" ] && title="【$device_name】$title" 1265 | ( echo "$lite_enable"|grep -q "content" ) && content="$title" 1266 | [ "$disturb" -eq "0" ] && diy_send "${title}" "${content}" "${jsonpath}" >/dev/null 2>&1 1267 | [ $? -eq 1 ] && echo "`date "+%Y-%m-%d %H:%M:%S"` 【!!!】推送失败,请检查网络或设置信息 " >> ${logfile} 1268 | fi 1269 | 1270 | while [ -f "${dir}send_enable.lock" ]; do 1271 | sleep $sleeptime 1272 | done 1273 | sleep $sleeptime 1274 | done 1275 | -------------------------------------------------------------------------------- /root/usr/share/rpcd/acl.d/luci-app-pushbot.json: -------------------------------------------------------------------------------- 1 | { 2 | "luci-app-pushbot": { 3 | "description": "Grant UCI access for luci-app-pushbot", 4 | "read": { 5 | "uci": [ "pushbot" ] 6 | }, 7 | "write": { 8 | "uci": [ "pushbot" ] 9 | } 10 | } 11 | } 12 | --------------------------------------------------------------------------------