Compare commits

...

198 Commits

Author SHA1 Message Date
hotyue
233af7181f release: bump AGENT_VERSION to v3.6.4 for Trust module Live News Engine 2026-04-22 14:03:41 +00:00
github-actions[bot]
62fb19f0c5 chore(data): 🤖 自动机兵:同步全战区热点词库与活体新闻流 [2026-04-22] 2026-04-22 13:49:03 +00:00
hotyue
54178ddcf1 fix(scripts): 修复 TW 战区 Yahoo RSS 拒绝 GitHub Actions IP 访问 (403) 的问题,切换至高可用 Google News TW 源 2026-04-22 13:48:06 +00:00
github-actions[bot]
92a65d8308 chore(data): 🤖 自动机兵:同步全战区热点词库与活体新闻流 [2026-04-22] 2026-04-22 13:45:37 +00:00
hotyue
eaaa7dabf0 Merge branch 'main' of https://github.com/hotyue/IP-Sentinel 2026-04-22 13:43:44 +00:00
hotyue
e797c8203f fix(scripts): 修复 HK 与 TW 战区 RSS 情报源失效报 404/解析错误的问题,切换至高可用源 2026-04-22 13:43:31 +00:00
github-actions[bot]
9ecf50c153 chore(data): 🤖 自动机兵:同步全战区热点词库与活体新闻流 [2026-04-22] 2026-04-22 13:37:10 +00:00
hotyue
c02b7eecc9 feat(scripts): 引入 v3.6.4 活体新闻融合引擎,重构 Action 流水线实现冷热数据合并原子提交 2026-04-22 13:35:20 +00:00
hotyue
6af8b6b25d chore(data): 注入全球国家级权威骨干网基石,重构 Trust 模块冷数据结构 2026-04-22 13:31:28 +00:00
hotyue
7081aa77cc fix(core): 废除 OnBootSec 相对开机时间,改用高兼容性的 OnActiveSec,彻底修复老内核系统下自动巡逻瘫痪的 Bug 2026-04-22 12:42:04 +00:00
hotyue
5e48edb030 fix(core): 废除物理阉割,全量下载模块脚本,彻底修复动态启用模块后提示 403 文件不存在的 Bug 2026-04-22 11:53:20 +00:00
github-actions[bot]
5f0f677f59 chore(data): 🤖 自动机兵:刷新全战区热点词库 [2026-04-21] 2026-04-21 19:22:42 +00:00
hotyue
7f0c3e3e29 release: bump version to v3.6.3 for final release 2026-04-21 09:50:14 +00:00
hotyue
c03f6ca9ba chore: 准备 v3.6.3 正式发布,将所有云端资源路由切换回 main 主干分支 2026-04-21 09:48:14 +00:00
hotyue
66f3ba7d06 perf(master): 优化包管理器参数,拒绝冗余依赖捆绑,实现 Master 中枢极致轻量化部署 2026-04-21 09:32:54 +00:00
hotyue
511ba90378 perf(core): 优化包管理器安装参数,拒绝冗余依赖捆绑,实现 Agent 节点极致轻量化部署 2026-04-21 09:30:04 +00:00
hotyue
01806d20dd fix(core): 引入智能网卡生存探测机制,彻底解决多 IP 站群机因 IP 漂移导致的 curl 死锁断网问题 2026-04-21 09:20:55 +00:00
hotyue
049278c458 fix(master): 修复 Telegram 429 频率限制拦截,延长全军简报下发间距至 2 秒,确保并发战报 100% 送达 2026-04-21 07:19:04 +00:00
hotyue
0aaa2d44a0 fix(master): 修复 db_exec 致命的标准输出混叠漏洞,改用静默的 .timeout 指令彻底消除面板 5000 乱码 2026-04-21 07:08:43 +00:00
hotyue
3f139a593e fix(master): 修复 db_exec 输出泄露导致的节点计数与战区列表乱码问题 2026-04-21 07:01:54 +00:00
hotyue
bee6fef69c fix(master): 启用 SQLite WAL 高并发引擎与 5000ms 锁排队机制,彻底解决全舰队并发通讯时的 database is locked 报错 2026-04-21 06:51:49 +00:00
hotyue
f283a8a4c6 fix(master): 完善向下兼容机制,对未升级老节点自动降级回退至 HTTP 通讯,确保私有司令部平滑过渡 2026-04-21 06:47:02 +00:00
hotyue
0d2433d850 feat(security): 引入动态 TLS 降级机制与自签名证书,全域 Webhook 通讯升级为强加密 HTTPS,彻底阻断明文嗅探风险并完美兼容官方网关 2026-04-21 06:27:58 +00:00
hotyue
a6b01bd8d5 chore(core): 恢复 install.sh 语法完整性,完成 OTA 防砖机制实弹演习 2026-04-21 06:12:38 +00:00
hotyue
8f2279b7e2 chore(core): 破坏 install.sh 语法完整性,用于 OTA 防砖机制实弹演习 2026-04-21 06:09:48 +00:00
hotyue
d37d26708d chore(core): 恢复 install.sh 语法完整性,完成 OTA 防砖机制实弹演习 2026-04-21 06:07:50 +00:00
hotyue
6234d7c49a fix(ota): 重构 Agent 防砖机制,引入双重 Base64 隔离,彻底杜绝 Shell 注入与换行截断,并实现失败主动告警 2026-04-21 06:05:39 +00:00
hotyue
f9a7bba32a Update install.sh
test
2026-04-21 13:52:06 +08:00
hotyue
068734da16 fix(ota): 引入 bash -n 语法树完整性校验,彻底阻断因网络波动下载不全导致的单点死机风险 2026-04-21 05:45:50 +00:00
hotyue
09a4108bcc docs(readme): 更新 Legacy 分支部署指令,全站统一采用更安全的落地执行法 2026-04-21 02:47:18 +00:00
hotyue
a7f08ec7a7 chore(release): 解除测试沙箱 URL 劫持,跃升至 v3.6.2,正式开启 Systemd 与智能双栈纪元 2026-04-21 02:42:04 +00:00
hotyue
f075fcce36 fix(master): 修复 Systemd 沙盒环境变量丢失问题,打通跨进程通讯,确保 OTA 升级捷报正常下发 2026-04-21 02:30:45 +00:00
hotyue
0bb96169e5 fix(core): 引入 Ceasefire Protocol (停火协议),彻底解决 Systemd 架构下 OTA 升级引发的无限重启风暴 2026-04-21 02:21:43 +00:00
hotyue
34320b2385 refactor(core): 手工融合 Systemd 引擎与 Root 权限校验 (提取自 PR #25),修复 Cgroup 误杀与交互逻辑陷阱,构建灰度测试候选版 2026-04-21 02:00:10 +00:00
github-actions[bot]
aeed9f0e57 chore(data): 🤖 自动机兵:刷新全战区热点词库 [2026-04-20] 2026-04-20 19:17:23 +00:00
hotyue
c04a4c41e4 fix(core): 修复内核级禁用 IPv6 时 Python Webhook 假死的问题,引入智能 IPv4 降级回退机制 (Resolves #23) 2026-04-20 17:41:17 +00:00
hotyue
3b28ead0e4 chore: 战略撤退,代码全量回滚至 9a38fb6 (PR 引入前的纯净状态) 2026-04-20 17:37:47 +00:00
hotyue
d0ea5d09b1 chore(release): 跃升至 v3.6.2,引入 Systemd 守护与智能双栈降级引擎 2026-04-20 17:20:09 +00:00
hotyue
a119973ec0 chore(release): 暂时回退至 v3.6.1 2026-04-20 17:18:17 +00:00
hotyue
b8b91ac17e chore(release): 跃升至 v3.6.2,引入 Systemd 守护与智能双栈降级引擎 2026-04-20 17:17:38 +00:00
hotyue
34f2c7e123 fix(core): 引入 systemd-run 逃逸机制,彻底修复 OTA 升级时因子进程被 Cgroup 误杀导致的假死漏洞 2026-04-20 17:13:48 +00:00
hotyue
172f1e0209 chore(release): 暂时回退至 v3.6.1 2026-04-20 17:11:05 +00:00
hotyue
1d5ed5d0cb chore(release): 跃升至 v3.6.2,引入 Systemd 守护与智能双栈降级引擎 2026-04-20 17:06:38 +00:00
hotyue
1e150f26f1 fix(core): 修复内核级禁用 IPv6 时 Python Webhook 假死的问题,引入智能 IPv4 降级回退机制 (Resolves #23) 2026-04-20 16:59:28 +00:00
hotyue
03e735a44b docs(readme): 重构系统部署指令,采用落地执行模式彻底修复管道符交互闪退与进程误杀漏洞 2026-04-20 16:55:12 +00:00
hotyue
011c1faad4 fix(core): 移除 agent_daemon.sh 尾部的 nohup 后台逻辑,适配 Systemd Type=simple 的前台阻塞监听,修复 cgroup 误杀导致的无限重启死循环 2026-04-20 16:46:45 +00:00
hotyue
2325a8abdf fix(core): 修复节点部署多城市选择分支下 CITY_NAME 变量未赋值导致播报为空的 UI 瑕疵 2026-04-20 16:41:00 +00:00
hotyue
201df489db refactor(core): 缝合 Systemd 架构,修复 PR #25 中的管道符闪退及 oneshot 守护进程死锁漏洞 2026-04-20 16:24:32 +00:00
IcySteam
2d680c5fc7 refactor(core): Enable Systemd and upgrade Sentinel service orchestration
The legacy crontabs have been superseded by Systemd to fortify orchestration of our global fleet of Sentinels.

While cron relies on timed, fire-and-forget execution, Systemd elevates our operations into natively integrated, state-aware OS daemons. This paradigm shift unlocks precise lifecycle management, unified logging (inspect all service logs with `journalctl -t ip-sentinel`), and absolute control over module deployment.

- Battle-Hardened: Sentinels now auto-resurrect upon failure, bypassing minute-long cron wait times.
- Zero-Impact Missions: Sentinels now operate under strict `idle` CPU/IO scheduling. This guarantees that automated maintenance cycles yield to high-priority user interactions, and never impact primary server workloads.
- Field Intelligence Auto-Stagger: Service-level `RandomizedDelaySec` natively staggers Agent check-ins to protect the Command Center.
- Legacy Fallback: OS interrogation on deployment ensures a seamless fallback to cron for Sentinels operating in Alpine/OpenRC environments.

The fleet is more resilient than ever, but the architecture is always evolving. I highly welcome any reviews/suggestions from the original Author/Commander to perfect this pull request!
2026-04-21 00:27:01 +10:00
IcySteam
e77b7c0319 fix(telemetry): Implement dual-write logging for Systemd integration
This commit refactors the internal logging functions across all core modules to guarantee telemetry reaches the Systemd journal. Sentinels now mirror their physical log outputs directly to the OS `logger`, ensuring flawless `journalctl` visibility even when modules are spawned in detached subshells.
2026-04-21 00:12:03 +10:00
IcySteam
2283da7421 docs(readme): Update setup instructions to use sudo pipes
The installation instructions in the README have been updated to pipe the `curl` output directly into `sudo bash`.

As we now mandate root privileges on setup, the standard `bash <(curl...)` command fails when prepended with `sudo` due to process substitution permissions. This fix ensures all new Commanders can deploy their Sentinels flawlessly on the first attempt.
2026-04-20 23:01:34 +10:00
IcySteam
4a28f7f395 fix(core): Mandate root privileges for all setup scripts
The old setup scripts assume root privileges. We are fixing this by explicitly requiring an `$EUID` root check before execution so that no borked, non-root installations happen.
2026-04-20 19:46:30 +10:00
github-actions[bot]
9a38fb62d0 chore(data): 🤖 自动机兵:刷新全战区热点词库 [2026-04-19] 2026-04-19 19:01:27 +00:00
hotyue
fefd5dc60c fix(master): 修复双栈机 IPv6 黑洞导致轮询假死的致命 Bug 2026-04-19 15:06:56 +00:00
hotyue
89aa1ead33 docs: 新增动态贡献者头像墙 (Contributors Wall),致敬开源极客 2026-04-19 14:36:48 +00:00
hotyue
a5f2fb53ed feat(data): 建立韩国 (KR) 战区拓扑,新增首尔节点信标及本土化高频活体词库 2026-04-19 14:23:50 +00:00
hotyue
bd26f1011d fix(master): 统一全域雷达面板的国旗状态机映射数组,修复删除节点后小众国家国旗丢失的 UI 渲染问题 2026-04-19 14:13:28 +00:00
hotyue
cfaf156e03 Merge pull request #24 from IcySteam/main
feat: Activate the AU command theater, deploy sentinel to 5 major Australian cities
2026-04-19 22:03:44 +08:00
github-actions[bot]
75cf50ce0c chore(data): 🤖 自动机兵:刷新全战区热点词库 [2026-04-18] 2026-04-18 19:01:49 +00:00
IcySteam
e2b6bbc347 master(AU): Add AU flag to TG menu 2026-04-19 01:05:38 +10:00
IcySteam
cd5160d1ea core(AU): Add AU flag to TG menu 2026-04-19 01:05:28 +10:00
IcySteam
040827aa27 data(AU): activate AU command theater, deploy sentinel to 5 major Australian cities 2026-04-19 00:57:01 +10:00
IcySteam
d00317a645 feat(map): establish the Oceania (AU) command theater 2026-04-19 00:53:00 +10:00
hotyue
60317b4444 docs: 更新项目文档,正式发布 v3.6.1 扁平化指控矩阵与司令部金蝉脱壳 (Master OTA) 架构 2026-04-18 00:54:27 +00:00
hotyue
a0bb0f30f2 chore(master): 移除安装向导测试期锚点,恢复生产环境 main 主分支直链 2026-04-18 00:54:22 +00:00
hotyue
cc6f7bf958 chore(master): 移除调度枢纽测试期锚点,恢复生产环境 main 主分支直链 2026-04-18 00:54:17 +00:00
hotyue
583e0b00d8 chore(release): 升级双端版本信标至 v3.6.1,激活扁平化矩阵与中枢 OTA 引擎 2026-04-18 00:54:09 +00:00
hotyue
c27f2fced9 feat(master): 实装司令部金蝉脱壳 (Silent Override) 架构,新增中枢免交互 OTA 热重载能力与自动捷报推送 2026-04-18 00:41:03 +00:00
hotyue
8baa141339 chore(master): 临时切换 install_master.sh 拉取直链至 dev-v3.6.1 分支以支持扁平化 UI 演习测试 2026-04-18 00:20:45 +00:00
hotyue
2eceb43ac3 chore(master): 临时切换 install_master.sh 拉取直链至 dev-v3.6.1 分支以支持扁平化 UI 演习测试 2026-04-18 00:17:12 +00:00
hotyue
8ce9eb256b refactor(master): 重构 M 菜单为扁平化指挥矩阵 (Flat Command Matrix),优化 L0-L3 层级逻辑,新增全局返回逃生舱,并实现统一哨兵终端的原位丝滑重绘 2026-04-18 00:15:33 +00:00
github-actions[bot]
bf2cfb7da0 chore(data): 🤖 自动机兵:刷新全战区热点词库 [2026-04-17] 2026-04-17 19:11:44 +00:00
hotyue
5dfaa19cca chore: 移除测试期 dev-v3.6.0 专属锚点,全系组件直链恢复至 main 主分支,准备发布正式版 2026-04-17 15:07:45 +00:00
hotyue
3404666b8e chore(release): 升级双端版本信标至 v3.6.0,全面激活零信任 OTA 引擎 2026-04-17 15:05:28 +00:00
hotyue
b64ab95658 docs: 重构项目文档,正式发布 v3.6.0 零信任 OTA 架构及全舰队升级指引 2026-04-17 15:05:05 +00:00
hotyue
f19d165ece refactor(master): 移植 Agent 级智能依赖探测引擎,实现缺啥补啥的优雅部署,并增加二次复检熔断机制 2026-04-17 14:49:10 +00:00
hotyue
602919dc18 fix(master): 修正 send_ui 函数的 JSON 载荷换行符为 \n,解决带按钮面板的排版乱码问题 2026-04-17 14:43:27 +00:00
hotyue
722db9f6d1 style(core): 引入终端 OSC 8 超链接特性,重构教程链接交互为点击即达,提升终端沉浸式体验 2026-04-17 14:35:55 +00:00
hotyue
970867f3c7 fix(master): 司令部启动追加 disown 脱钩指令,抹除卸载与升级时底层 Bash 的 Killed 进程报错,提升静默优雅度 2026-04-17 14:18:39 +00:00
hotyue
e22d8d3cd0 fix(master): 修复官方机器人 OTA 按钮 UI 泄露问题,精准挂载 IS_OFFICIAL_GATEWAY 标识完成渲染层拦截 2026-04-17 14:10:54 +00:00
hotyue
cfe6dd59c8 feat(master): 部署向导新增官方与私有网关身份选择,固化 IS_OFFICIAL_GATEWAY 标识以支持 UI 级物理熔断 2026-04-17 14:10:40 +00:00
hotyue
b46e257545 fix(master): 修正 TG 报文换行符为 %0A,解决 Markdown 解析排版异常 2026-04-17 13:39:59 +00:00
hotyue
3e9a82a657 chore: 临时将各组件拉取直链指向 dev-v3.6.0 分支,修复跨分支拉取导致的数据解析错位 2026-04-17 13:27:20 +00:00
hotyue
4cf687f436 feat(master): 控制面板实装单点与全舰队级 OTA 升级核按钮及二次确认防抖,重构底层注册逻辑以兼容 7 字段解析入库 2026-04-17 13:08:04 +00:00
hotyue
e88cf4ac5b feat(master): 部署引擎移植全境兼容嗅探器,并预建 SQLite 数据库的 enable_ota 控制字段 2026-04-17 13:07:14 +00:00
hotyue
898349d22e feat(core): Webhook 通讯引擎新增 /trigger_ota 高危路由,实装本地与网关双重熔断校验,并支持后台剥离交互的静默热重载 2026-04-17 13:06:44 +00:00
hotyue
9ea188cb6d feat(core): 部署向导新增静默接管模式 (SILENT_OTA),并实现基于双轨网关的 OTA 权限物理熔断与配置下发 2026-04-17 13:06:37 +00:00
hotyue
03d4c6160a docs: 恢复英文提示词 2026-04-17 09:02:38 +00:00
hotyue
cf4433cdd6 docs: 修改提示词 2026-04-17 08:55:17 +00:00
hotyue
ae80f25c67 docs: 增加Bot Token 及 Chat ID获取教程链接 2026-04-17 08:28:15 +00:00
hotyue
5b2c294c61 docs: 增加官方机器人直达链接 2026-04-17 08:19:00 +00:00
hotyue
a1595ab0c5 docs: 增加官方机器人直达链接 2026-04-17 08:17:30 +00:00
hotyue
0be1e92ac5 docs: 优化部署指南,将私有独立部署提升为首选推荐,并预告 OTA 远程升级战略 2026-04-17 08:02:59 +00:00
hotyue
cf3e5dca2f docs: 优化部署指南,将私有独立部署提升为首选推荐,并预告 OTA 远程升级战略 2026-04-17 07:58:54 +00:00
hotyue
902f612d31 chore(release): bump version to v3.5.4 2026-04-17 07:20:05 +00:00
hotyue
45475f14b7 feat(core): 优化中枢接入交互引导,将私有独立部署设为首选默认项,为后续 OTA 远程平滑升级铺路 2026-04-17 07:06:45 +00:00
hotyue
30f396aefe fix(core): 升级智能包管理器嗅探器,彻底修复 Alpine/Arch 依赖安装失败 Bug,并重构 Master 接入交互逻辑防止误触跳过 (Resolves #21) 2026-04-17 06:49:16 +00:00
hotyue
7cf7117615 fix(core): 增强安装引擎容错能力,加固 Cron 清理逻辑并严格限制底层物理标识符格式 2026-04-17 05:32:19 +00:00
hotyue
062305d126 fix(core): Webhook 引擎引入 fcntl 排他写锁防配置文件损坏,强制清洗底层物理主键 2026-04-17 05:32:15 +00:00
hotyue
f451aea643 fix(core): 优化战报日志提取逻辑,改用精确截断替代全量扫描,大幅降低 I/O 消耗 2026-04-17 05:32:09 +00:00
hotyue
64342b2846 fix(master): 批量调度引擎引入流量削峰机制,杜绝瞬间并发导致的网络栈与文件句柄耗尽 2026-04-17 05:32:03 +00:00
hotyue
d96b6e769a fix(core): 引入 flock 排他锁,彻底解决 Cron 任务重入导致的内存雪崩与 Fork 炸弹 2026-04-17 05:31:58 +00:00
hotyue
539de62eee chore(release): bump version to v3.5.3 2026-04-17 03:00:11 +00:00
hotyue
d514106e65 docs: [v3.5.3] 重构 README 极客特征文案,合并冗余架构特性并引入常青化排版 2026-04-17 03:00:05 +00:00
hotyue
7f9c8a4dea feat(master): [v3.5.3] 引入L5降维控制面板与内联UI重绘,实装红绿灯状态机与模块动态启停 (Resolves #17, Resolves #19) 2026-04-17 02:40:27 +00:00
hotyue
31014e571d feat(master): [v3.5.3] 升级 SQLite 初始表结构,新增模块状态追踪字段以支持红绿灯 UI (Resolves #19) 2026-04-17 02:40:23 +00:00
hotyue
f5aa68a8dc feat(core): [v3.5.3] Webhook 引擎新增模块动态启停(Toggle)路由,支持安全重写本地配置 (Resolves #19) 2026-04-17 02:40:19 +00:00
hotyue
63bbbd549e feat(agent): [v3.5.3] 优化安装向导,默认全量部署养护模块以支持远端动态控制 (Resolves #19) 2026-04-17 02:40:14 +00:00
hotyue
5e40ed426b chore: revert failed v3.6.0 attempts, rollback to safe state 2026-04-17 02:24:07 +00:00
hotyue
aebf3a9e90 fix(core): [v3.6.0] 终极修复 OTA 死锁:解决 curl 管道吞噬脚本 Bug,并应用底层网络脱壳机制 2026-04-17 02:17:32 +00:00
hotyue
8a3d7c305b fix(core): [v3.6.0] 彻底重构 OTA 升级调度,引入外挂延时脚本实现 100% 的网络脱壳与静默重启 2026-04-17 02:09:05 +00:00
hotyue
2d580eaea2 fix(core): [v3.6.0] 彻底解决 OTA 升级 TCP 通讯超时 Bug,引入 close_fds 剥离套接字继承机制 2026-04-17 01:59:29 +00:00
hotyue
d7ab695372 fix(core): [v3.6.0] 彻底解决 OTA 升级 TCP 通讯超时 Bug,引入异步守护线程与套接字剥离机制 2026-04-17 01:48:46 +00:00
hotyue
0c250dfd17 fix(core): [v3.6.0] 修复 OTA 升级时的竞态自杀 Bug,引入 TCP 强制刷新与 3 秒延迟脱壳机制 2026-04-17 01:44:40 +00:00
hotyue
52b12c7057 feat(master): [v3.6.0] 深度重构中枢调度,引入L5降维控制面板、红绿灯模块启停与全网 OTA 静默升级 (Resolves #17, Resolves #19) 2026-04-17 01:19:27 +00:00
hotyue
2166753569 feat(master): [v3.6.0] 司令部部署引入 OTA 下发权限控制,重构 SQLite 初始表结构以支持状态机 (Resolves #17, Resolves #19) 2026-04-17 01:19:20 +00:00
hotyue
46e418dfd0 feat(core): [v3.6.0] Webhook 引擎新增 OTA 升级与动态启停路由,实装底层权限物理熔断机制 (Resolves #17, Resolves #19) 2026-04-17 01:19:13 +00:00
hotyue
673e0ce3e6 feat(agent): [v3.6.0] 重构安装向导,引入静默 OTA 嗅探机制与双端授权防线,默认全量部署养护模块 (Resolves #17, Resolves #19) 2026-04-17 01:19:06 +00:00
github-actions[bot]
6203249782 chore(data): 🤖 自动机兵:刷新全战区热点词库 [2026-04-16] 2026-04-16 19:25:36 +00:00
hotyue
05e708ed21 fix(master): [v3.5.2] 修复交互向导首选项的默认值丢失问题,防止直接回车导致主控数据库被误删 2026-04-16 07:57:02 +00:00
hotyue
c4faa102cf fix(installer): [v3.5.2] 修复交互向导首选项的默认值丢失问题,防止直接回车导致平滑升级失效被误删档 2026-04-16 07:52:45 +00:00
hotyue
4a1b32278c fix(core): [v3.5.2] 补充 version.txt 尾部换行符,防止环境变量读取截断 2026-04-16 06:54:29 +00:00
hotyue
584ead387e docs: [v3.5.2] 更新 README 战报日志,全系版本号正式锚定 v3.5.2 2026-04-16 06:52:06 +00:00
hotyue
efdc62ba68 feat(map): 更新全球战区拓扑,挂载考文垂与蒙特利尔节点索引 2026-04-16 06:32:47 +00:00
hotyue
67618587e4 feat(data): 新增节点数据 - 加拿大蒙特利尔 (CA, Montreal) 2026-04-16 06:32:42 +00:00
hotyue
a2c045a841 feat(data): 新增节点数据 - 英国考文垂 (UK, Coventry) 2026-04-16 06:32:37 +00:00
hotyue
9b35c87cb4 fix(master): [v3.5.2] 修复 Telegram 纯文本 API 下发消息时的换行符 (%0A) 转义问题 2026-04-16 06:02:51 +00:00
hotyue
e6c6e66e4b feat(agent): [v3.5.2] 剥除改名后的冗余 TG 推送报文,实现静默修改配置与底层 HTTP 回执 2026-04-16 05:51:04 +00:00
hotyue
f1d36a2148 feat(master): [v3.5.2] 实现全自动丝滑改名,接收 Agent 成功回执后瞬间刷新本地 SQLite 数据库 2026-04-16 05:50:58 +00:00
hotyue
41906d0570 revert: 紧急回滚至稳定版 9768bed (修复加密升级导致的通讯中断) 2026-04-16 03:24:11 +00:00
hotyue
dc7d1c0f40 feat: [v3.5.2] 终极安全与逻辑闭环补丁
1. 升级军工级 HMAC 签名:将数据负载 (Base64) 卷入哈希,封死中间人篡改路径。
2. 引入高熵复合密钥:结合 CHAT_ID 与 TG_TOKEN,大幅提升抗暴力破解强度。
3. 实现全自动改名闭环:Master 确认 Agent 修改成功后自动同步数据库,彻底告别手动复制。
2026-04-16 03:14:12 +00:00
hotyue
9768bed637 fix(master): [v3.5.2] 废除原生 tr 命令的失效中文白名单,改用黑名单过滤,确保中文字符完美送入 Base64 编码 2026-04-16 02:43:52 +00:00
hotyue
fa202a0405 fix(core): [v3.5.2] 采用 Base64 编码彻底重构别名同步链路,免疫 WAF 拦截与中英文符号解析崩溃 2026-04-16 02:24:50 +00:00
hotyue
b8bcd09134 fix(agent): [v3.5.2] 修复别名同步时的中文 UTF-8 编码崩溃,改用 curl 绕过 WAF 拦截,并拦截下划线防止 TG 面板渲染异常 2026-04-16 01:55:57 +00:00
hotyue
ef8dc033cc feat(master): [v3.5.2] 中枢支持解析 6 字段注册包,面板适配别名并新增重命名状态机 (Resolves #9) 2026-04-16 01:35:16 +00:00
hotyue
03a54bcca0 chore(master): [v3.5.2] 完善全新部署时的 SQLite 表结构 (增加 region 与 node_alias) 2026-04-16 01:35:16 +00:00
hotyue
f4f93d8955 feat(agent): [v3.5.2] 每日战报全面适配 NODE_ALIAS 展示字段 2026-04-16 01:35:16 +00:00
hotyue
07cac792f0 feat(agent): [v3.5.2] 守护进程新增 /trigger_rename 接口,实现免注入安全重命名 2026-04-16 01:35:16 +00:00
hotyue
50edad9e25 feat(agent): [v3.5.2] 部署引擎引入双轨身份,支持自定义节点展示别名 2026-04-16 01:35:16 +00:00
hotyue
69edf12620 feat(map): [v3.5.2] 全球大地图更新,正式集成台湾 (TW) 及美国本土 6 大新州节点 2026-04-16 01:35:16 +00:00
hotyue
0b448e2b7e data(US): [v3.5.2] 深度扩容美国版图,新增 IL, UT, WA, NV, NC, OR 六大节点 (Resolves #15, 感谢 NQ 论坛 @yct002, @Ideal 提交的需求) 2026-04-16 01:35:16 +00:00
github-actions[bot]
d7b95136dd data(TW): [v3.5.2] 新增台湾战区数据与台北锚点 (Resolves #11) 2026-04-16 01:35:16 +00:00
github-actions[bot]
80d74111c4 chore(data): 🤖 自动机兵:刷新全战区热点词库 [2026-04-15] 2026-04-15 19:37:24 +00:00
hotyue
223d7c4b56 docs(readme): 更新项目架构图,同步 v3.5.1 双端版本解耦信标说明 2026-04-15 06:47:43 +00:00
hotyue
de3b4ca6d3 chore: 正式发布 v3.5.1,引入双端版本解耦架构 (KV 解析法) 2026-04-15 06:15:59 +00:00
hotyue
423a765e5f feat(core): 引入 KV 环境分解法,实现 Agent 与 Master 版本独立解耦 2026-04-15 05:58:28 +00:00
github-actions[bot]
ca74c31b96 chore(data): 🤖 自动机兵:刷新全战区热点词库 [2026-04-15] 2026-04-15 04:50:05 +00:00
hotyue
9366240d62 chore: 正式发布 v3.5.0,整合大洲战区架构与全球版图扩张 (NL, ES, CA, VN) 2026-04-15 04:39:43 +00:00
hotyue
1fa2cd10b1 feat(map): 全球版图正式扩充,集成 VN, NL, ES, CA 节点并修正更新日期 2026-04-15 04:36:52 +00:00
hotyue
3210c8cfcc data(VN): 新增越南 (Vietnam) 战区数据与核心规则 2026-04-15 04:35:22 +00:00
hotyue
d7e1e8fc8f data(CA): 新增加拿大 (Canada) 战区数据与核心规则 2026-04-15 04:35:12 +00:00
hotyue
a81f0564f1 data(ES): 新增西班牙 (Spain) 战区数据与核心规则 2026-04-15 04:35:04 +00:00
hotyue
3b20630e9e data(NL): 新增荷兰 (Netherlands) 战区数据与核心规则 2026-04-15 04:33:17 +00:00
hotyue
7321b76bb5 fix(scripts): 升级热搜词抓取引擎,适配 v3.5.0 大洲战区多层级解析 2026-04-15 04:25:25 +00:00
hotyue
8016b0531c docs(readme): 全面同步 v3.5.0 特性,更新大洲战区贡献规范与 SSOT 架构说明 2026-04-15 03:57:18 +00:00
hotyue
c7c93ea22e refactor(core): 全面肃清硬编码版本注释,适配动态锚点架构 2026-04-15 03:57:12 +00:00
hotyue
9aef79831c refactor(daemon): 动态注入节点防撞身份与运行时版本号至 UA 请求头及交互播报中 2026-04-15 03:57:02 +00:00
hotyue
43f2e98459 refactor(master): 剥离写死版本,严格落实运行态配置继承,优化卸载进程绞杀逻辑 2026-04-15 03:56:55 +00:00
hotyue
5627c0115a feat(installer): 引入 SSOT 动态版本抓取机制,并重构边缘节点战区分组交互 UI 2026-04-15 03:56:45 +00:00
hotyue
f252b26088 feat(data): 重构 map.json 至 v3.5.0 大洲战区 (Continental Grouping) 降维拓扑架构 2026-04-15 03:56:36 +00:00
github-actions[bot]
12e6619ab9 chore(data): 🤖 自动机兵:刷新全战区热点词库 [2026-04-14] 2026-04-14 19:26:11 +00:00
hotyue
a0bad1acf0 docs: 📝 更新 README 以适配 v3.4.0 架构特性与版本路由逻辑 2026-04-14 08:26:31 +00:00
hotyue
01d65972fd feat(master): 🗑️ Master 卸载程序同步 v3.4.0 焦土逻辑 2026-04-14 08:00:48 +00:00
hotyue
b1334fc06a feat(master): 🤖 调度中枢 UI 重构,接入 v3.4.0 实时版本监控 2026-04-14 08:00:47 +00:00
hotyue
918c73b5dc feat(master): 🧠 中枢安装脚本实现版本号补录与无损热升级 2026-04-14 08:00:47 +00:00
hotyue
28f04a4eb9 feat(core): 🗑️ 卸载脚本增加版本感知识别逻辑 2026-04-14 08:00:41 +00:00
hotyue
26328e66c4 feat(core): 🛡️ Trust 净化模块同步 v3.4.0 版本追踪标识 2026-04-14 08:00:40 +00:00
hotyue
1d85837e79 feat(core): 📍 Google 养护模块日志格式化对齐 v3.4.0 2026-04-14 08:00:40 +00:00
hotyue
ba8e2f1625 feat(core): 📊 战报模块注入云端版本感知与 OTA 提醒 2026-04-14 08:00:40 +00:00
hotyue
6b809138e5 feat(core): 🔄 更新引擎同步 v3.4.0 版本锚点架构 2026-04-14 08:00:40 +00:00
hotyue
6f4e871c7c feat(core): ⏱️ 调度引擎注入版本探针日志追踪 2026-04-14 08:00:40 +00:00
hotyue
fe2c9de80b fix(core): 🐍 守护进程同步 v3.4.0 标识并修正节点命名连接符 2026-04-14 08:00:40 +00:00
hotyue
6c0a589395 feat(core): 🚀 部署引擎升级至 v3.4.0 (引入版本路由与状态机) 2026-04-14 08:00:40 +00:00
hotyue
42a128fd6b feat: 🚩 建立云端版本锚点 v3.4.0 2026-04-14 08:00:32 +00:00
hotyue
a891f2017a fix(core): 🚑 替换节点命名连接符为中划线,彻底修复 Telegram Markdown V1 解析崩溃 Bug 2026-04-14 06:58:00 +00:00
hotyue
66fdfb1908 fix(install): 🐛 修复热更新节点失联问题,引入静默兼容基因锁 2026-04-14 06:44:17 +00:00
hotyue
aa2874fdcd chore(master): ⬆️ 对齐主控端安装脚本头部版本号 2026-04-14 06:18:12 +00:00
hotyue
120dd264c2 feat(master): 扩充全球战区国旗字典,完美适配无界战区版图的 UI 渲染 2026-04-14 06:17:24 +00:00
hotyue
455f98fafd fix(report): 🐛 同步防撞甲逻辑,确保每日战报身份代号与初始注册绝对统一 (v3.3.2) 2026-04-14 06:17:20 +00:00
hotyue
2c1041ebed fix(install): 🐛 引入 IP 指纹哈希防撞机制,粉碎克隆节点同名覆盖 Bug (v3.3.2) 2026-04-14 06:17:15 +00:00
github-actions[bot]
0af3ff5cd8 chore(data): 🤖 自动机兵:刷新全战区热点词库 [2026-04-13] 2026-04-13 19:22:53 +00:00
hotyue
6faa7b2c2a fix(install): 🚑 引入老版本配置无损热迁移装甲,确保 NAT 修复特性在平滑升级中完美生效 2026-04-13 12:10:34 +00:00
hotyue
873b6996ca chore(updater): ⬆️ 对齐脚本头部版本号至 v3.3.1 2026-04-13 12:06:16 +00:00
hotyue
84832395bd fix(daemon): 🔇 引入公网 IP 兜底机制,彻底拦截因 API 探测失败导致的幽灵注册风暴 2026-04-13 12:06:16 +00:00
hotyue
96a7400be8 fix(trust): 🐛 净化模块同步修复哈希种子逻辑,确保活体设备唯一性 2026-04-13 12:06:16 +00:00
hotyue
ba565978c6 fix(google): 🐛 重写哈希种子提取逻辑,彻底杜绝 NAT 节点指纹同质化灾难 2026-04-13 12:06:16 +00:00
hotyue
b53032cc92 fix(report): 🐛 战报 IP 探测接入 PUBLIC_IP 兜底,完美兼容 NAT 架构 2026-04-13 12:06:16 +00:00
hotyue
e96eacd6f8 feat(install): 重构网络锚定逻辑,引入双核身份剥离与双栈 NAT 嗅探 2026-04-13 12:06:16 +00:00
github-actions[bot]
4cac51673a chore(data): 🤖 自动机兵:刷新全战区热点词库 [2026-04-13] 2026-04-13 08:37:41 +00:00
hotyue
be75e5b65c fix(scripts): 🐛 修复地图解析逻辑,深度穿透 JSON 锁定真实战区 2026-04-13 08:37:12 +00:00
hotyue
c7ece6620c chore(test): 故意制造数据缺口,诱导自动机兵修复 2026-04-13 08:30:07 +00:00
hotyue
7e9da4b82a ci(workflows): 🔧 修复 Actions 推送逻辑,适配 main 分支保护规则 2026-04-13 08:27:33 +00:00
hotyue
c657c92b27 docs(readme): 📝 更新特性列表,加入 OTA 动态活体词库与智能错峰调度说明 2026-04-13 08:18:16 +00:00
hotyue
d43163703e chore(master): ⬆️ 对齐主控端版本号至 v3.3.0 2026-04-13 08:18:10 +00:00
hotyue
1150450718 feat(core): 🚀 升级 Agent 安装脚本,注入错峰时间戳与每日调度 Cron 2026-04-13 08:18:05 +00:00
hotyue
df6483afa8 feat(core): 🔄 升级 updater 引入每日词库同步与指纹库 30 天错峰调度 2026-04-13 08:17:58 +00:00
hotyue
29de2eadf8 ci(workflows): 🤖 部署 OTA 动态词库每日自动生成流水线 2026-04-13 08:17:51 +00:00
hotyue
318689f163 feat(scripts): 🐍 新增 Google Trends 动态热搜抓取引擎 2026-04-13 08:17:47 +00:00
59 changed files with 5028 additions and 562 deletions

49
.github/workflows/daily_keywords.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: Daily Data Factory
on:
schedule:
# 每天 UTC 18:00 (北京时间凌晨 02:00) 执行赶在节点凌晨3点更新前造好子弹
- cron: '0 18 * * *'
workflow_dispatch:
permissions:
contents: write
jobs:
update-data:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Execute Trends Engine (搜索词库)
run: python scripts/fetch_trends.py
- name: Execute Trust URL Engine (活体新闻流融合)
run: python scripts/fetch_trust_urls.py
- name: Commit and Push All Data
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
# 一揽子添加搜索词库和地区白名单的变化
git add data/keywords/
git add data/regions/
# 防御机制:如果没有新数据,就静默退出,不产生空提交
if git diff --staged --quiet; then
echo "No changes, skipping."
exit 0
fi
# 策略:将两路数据的更新合并为一个原子提交
git commit -m "chore(data): 🤖 自动机兵:同步全战区热点词库与活体新闻流 [$(date +'%Y-%m-%d')]"
git push origin main

129
README.md
View File

@@ -10,33 +10,22 @@
专为解决 VPS IP 被 Google 等数据库错误定位到中国大陆/香港俗称“送中”等问题而生。IP-Sentinel 已从单机脚本全面跃升为 **Master-Agent 分布式架构**。它像影子一样潜伏在全球各地的服务器后台,通过高度拟真的真实用户行为为你默默积累 IP 权重,并允许你通过 Telegram 随时随地对整个舰队进行毫秒级“点名”与“遥控”。
## ✨ 核心极客特性
## ✨ 核心极客特性 (Core Architecture)
- 🗺️ **全球拓扑矩阵 (Global Nexus)**v3.1 跨洲际跃升。守护版图现已横跨亚、欧、美三大洲(美、日、英、德、法、新、港)。为每个国家注入极其硬核的“原生本地化”搜索词库与本土高权重站点(如政府、权威媒体、高铁网),真正实现“拟真融入”
- **无损高并发引擎 (WAL Concurrency)**:司令部 SQLite 数据库全面激活 `WAL` (Write-Ahead Logging) 模式与毫秒级排队削峰算法。即使您同时对 500 台边缘节点发起全军总攻,也能完美规避 `database is locked` 与 Telegram `429` 频率拦截,实现 100% 战报送达
- 🪶 **抽脂级极简部署 (Zero-Bloat Native)**:全栈剔除 `pip``flask` 等臃肿第三方依赖,完全基于 Python3 原生标准库运行。安装底层强制注入 `--no-install-recommends` 防捆绑参数。无论是 128MB 内存的极简 NAT 小鸡,还是 Alpine/Arch Linux 特种系统,均可如丝般顺滑运行。
- 🎛️ **扁平化指挥矩阵 (Flat Command Matrix)**[v3.6.1 重构] 引入扁平化 L0-L3 四级战区降维视图与双轨身份制。深度定制 Inline Keyboard 逃生舱交互,支持在统一哨兵终端进行原位丝滑重绘 (In-place UI Edit),实现毫秒级模块热启停与日志抓取,彻底告别刷屏烦恼。
- 🔄 **全栈零信任 OTA 引擎 (Zero-Trust OTA Upgrade)**:首创双端物理熔断机制。长官可通过私有中枢,一键向全舰队下发静默热重载指令;更支持**「司令部金蝉脱壳」**,中枢大脑可在此面板自我抛出幽灵进程进行免交互直装覆盖,实现真正的全栈去 SSH 化运维。
- 🛡️ **SSOT 溯源与热更新装甲 (Smooth Upgrade Engine)**:全系脚本彻底消灭硬编码,部署时动态抓取云端版本信标。自带状态机嗅探逻辑与防撞甲探测,即使是手动在终端运行安装,也仅需回车瞬间完成配置继承、数据同步与无损换代。
- 🗺️ **全球拓扑矩阵与活体词库 (Global Nexus)**:守护版图横跨亚欧美三大洲。接入 GitHub Actions 云端流水线,每日静默同步全球各大区当日 Google 真实热搜榜单与高权重本土站点,让伪装行为永远贴合当地网络脉搏。
- 👻 **资产持久化与错峰调度 (Hash-Seeded Persona)**:摒弃随机抽取指纹,基于节点物理 IP 哈希永久锁定 3 个绝对专属设备,完美构建高权重真实家庭内网画像。叠加按需智能分频与随机防并发休眠,化解“惊群效应”。
- 🖧 **底层路由死锁与高精度探针 (Hard-Bind Routing)**:底层探测引擎强力接管 curl 核心参数 (`--interface`),将发出的每一滴伪装流量死死绑定在物理网卡或隧道 IP 上。配合多级 ISP 容灾链路,彻底杜绝双栈环境下的流量溢出与 API 误判。
- 👻 **设备资产持久化 (Hash-Seeded Persona)**v3.2 核心换代。彻底摒弃传统的“随机抽取指纹”,引入基于节点物理 IP 的哈希锚定引擎。利用不可变哈希种子,为您的每台 VPS 在千万级指纹库中永久锁定 3 个绝对专属设备(如固定表现为 1台 Mac、1台 iPhone、1台 PC 交替上网)。完美构建高权重真实家庭内网画像,根除“僵尸网络”同质化特征!
- 🏭 **自动化指纹兵工厂 (Automated UA Factory)**:依托 GitHub Actions CI/CD 流水线,每月 1 日无人值守全自动生成 4000+ 带绝对物理分区的真实终端设备数据。配合边缘节点的守护进程静默拉取,实现千万级指纹资产的“自动驾驶”级演进
- 🖧 **底层路由死锁 (Hard-Bind Routing)**v3.2.1 热修复升级。底层探测引擎强力接管 curl 核心参数 (--interface),强制将发出的每一滴伪装流量死死绑定在您设定的物理网卡或隧道 IP 上,彻底杜绝双栈或多网卡环境下的流量溢出漏洞
- 🎯 **多级容灾与高精度探针 (High-Precision Probe)**v3.2.2 底层重构。重写战报模块与底层协议自适应逻辑,植入多级 ISP 容灾探针链路,并按“底层数据共识原则”智能清洗冗余 AS 号。确保在纯 V6、隧道或弱网环境下数据获取依然 100% 精准畅通。
- 🔄 **平滑热更新装甲 (Smooth Upgrade Engine)**v3.2.2 体验进化。全系植入状态机嗅探逻辑。无论是 Master 司令部还是 Agent 边缘节点再次执行部署脚本时将自动识别并继承历史配置、SQLite 数据库与锚定 IP一键回车即可瞬间完成无损换代告别繁琐的重复配置。
- ☁️ **云端中枢 (Public Master)**:引入官方公共机器人 @OmniBeacon_bot,新手无需部署 Master 司令部,部署 Agent 时一键回车即可调用官方加密网关30 秒极速入伍!
- 🧠 **分布式中枢 (Master-Agent)**:对于硬核极客,支持私有化部署。一台 Master 主控集成 SQLite 数据库,统管无数台 Agent 边缘节点,确保数据绝对私有。
- 🔒 **叹息之墙 (Zero-Trust HMAC)**:全面废弃明文 Token底层通讯引入 时间戳 + HMAC-SHA256 军用级动态签名。指令有效期仅 60 秒(阅后即焚),彻底免疫中间人抓包、重放攻击与端口爆破。
- 🛡️ **工业级并发与自净引擎**:底层 Webhook 采用多线程模型彻底免疫慢速耗尽攻击;独创“智能清道夫”逻辑,覆盖安装/升级时自动绞杀僵尸进程与冗余定时任务,绝对纯净,告别玄学冲突。
- 🎮 **TG 战术面板 (Command Center)**:无需记忆繁琐命令,全 Inline Keyboard 交互。支持一键下发伪装指令、一键索要精准战报、毫秒级抓取边缘节点实时运行日志。
- 👁️‍🗨️ **玻璃房透明遥测 (Glasshouse Telemetry)**:引入基于 Cloudflare Workers 的全透明计数中枢,首页动态徽章实时展示全球真实装机与调用量。绝对零隐私收集,仅作原子累加,底层网关源码全开源,接受全网极客审计。
-**丝滑战术交互 (Seamless UI)**:司令部交互面板像素级打磨。新节点发送暗号入伍成功后,司令部将无缝零延迟自动呼出最新的活跃节点阵列面板,彻底免除重复输入命令的繁琐,掌控感拉满。
**—— 💎 骨干基建特征 ——**
- 🏭 **自动化指纹兵工厂**:依托 GitHub Actions CI/CD 流水线,每月 1 日无人值守锻造 4000+ 带绝对物理分区的真实终端设备数据。
- 🔒 **叹息之墙 (Zero-Trust HMAC)**:底层通讯引入 时间戳 + HMAC-SHA256 军用级动态签名。指令有效期仅 60 秒(阅后即焚),未授权请求直接触发系统级 403 物理熔断,彻底免疫中间人抓包与重放攻击
- ☁️ **云端中枢 (Public Master)**:官方公共机器人 [@OmniBeacon_bot](https://t.me/OmniBeacon_bot) ,新手免自建,一键接入极速入伍!同时支持硬核极客私有化 SQLite 分布式部署。
- 👁️‍🗨️ **玻璃房透明遥测 (Glasshouse)**:基于 Cloudflare Workers 的全透明计数中枢,绝对零隐私收集,仅作原子累加,底层网关源码全开源
## 📂 项目架构 (Monorepo)
@@ -49,52 +38,64 @@
┣ 📂 core/ # 🛡️ 边缘哨兵Webhook 被动监听、哈希锚定执行引擎
┣ 📂 scripts/ # 🐍 兵工厂引擎:基于 Python 的多物理分区 UA 生成器
┣ 📂 data/ # 🗂️ 全球数据规则库 (动态拓扑)
┃ ┣ 📜 map.json # 🌐 全球区域索引大脑 (Master Index)
┃ ┣ 📜 map.json # 🌍 全球区域大脑 (v3.5.0 大洲战区拓扑)
┃ ┣ 📂 regions/ # 🧊 冷数据:按 [国家/省州/城市] 深度细分的 LBS 锚点
┃ ┣ 📂 keywords/ # 🔥 热数据:按国家归类的动态搜索词库 (OTA 自动更新)
┃ ┗ 📜 user_agents.txt # 🔥 热数据:由兵工厂每月锻造的绝对坐标专属设备库
┣ 📜 version.txt # 🚩 双端版本信标Agent/Master 独立解耦的 KV 环境配置
┗ 📂 telemetry/ # 👁️‍🗨️ 玻璃房计划Cloudflare Workers 透明计数器网关源码
```
## 🚀 极速部署 (Quick Start)
> 🛡️ **跨平台装甲支持**Debian / Ubuntu / CentOS / RHEL / Alpine Linux / Arch Linux
系统现提供两种接入模式,请根据您的战术需求选择:
v3.2.x 提供了两种接入模式,请根据您的战术需求选择:
### 🔹 模式 A私有独立模式 (全自主、强烈推荐)
适合追求绝对数据隐私与舰队最高控制权的领主。
### 🔹 模式 A官方公共模式 (最简、推荐)
**适合不想折腾、只想快速养护 IP 的新兵。**
1. **关注机器人**:在 TG 中关注 [@OmniBeacon_bot](https://t.me/OmniBeacon_bot) 并发送 `/start`
2. **部署 Agent**:在目标 VPS 上执行以下指令,安装过程中**直接回车**使用官方机器人,并输入您的 Chat ID
```Bash
bash <(curl -sL https://raw.githubusercontent.com/hotyue/IP-Sentinel/main/core/install.sh)
> ☢️ **核按钮系统已就绪**:采用私有部署,您将解锁 **OTA 远程静默升级** 权限!所有私有前线节点均可通过您的 TG 面板实现一键全网代码热重载换代!
- **部署 Master (中枢大脑)**:找一台 VPS 作为司令部(仅需部署一台),执行:
```bash
curl -fsSL https://raw.githubusercontent.com/hotyue/IP-Sentinel/main/master/install_master.sh -o /tmp/ins_master.sh && sudo bash /tmp/ins_master.sh
```
3. **激活节点**:安装完成后,您的手机会收到一条 #REGISTER# 暗号,将其转发给机器人即可完成入库。
- 部署 Agent (边缘哨兵):在需要养护的机器上执行 Agent 脚本,安装时选择私有独立中枢,并分别输入您自建机器人的 [Token](https://blog.iot-architect.com/engineering-practice/create-private-telegram-bot-via-botfather) 以及您的个人 [Chat ID](https://blog.iot-architect.com/engineering-practice/get-telegram-personal-id-via-userinfobot)
### 🔸 模式 B私有独立模式 (全自主、硬核)
**适合追求绝对数据隐私、需自建机器人的领主。**
1. **部署 Master**:找一台 VPS 作为大脑(仅需部署一台),执行:
```Bash
bash <(curl -sL https://raw.githubusercontent.com/hotyue/IP-Sentinel/main/master/install_master.sh)
curl -fsSL https://raw.githubusercontent.com/hotyue/IP-Sentinel/main/core/install.sh -o /tmp/ins_agent.sh && sudo bash /tmp/ins_agent.sh
```
2. **部署 Agent**:在需要养护的机器上执行 Agent 脚本,输入您自建机器人的 Token 以及与 Master 一致的配置
- 激活节点:安装完成后,您的手机会收到一条 #REGISTER# 注册暗号,将其转发给您自己的机器人即可完成编队入库
### 🔸 模式 B官方公共模式 (最简体验)
适合不想折腾、只想快速体验养护效果的新兵。
- 关注机器人:在 TG 中关注官方安全网关 [@OmniBeacon_bot](https://t.me/OmniBeacon_bot) 并发送 /start。
- 部署 Agent在目标 VPS 上执行以下指令,安装过程中选择官方公共网关,并输入您的 Chat ID
```Bash
bash <(curl -sL https://raw.githubusercontent.com/hotyue/IP-Sentinel/main/core/install.sh)
curl -fsSL https://raw.githubusercontent.com/hotyue/IP-Sentinel/main/core/install.sh -o /tmp/ins_agent.sh && sudo bash /tmp/ins_agent.sh
```
3. **激活节点**:同上,将暗号转发给您自己的机器人即可。
- 激活节点:同上,将收到的暗号转发给官方机器人即可。
### ⚠️ 平滑升级指引 (Upgrade to v3.2.2)
## 🆙 架构级无损热升级指引 (Upgrade Guide)
得益于 **v3.2.2 全新引入的平滑热更新引擎 (Smooth Upgrade Engine)**,系统升级现已变得极其优雅与安全。
### 📡 方式一OTA 远程静默升级 (私有中枢专属)
如果您是私有中枢领主,当司令部首页 (`/start`) 或每日战报提示发现新版本时:
无需卸载旧版本,无论您是要升级 Agent 边缘节点还是 Master 控制中枢,只需在您的终端中**再次运行上方对应的官方部署指令**
1. **升级 Master 司令部自身**:在司令部顶级菜单,点击最上方的 `[ 🆙 升级司令部至 vX.X.X ]`。中枢将释放幽灵进程静默重构,数秒后向您发送捷报
2. **升级全舰队 Agent**:在司令部顶级菜单,点击 `[ ☢️ 全舰队 OTA 热重载 ]`
3. **升级单节点 Agent**:进入 `🌍 全球战区雷达` -> 选择目标节点 -> 在统一终端面板点击 `[ 🆙 OTA 静默升级 ]`
*(⚠️ 节点收到指令后会在后台挂起静默拉取,全程无需登录 SSH完成后将主动发回心跳确认)*
安装雷达会自动嗅探您的历史部署状态(包括您的 Token、区域设定、SQLite 数据库及物理网卡锚点)。当询问是否平滑升级时,您只需**一路回车 (默认选 y)**,脚本将在短短 3 秒内瞬间完成核心装甲的无损换脑手术,您的所有战术资产将得到 100% 保留!
### 💻 方式二SSH 终端平滑直装 (适用于官方网关或老旧节点)
如果您的节点不支持 OTA或者您的节点版本过于陈旧 (如 v3.3.1)
🗑️ 一键无痕卸载
- 登录该节点的 SSH 终端,再次运行上面的 core/install.sh 官方安装指令。
- 安装引擎自带状态机嗅探逻辑它会自动读取老旧数据您只需一路回车3 秒即可在本地完成配置继承、数据同步与新内核的无损覆盖热重载!
## 🗑️ 一键无痕卸载
如果你需要清理某个边缘节点,只需重新运行 `core/install.sh` 并选择 **[2]**,或直接在节点终端执行:
```Bash
@@ -102,7 +103,7 @@ bash /opt/ip_sentinel/core/uninstall.sh
```
### 🧓 传家宝老旧系统专用通道 (Debian 9)
## 🧓 传家宝老旧系统专用通道 (Debian 9)
如果你的小鸡系统版本过低(如 Debian 9由于官方 APT 源已关闭且 Python 版本过旧,无法使用主线版本,请使用 **Legacy 兼容分支** 部署。
*(注意:该分支仅作基础维护,不享受新功能迭代,请尽可能升级你的系统)*
@@ -111,20 +112,36 @@ bash /opt/ip_sentinel/core/uninstall.sh
bash <(curl -sL https://raw.githubusercontent.com/hotyue/IP-Sentinel/legacy/core/install.sh)
```
📡 战术联络 (Community)
## 📡 战术联络 (Community)
如果你在使用过程中遇到任何疑难杂症,或者想围观大佬们的养护战报,欢迎加入我们的基地:
- Telegram 频道: [@IP_Sentinel_Matrix](https://t.me/IP_Sentinel_Matrix)
🤝 参与贡献
如果你想为项目增加新的节点区域(例如德国、英国、新加坡等),或者提供更丰富的本土化搜索词库,非常欢迎提交 Pull Request
## 🤝 参与贡献 (Contributors)
**v3.0 全球节点贡献规范:**
**🌟 感谢以下所有为 IP-Sentinel 添砖加瓦的指挥官们!** 你们的每一次 PR 都在让这艘战舰的全球雷达覆盖得更广。
<a href="https://github.com/hotyue/IP-Sentinel/graphs/contributors">
<img src="https://contrib.rocks/image?repo=hotyue/IP-Sentinel" alt="Contributors" />
</a>
如果你想为项目增加新的节点区域(例如德国、英国、大洋洲等),或者提供更丰富的本土化搜索词库,非常欢迎提交 Pull Request
**💡 全球节点贡献规范:**
1.`data/regions/国家代码/省州代码/` 目录下新增对应城市的配置 `.json`
2.`data/keywords/` 目录下新增或完善配套国家的词库 `kw_XX.txt`
3. **最重要的一步:**`data/map.json` 中登记你的国家、省州与城市信息。安装脚本将自动读取地图,在全球雷达中点亮你的节点!
⚠️ 免责声明
## ⚠️ 免责声明
本项目仅供网络原理研究、个人 VPS 维护学习使用。请遵守当地法律法规及目标服务商的 TOS服务条款切勿用于恶意高频请求或任何非法用途。使用者需自行承担因不当使用造成的 IP 封禁或其他相关风险。
## 保持联系
[![Blog](https://img.shields.io/badge/Blog-个人博客-blue)](https://blog.iot-architect.com)
如果你觉得这个项目对你有帮助,欢迎关注我的个人博客,我会定期分享技术教程。
## Stargazers over time
[![Stargazers over time](https://starchart.cc/hotyue/IP-Sentinel.svg?variant=adaptive)](https://starchart.cc/hotyue/IP-Sentinel)

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# ==========================================================
# 脚本名称: agent_daemon.sh (受控节点 Webhook 守护进程 V3.0.3)
# 脚本名称: agent_daemon.sh (受控节点 Webhook 守护进程 - 动态锚点版)
# 核心功能: 智能防打扰注册、进程自检、模块级路由分发(403拦截)
# ==========================================================
@@ -17,21 +17,26 @@ source "$CONFIG_FILE"
# 默认 Webhook 监听端口
AGENT_PORT=${AGENT_PORT:-9527}
NODE_NAME=$(hostname | cut -c 1-15)
# --- [重点升级 1: 守护进程防冲突自检] ---
if pgrep -f "webhook.py $AGENT_PORT" > /dev/null; then
exit 0
# [v3.5.2 核心] 载入不可变主键与可变展示名 (双轨身份)
if [ -z "$NODE_NAME" ]; then
IP_HASH=$(echo "${PUBLIC_IP:-127.0.0.1}" | md5sum | cut -c 1-4 | tr 'a-z' 'A-Z')
NODE_NAME="$(hostname | tr -cd 'a-zA-Z0-9' | cut -c 1-10)-${IP_HASH}"
fi
NODE_ALIAS="${NODE_ALIAS:-$NODE_NAME}"
# 1. [v3.0.1修复] 严格按照 install.sh 锁定的网络协议 (v4/v6) 获取 IP
# 1. 尝试获取实时公网 IP
RAW_IP=$(curl -${IP_PREF:-4} -s -m 5 api.ip.sb/ip | tr -d '[:space:]')
# 为新获取到的 v6 自动加方括号,以确保与之前锁定的格式对齐比对
if [[ "$RAW_IP" == *":"* ]] && [[ "$RAW_IP" != *"["* ]]; then
AGENT_IP="[${RAW_IP}]"
# [v3.3.1 修改] 为新获取到的 v6 自动加方括号;如果网络波动没抓到,强制信任本地 config 中的公网面孔
if [ -n "$RAW_IP" ]; then
if [[ "$RAW_IP" == *":"* ]] && [[ "$RAW_IP" != *"["* ]]; then
AGENT_IP="[${RAW_IP}]"
else
AGENT_IP="$RAW_IP"
fi
else
AGENT_IP="$RAW_IP"
AGENT_IP="${PUBLIC_IP:-${BIND_IP:-Unknown}}"
fi
if [ -n "$AGENT_IP" ]; then
@@ -41,8 +46,8 @@ if [ -n "$AGENT_IP" ]; then
# 只有当这是第一次运行,或者公网 IP 发生变动时,才发送 Telegram 申请
if [ "$AGENT_IP" != "$LAST_IP" ]; then
# V3.1.3 协议升级: 在底部暗号中精准嵌入 ${REGION_CODE} 大区标识
REG_MSG="👋 **[边缘节点接入申请]**%0A大区: \`${REGION_CODE}\`%0A节点: \`${NODE_NAME}\`%0A地址: \`${AGENT_IP}:${AGENT_PORT}\`%0A%0A⚠ **安全验证**: 为防止非法节点接入,请长按复制下方代码,并**发送给我**以完成最终授权录入:%0A%0A\`#REGISTER#|${REGION_CODE}|${NODE_NAME}|${AGENT_IP}|${AGENT_PORT}\`"
# [v3.5.2 核心] 携带 6 字段双轨身份发起注册申请 (展示别名,暗号尾部追加 NODE_ALIAS)
REG_MSG="👋 **[边缘节点接入申请]**%0A大区: \`${REGION_CODE}\`%0A节点: \`${NODE_ALIAS}\`%0A地址: \`${AGENT_IP}:${AGENT_PORT}\`%0A%0A⚠ **安全验证**: 为防止非法节点接入,请长按复制下方代码,并**发送给我**以完成最终授权录入:%0A%0A\`#REGISTER#|${REGION_CODE}|${NODE_NAME}|${AGENT_IP}|${AGENT_PORT}|${NODE_ALIAS}\`"
curl -s -m 5 -X POST "${TG_API_URL}" \
-d "chat_id=${CHAT_ID}" \
@@ -56,6 +61,20 @@ if [ -n "$AGENT_IP" ]; then
fi
fi
# ================== [v3.6.3 新增: 自动生成自签名 TLS 加密证书] ==================
# [修复] 仅在私有中枢模式下生成证书。官方网关模式下CF Worker 严格拒绝自签名,必须回退 HTTP
if [ "$TG_TOKEN" != "OFFICIAL_GATEWAY_MODE" ]; then
CERT_FILE="${INSTALL_DIR}/core/cert.pem"
KEY_FILE="${INSTALL_DIR}/core/key.pem"
if [ ! -f "$CERT_FILE" ] || [ ! -f "$KEY_FILE" ]; then
echo "🔐 [Agent] 正在生成本地自签名 TLS 加密证书 (2048位 RSA)..."
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout "$KEY_FILE" -out "$CERT_FILE" \
-subj "/C=US/O=IP-Sentinel/CN=Agent-Sec" >/dev/null 2>&1 || true
fi
fi
# ==============================================================================
# 3. 启动轻量级 Python3 Webhook 监听服务 (v3.0.4 动态 HMAC 签名防重放)
cat > "${INSTALL_DIR}/core/webhook.py" << 'EOF'
import http.server
@@ -200,8 +219,11 @@ class AgentHandler(http.server.BaseHTTPRequestHandler):
if lines:
log_data = html.escape("".join(lines[-15:]))
node_name = subprocess.check_output(['hostname']).decode('utf-8').strip()[:15]
text_msg = f"📄 <b>[{node_name}] 实时运行日志:</b>\n<pre><code>{log_data}</code></pre>"
# [v3.5.2 核心] 获取版本与节点展示别名
local_ver = config.get('AGENT_VERSION', '未知')
node_alias = config.get('NODE_ALIAS', config.get('NODE_NAME', 'Unknown-Node'))
text_msg = f"📄 <b>[{node_alias}] 实时日志 (v{local_ver}):</b>\n<pre><code>{log_data}</code></pre>"
data = urllib.parse.urlencode({
'chat_id': config.get('CHAT_ID', ''),
@@ -212,13 +234,196 @@ class AgentHandler(http.server.BaseHTTPRequestHandler):
req = urllib.request.Request(
config.get('TG_API_URL', ''),
data=data,
headers={'User-Agent': 'IP-Sentinel-Agent/3.0.4'}
# [动态化] 彻底消灭硬编码,使用运行态版本号
headers={'User-Agent': f'IP-Sentinel-Agent/{local_ver}'}
)
urllib.request.urlopen(req, timeout=10)
except Exception as e:
print(f"Log transmission failed: {e}")
# 路由 5: 节点重命名展示别名同步接口 (Base64 终极防御版)
elif req_path == '/trigger_rename':
b64_alias = query.get('b64', [''])[0]
if not b64_alias:
self.send_response(400)
self.end_headers()
self.wfile.write(b"400 Bad Request: Alias is empty\n")
return
import re
import base64
try:
# 1. 还原 URL 安全的 Base64 字符并解码 (杜绝乱码与 WAF 拦截)
pad = len(b64_alias) % 4
if pad > 0:
b64_alias += '=' * (4 - pad)
b64_alias = b64_alias.replace('-', '+').replace('_', '/')
raw_alias = base64.b64decode(b64_alias).decode('utf-8', errors='ignore')
# 2. 强清洗:杜绝 TG Markdown 崩溃严格限制中英数最大20字符
decoded_alias = raw_alias.replace('_', '-')
safe_alias = re.sub(r'[^a-zA-Z0-9\-\u4e00-\u9fa5]', '', decoded_alias)[:20]
if safe_alias:
# 3. 强容错读写 config.conf (引入 fcntl 排他锁与 r+ 模式防并发清空)
config_path = '/opt/ip_sentinel/config.conf'
import fcntl
with open(config_path, 'r+', encoding='utf-8', errors='ignore') as f:
fcntl.flock(f, fcntl.LOCK_EX)
lines = f.readlines()
alias_found = False
for i, line in enumerate(lines):
if line.startswith('NODE_ALIAS='):
lines[i] = f'NODE_ALIAS="{safe_alias}"\n'
alias_found = True
break
if not alias_found:
lines.append(f'NODE_ALIAS="{safe_alias}"\n')
f.seek(0)
f.writelines(lines)
f.truncate()
fcntl.flock(f, fcntl.LOCK_UN)
# [v3.5.2 极致丝滑] 移除向 TG 推送冗余报文的逻辑,直接向 Master 回执成功状态即可
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
self.wfile.write(b"Action Accepted: trigger_rename\n")
return
except Exception as e:
self.send_response(500)
self.end_headers()
self.wfile.write(f"500 Internal Error: {str(e)}\n".encode('utf-8'))
return
self.send_response(400)
self.end_headers()
self.wfile.write(b"400 Bad Request: Invalid Characters\n")
# ================== [v3.5.3 新增: 模块动态启停接口] ==================
elif req_path == '/trigger_toggle':
mod_name = query.get('mod', [''])[0]
target_state = query.get('state', [''])[0].lower()
if mod_name not in ['google', 'trust'] or target_state not in ['true', 'false']:
self.send_response(400)
self.end_headers()
self.wfile.write(b"400 Bad Request: Invalid parameters\n")
return
config_key = f"ENABLE_{mod_name.upper()}="
try:
config_path = '/opt/ip_sentinel/config.conf'
import fcntl
with open(config_path, 'r+', encoding='utf-8', errors='ignore') as f:
fcntl.flock(f, fcntl.LOCK_EX)
lines = f.readlines()
found = False
for i, line in enumerate(lines):
if line.startswith(config_key):
lines[i] = f'{config_key}"{target_state}"\n'
found = True
break
if not found:
lines.append(f'{config_key}"{target_state}"\n')
f.seek(0)
f.writelines(lines)
f.truncate()
fcntl.flock(f, fcntl.LOCK_UN)
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
self.wfile.write(b"Action Accepted: trigger_toggle\n")
except Exception as e:
self.send_response(500)
self.end_headers()
self.wfile.write(f"500 Internal Error: {str(e)}\n".encode('utf-8'))
# ================== [v3.6.0 新增: 零信任 OTA 远程静默升级路由] ==================
elif req_path == '/trigger_ota':
try:
# 动态读取最新 config 内存态
config_mem = {}
config_path = '/opt/ip_sentinel/config.conf'
if os.path.exists(config_path):
with open(config_path, 'r', errors='ignore') as f:
for line in f:
line = line.strip()
if '=' in line and not line.startswith('#'):
key, val = line.split('=', 1)
config_mem[key] = val.strip('"\'')
# 🛡️ 熔断校验 1: Agent 本地是否开启了 OTA 授权
if config_mem.get('ENABLE_OTA', 'false').lower() != 'true':
self.send_response(403)
self.end_headers()
self.wfile.write(b"403 Forbidden: OTA Upgrade Disabled locally\n")
return
# 🛡️ 熔断校验 2: 是否处于官方公共网关下 (强行硬编码拦截)
if config_mem.get('TG_TOKEN', '') == 'OFFICIAL_GATEWAY_MODE':
self.send_response(403)
self.end_headers()
self.wfile.write(b"403 Forbidden: OTA strictly disabled under Public Gateway mode\n")
return
# 校验通过,立即返回 200 回执,释放 Master 连接池
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
self.wfile.write(b"Action Accepted: trigger_ota\n")
# [修复] 逃逸 Systemd Cgroup并引入 bash -n 语法树校验防砖机制
import shutil
import base64
repo_url = "https://raw.githubusercontent.com/hotyue/IP-Sentinel/main"
# 动态构建报错回执文本 (第一层 Base64 隔离换行与特殊字符)
err_msg = f"❌ **OTA 熔断告警**\n📍 节点: `{config_mem.get('NODE_ALIAS', '未知')}`\n⚠ 原因: 脚本语法校验(bash -n)未通过,下载可能不完整。\n🚀 状态: 升级已取消,节点安全。"
err_msg_b64 = base64.b64encode(err_msg.encode('utf-8')).decode('utf-8')
tg_url = config_mem.get('TG_API_URL', '')
chat_id = config_mem.get('CHAT_ID', '')
# [v3.6.3 究极防御] 采用 Base64 将整个 OTA 执行脚本封装 (第二层隔离)
# 彻底免疫因为 python 变量掺杂引号而导致的 shell 注入或截断
ota_script = f"""
export SILENT_OTA="true"
curl -fsSL {repo_url}/core/install.sh -o /tmp/ota_agent.sh
if bash -n /tmp/ota_agent.sh; then
bash /tmp/ota_agent.sh > /opt/ip_sentinel/logs/ota_upgrade.log 2>&1
else
MSG=$(echo '{err_msg_b64}' | base64 -d)
curl -s -m 10 -X POST "{tg_url}" -d "chat_id={chat_id}" -d "text=$MSG" -d "parse_mode=Markdown" > /dev/null 2>&1
echo "OTA Checksum Failed: Script corrupted" > /opt/ip_sentinel/logs/ota_upgrade.log
fi
"""
ota_script_b64 = base64.b64encode(ota_script.encode('utf-8')).decode('utf-8')
# 安全解包并执行
if shutil.which("systemd-run"):
full_cmd = f"systemd-run --quiet --no-block bash -c \"echo '{ota_script_b64}' | base64 -d | bash\""
else:
full_cmd = f"nohup bash -c \"echo '{ota_script_b64}' | base64 -d | bash\" >/dev/null 2>&1 &"
subprocess.Popen(full_cmd, shell=True)
except Exception as e:
self.send_response(500)
self.end_headers()
self.wfile.write(f"500 Internal Error: {str(e)}\n".encode('utf-8'))
else:
self.send_response(404)
self.end_headers()
@@ -228,21 +433,49 @@ class AgentHandler(http.server.BaseHTTPRequestHandler):
import socket
# ================== [v3.0.3 变更: 引入多线程模型抵抗 Slowloris 攻击] ==================
class ThreadedDualStackServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
allow_reuse_address = True # 开启端口复用,防止热重启时端口冲突
address_family = socket.AF_INET6 if socket.has_ipv6 else socket.AF_INET
try:
bind_addr = "::" if socket.has_ipv6 else ""
with ThreadedDualStackServer((bind_addr, PORT), AgentHandler) as httpd:
httpd.serve_forever()
# 1. 优先尝试监听双栈/IPv6 (大多数 Linux 默认支持 IPv4 映射接入)
ThreadedServer.address_family = socket.AF_INET6
httpd = ThreadedServer(("::", PORT), AgentHandler)
except Exception:
# 2. [核心修复 Issue #23] 若系统内核已禁用 IPv6抛弃报错智能回退至纯 IPv4 监听
ThreadedServer.address_family = socket.AF_INET
httpd = ThreadedServer(("0.0.0.0", PORT), AgentHandler)
# ================== [v3.6.3 核心: 挂载 TLS 加密隧道 (动态适配兼容版)] ==================
import ssl
cert_path = '/opt/ip_sentinel/core/cert.pem'
key_path = '/opt/ip_sentinel/core/key.pem'
# 核心判定:提取配置中的 TOKEN 标识
is_official_gateway = False
if os.path.exists('/opt/ip_sentinel/config.conf'):
with open('/opt/ip_sentinel/config.conf', 'r') as f:
for line in f:
if line.startswith('TG_TOKEN=') and 'OFFICIAL_GATEWAY_MODE' in line:
is_official_gateway = True
break
# 仅在非官方网关且证书存在时,才挂载 TLS 装甲
if not is_official_gateway and os.path.exists(cert_path) and os.path.exists(key_path):
try:
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile=cert_path, keyfile=key_path)
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
except Exception as e:
print(f"SSL 隧道构建失败,退化为 HTTP: {e}")
# ======================================================================================
try:
httpd.serve_forever()
except Exception as e:
sys.exit(1)
# ====================================================================================
EOF
# --- [重点升级 3: 真正的静默后台启动] ---
echo "🚀 [Agent] 正在后台启动 Webhook 监听服务 (端口: $AGENT_PORT)..."
nohup python3 "${INSTALL_DIR}/core/webhook.py" "$AGENT_PORT" > /dev/null 2>&1 &
disown 2>/dev/null || true
echo "✅ [Agent] 守护进程启动完毕,可安全关闭终端。"
# --- [重点升级 3: 移交系统级守护进程接管 (阻塞模式)] ---
echo "🚀 [Agent] 正在启动 Webhook 监听服务 (端口: $AGENT_PORT)..."
exec python3 "${INSTALL_DIR}/core/webhook.py" "$AGENT_PORT"

View File

@@ -1,32 +1,110 @@
#!/bin/bash
# ==========================================================
# 脚本名称: install.sh (IP-Sentinel 分布式边缘节点部署脚本 v3.2.3 - Global Nexus)
# 核心功能: 区域选择、模块按需开启、官方机器人一键配置、平滑热更新
# 脚本名称: install.sh (IP-Sentinel 分布式边缘节点部署脚本 - 动态锚点版)
# 核心功能: 战区分组菜单、模块按需开启、官方机器人一键配置、版本状态机路由
# ==========================================================
# ==========================================================
# 🛑 核心权限防线: 检查是否以 root 权限运行
# ==========================================================
if [ "$EUID" -ne 0 ]; then
echo -e "\033[31m❌ 权限被拒绝: 部署 IP-Sentinel 需要最高系统权限。\033[0m"
echo -e "💡 请切换到 root 用户 (执行 su root 或 sudo -i) 后重新运行指令。"
exit 1
fi
# 你的 GitHub 仓库 Raw 数据直链前缀
REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main"
# 临时改为私库地址用于测试
# REPO_RAW_URL="https://git.94211762.xyz/hotyue/IP-Sentinel/raw/branch/main"
# 临时改为开发地址用于测试
# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/v3.6.2-rc"
INSTALL_DIR="/opt/ip_sentinel"
CONFIG_FILE="${INSTALL_DIR}/config.conf"
echo "========================================================"
echo " 🛡️ 欢迎使用 IP-Sentinel (边缘节点 Edge Agent)"
echo "========================================================"
# [核心: 动态提取 Agent 专属版本锚点 (KV 解析法)]
TARGET_VERSION=$(curl -s -m 3 "${REPO_RAW_URL}/version.txt" | grep "^AGENT_VERSION=" | cut -d'=' -f2 | tr -d '[:space:]')
# 🛡️ 兜底防线:如果网络波动拉取失败,启用内置的安全兜底版本
TARGET_VERSION=${TARGET_VERSION:-"3.5.1"}
# 1. 依赖检查与安装 (新增 python3 用于轻量级 Webhook 服务)
echo -e "\n[1/7] 正在安装必要环境依赖 (curl, jq, cron, procps, python3)..."
if [ -f /etc/debian_version ]; then
apt-get update -y >/dev/null 2>&1
apt-get install -y curl jq cron procps python3 >/dev/null 2>&1
elif [ -f /etc/redhat-release ]; then
yum install -y curl jq cronie procps-ng python3 >/dev/null 2>&1
systemctl enable crond && systemctl start crond
else
echo "⚠️ 未知系统,请确保已手动安装 curl, jq, pgrep 和 python3"
# 轻量级版本号比对函数 (例如: version_lt "3.3.1" "3.4.0" 返回 true)
version_lt() {
test "$(printf '%s\n' "$1" "$2" | sort -V | head -n 1)" = "$1" && test "$1" != "$2"
}
# 1. 依赖检查与智能安装 (v3.5.4 兼容性升级: 支持 Alpine, Arch 及更完善的依赖链)
echo -e "\n[1/7] 正在探测并安装基础环境依赖 (curl, jq, cron, procps, python3)..."
# 定义必须检测的核心命令
REQUIRED_CMDS=("curl" "jq" "crontab" "pgrep" "python3")
MISSING_CMDS=()
# 基础探测:预检查缺失的命令
for cmd in "${REQUIRED_CMDS[@]}"; do
if ! command -v "$cmd" >/dev/null 2>&1; then
MISSING_CMDS+=("$cmd")
fi
done
# 如果有缺失,执行智能安装逻辑
if [ ${#MISSING_CMDS[@]} -gt 0 ]; then
echo "⏳ 发现缺失依赖: ${MISSING_CMDS[*]},正在尝试自动补齐..."
# 嗅探包管理器
if command -v apt-get >/dev/null 2>&1; then
# Debian / Ubuntu 系列
apt-get update -y >/dev/null 2>&1
# [v3.6.3 抽脂级优化] 注入 --no-install-recommends 拒绝捆绑销售,大幅节省磁盘与内存
apt-get install -y --no-install-recommends curl jq cron procps python3 >/dev/null 2>&1
systemctl enable cron >/dev/null 2>&1 && systemctl start cron >/dev/null 2>&1
elif command -v yum >/dev/null 2>&1 || command -v dnf >/dev/null 2>&1; then
# RHEL / CentOS / AlmaLinux 系列
PKG_MGR="yum"
OPT_ARGS=""
if command -v dnf >/dev/null 2>&1; then
PKG_MGR="dnf"
# [v3.6.3 抽脂级优化] 强行关闭 DNF 的弱依赖拉取
OPT_ARGS="--setopt=install_weak_deps=False"
fi
$PKG_MGR install -y $OPT_ARGS curl jq cronie procps-ng python3 >/dev/null 2>&1
systemctl enable crond >/dev/null 2>&1 && systemctl start crond >/dev/null 2>&1
elif command -v apk >/dev/null 2>&1; then
# Alpine 本身就是极致精简,无需特殊参数
echo "Alpine 探测到系统类型为 Alpine Linux正在执行轻量级安装..."
apk add --no-cache curl jq dcron procps python3 bash >/dev/null 2>&1
mkdir -p /var/spool/cron/crontabs
rc-update add crond default >/dev/null 2>&1
service crond start >/dev/null 2>&1
elif command -v pacman >/dev/null 2>&1; then
# Arch Linux 系列
pacman -Sy --noconfirm curl jq cronie procps-ng python >/dev/null 2>&1
mkdir -p /root/.cache/crontab 2>/dev/null
systemctl enable cronie >/dev/null 2>&1 && systemctl start cronie >/dev/null 2>&1
else
# 无法识别的系统:退出并给出清晰的引导信息 (同步更新防捆绑参数)
echo -e "\033[31m❌ 自动安装失败:系统未知的包管理器。\033[0m"
echo -e "\033[33m⚠ 请根据您的操作系统,手动执行以下安装命令后重新运行本脚本:\033[0m"
echo -e " Debian/Ubuntu: \033[36mapt-get update && apt-get install -y --no-install-recommends curl jq cron procps python3\033[0m"
echo -e " CentOS/RHEL: \033[36myum install -y curl jq cronie procps-ng python3\033[0m"
echo -e " Alpine Linux: \033[36mapk add --no-cache curl jq dcron procps python3 bash\033[0m"
echo -e " Arch Linux: \033[36mpacman -Sy curl jq cronie procps-ng python\033[0m"
exit 1
fi
# 安装后二次复检
for cmd in "${REQUIRED_CMDS[@]}"; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo -e "\033[31m❌ 致命错误:核心命令 '$cmd' 仍未找到!\033[0m"
echo -e "这通常是因为您的系统源配置错误或缺失基础组件库导致。"
echo -e "请手动修复您的包管理器源,或联系 VPS 供应商重新格式化系统。"
exit 1
fi
done
fi
echo -e "\033[32m✅ 基础环境检测通过。\033[0m"
# 2. 交互式引导与动态地图解析 (v3.0 全球网络)
echo -e "\n[2/7] 正在连线云端,拉取全球节点地图..."
@@ -37,56 +115,73 @@ if [ ! -s "/tmp/map.json" ]; then
exit 1
fi
echo -e "\n请选择操作:"
echo " 1) 🚀 部署边缘节点 (进入全球节点配置)"
echo " 2) 🗑️ 一键卸载 IP-Sentinel"
read -p "请输入选择 [1-2] (默认1): " ACTION_CHOICE
# ==========================================================
# [v3.6.0 核心] 拦截静默 OTA 升级模式 (强行接管执行流,跳过人工交互)
# ==========================================================
if [ "$SILENT_OTA" == "true" ]; then
echo -e "\n⏳ [OTA] 静默升级指令已确认,正在剥离控制台交互..."
ACTION_CHOICE=1
UPGRADE_MODE="true"
KEEP_LOGS="true"
source "$CONFIG_FILE"
else
echo -e "\n请选择操作:"
echo " 1) 🚀 部署边缘节点 (进入全球节点配置)"
echo " 2) 🗑️ 一键卸载 IP-Sentinel"
read -p "请输入选择 [1-2] (默认1): " ACTION_CHOICE
if [ "$ACTION_CHOICE" == "2" ]; then
echo -e "\n⏳ 正在拉取卸载程序..."
curl -sL "${REPO_RAW_URL}/core/uninstall.sh" -o "/tmp/ip_uninstall.sh"
chmod +x "/tmp/ip_uninstall.sh"
bash "/tmp/ip_uninstall.sh"
rm -f "/tmp/ip_uninstall.sh"
exit 0
fi
# [v3.5.2 修复] 防止用户直接回车导致变量为空,从而漏过下方的平滑升级判定
ACTION_CHOICE=${ACTION_CHOICE:-1}
# ================== [v3.2.2 新增: 平滑升级模式嗅探] ==================
UPGRADE_MODE="false"
KEEP_LOGS="true"
if [ "$ACTION_CHOICE" == "1" ] && [ -f "$CONFIG_FILE" ]; then
echo -e "\n\033[33m💡 哨兵雷达提示:检测到本机已部署过 IP-Sentinel。\033[0m"
read -p "👉 是否按原配置直接进行平滑升级?(y/n, 默认y): " UPGRADE_CHOICE
if [[ -z "$UPGRADE_CHOICE" || "$UPGRADE_CHOICE" =~ ^[Yy]$ ]]; then
UPGRADE_MODE="true"
read -p "👉 是否保留历史运行日志?(y/n, 默认y): " LOG_CHOICE
if [[ "$LOG_CHOICE" =~ ^[Nn]$ ]]; then
KEEP_LOGS="false"
fi
# 将原配置读入环境变量,为后续跳过配置步骤提供燃料
source "$CONFIG_FILE"
echo -e "\033[32m✅ 已激活 [平滑升级模式],即将跳过基础配置,直接更新核心装甲...\033[0m"
else
echo -e "\033[33m🔄 您选择了重新配置,旧的哨兵数据将被彻底抹除。\033[0m"
if [ "$ACTION_CHOICE" == "2" ]; then
echo -e "\n⏳ 正在拉取卸载程序..."
curl -sL "${REPO_RAW_URL}/core/uninstall.sh" -o "/tmp/ip_uninstall.sh"
chmod +x "/tmp/ip_uninstall.sh"
bash "/tmp/ip_uninstall.sh"
rm -f "/tmp/ip_uninstall.sh"
exit 0
fi
# ================== [v3.2.2 新增: 平滑升级模式嗅探] ==================
UPGRADE_MODE="false"
KEEP_LOGS="true"
if [ "$ACTION_CHOICE" == "1" ] && [ -f "$CONFIG_FILE" ]; then
echo -e "\n\033[33m💡 哨兵雷达提示:检测到本机已部署过 IP-Sentinel。\033[0m"
read -p "👉 是否按原配置直接进行平滑升级?(y/n, 默认y): " UPGRADE_CHOICE
if [[ -z "$UPGRADE_CHOICE" || "$UPGRADE_CHOICE" =~ ^[Yy]$ ]]; then
UPGRADE_MODE="true"
read -p "👉 是否保留历史运行日志?(y/n, 默认y): " LOG_CHOICE
if [[ "$LOG_CHOICE" =~ ^[Nn]$ ]]; then
KEEP_LOGS="false"
fi
# 将原配置读入环境变量,为后续跳过配置步骤提供燃料
source "$CONFIG_FILE"
echo -e "\033[32m✅ 已激活 [平滑升级模式],即将跳过基础配置,直接更新核心装甲...\033[0m"
else
echo -e "\033[33m🔄 您选择了重新配置,旧的哨兵数据将被彻底抹除。\033[0m"
fi
fi
# ====================================================================
fi
# ====================================================================
# ================== [v3.1.1/v3.2.2 优化: 安装前环境纯净度清理] ==================
echo -e "\n⏳ 正在清理旧版守护进程与冗余任务..."
# [新增] 优雅停止 Systemd 服务,防止代码替换时引发无限复活风暴
if command -v systemctl >/dev/null 2>&1; then
systemctl stop ip-sentinel-runner.timer ip-sentinel-updater.timer ip-sentinel-report.timer ip-sentinel-agent-daemon.service >/dev/null 2>&1 || true
fi
# 1. 强制超度可能存活的 Webhook 及各类看门狗进程,释放端口
pkill -9 -f "webhook.py" >/dev/null 2>&1 || true
pkill -9 -f "agent_daemon.sh" >/dev/null 2>&1 || true
pkill -9 -f "runner.sh" >/dev/null 2>&1 || true
# 2. 清除系统定时任务 (Cron) 中的旧版条目
if crontab -l >/dev/null 2>&1; then
crontab -l | grep -v "ip_sentinel" > /tmp/cron_clean
crontab /tmp/cron_clean
rm -f /tmp/cron_clean
fi
# 2. 清除系统定时任务 (Cron) 中的旧版条目 (安全容错版)
crontab -l 2>/dev/null | grep -v "ip_sentinel" > /tmp/cron_clean || true
[ -f /tmp/cron_clean ] && crontab /tmp/cron_clean 2>/dev/null
rm -f /tmp/cron_clean
# 3. 抹除旧版核心代码,杜绝代码冲突 (根据模式分流)
if [ "$UPGRADE_MODE" == "true" ]; then
@@ -112,9 +207,23 @@ echo -e "\033[32m✅ 环境清理完毕,幽灵进程已肃清!\033[0m"
# ==========================================================
if [ "$UPGRADE_MODE" == "false" ]; then
# 📍 动态级菜单:国家选择
echo -e "\n\033[36m📍 【第级】请选择目标国家/地区:\033[0m"
jq -r '.countries[] | "\(.id)|\(.name)|\(.keyword_file)"' /tmp/map.json > /tmp/countries.txt
# 📍 动态级菜单:战区(大洲)选择
echo -e "\n\033[36m📍 【第级】请选择目标战区 (Continent):\033[0m"
jq -r '.continents[] | "\(.id)|\(.name)"' /tmp/map.json > /tmp/continents.txt
i=1; CONT_MAP=()
while IFS="|" read -r cont_id cont_name; do
echo " $i) $cont_name"
CONT_MAP[$i]="$cont_id"
((i++))
done < /tmp/continents.txt
read -p "请输入选择 [1-$((i-1))] (默认1): " CONT_SEL
CONT_SEL=${CONT_SEL:-1}
CONT_ID="${CONT_MAP[$CONT_SEL]}"
# 📍 动态一级菜单:国家选择 (基于选中战区)
echo -e "\n\033[36m📍 【第一级】正在检索 [$CONT_ID] 战区下的国家/地区...\033[0m"
jq -r ".continents[] | select(.id==\"$CONT_ID\") | .countries[] | \"\(.id)|\(.name)|\(.keyword_file)\"" /tmp/map.json > /tmp/countries.txt
i=1; COUNTRY_MAP=(); KEYWORD_MAP=()
while IFS="|" read -r c_id c_name k_file; do
echo " $i) $c_name"
@@ -129,9 +238,9 @@ if [ "$UPGRADE_MODE" == "false" ]; then
KEYWORD_FILE="${KEYWORD_MAP[$C_SEL]}"
REGION_CODE="$COUNTRY_ID" # 兼容旧版的 config.conf
# 📍 动态二级菜单:省/州选择
# 📍 动态二级菜单:省/州选择 (基于选中战区和国家)
echo -e "\n\033[36m📍 【第二级】正在检索 [$COUNTRY_ID] 的行政区数据...\033[0m"
jq -r ".countries[] | select(.id==\"$COUNTRY_ID\") | .states[] | \"\(.id)|\(.name)\"" /tmp/map.json > /tmp/states.txt
jq -r ".continents[] | select(.id==\"$CONT_ID\") | .countries[] | select(.id==\"$COUNTRY_ID\") | .states[] | \"\(.id)|\(.name)\"" /tmp/map.json > /tmp/states.txt
STATE_COUNT=$(wc -l < /tmp/states.txt)
if [ "$STATE_COUNT" -eq 1 ]; then
@@ -149,28 +258,30 @@ if [ "$UPGRADE_MODE" == "false" ]; then
STATE_ID="${STATE_MAP[$S_SEL]}"
fi
# 📍 动态三级菜单:城市选择
# 📍 动态三级菜单:城市选择 (基于战区、国家、州三层过滤)
echo -e "\n\033[36m📍 【第三级】请锁定具体城市节点:\033[0m"
jq -r ".countries[] | select(.id==\"$COUNTRY_ID\") | .states[] | select(.id==\"$STATE_ID\") | .cities[] | \"\(.id)|\(.name)\"" /tmp/map.json > /tmp/cities.txt
jq -r ".continents[] | select(.id==\"$CONT_ID\") | .countries[] | select(.id==\"$COUNTRY_ID\") | .states[] | select(.id==\"$STATE_ID\") | .cities[] | \"\(.id)|\(.name)\"" /tmp/map.json > /tmp/cities.txt
CITY_COUNT=$(wc -l < /tmp/cities.txt)
if [ "$CITY_COUNT" -eq 1 ]; then
IFS="|" read -r CITY_ID CITY_NAME < /tmp/cities.txt
echo -e "\033[32m💡 该区域下仅有单一城市 [$CITY_NAME],已自动锁定。\033[0m"
else
i=1; CITY_MAP=()
i=1; CITY_MAP=(); CITY_NAME_MAP=()
while IFS="|" read -r c_id c_name; do
echo " $i) $c_name"
CITY_MAP[$i]="$c_id"
CITY_NAME_MAP[$i]="$c_name"
((i++))
done < /tmp/cities.txt
read -p "请输入选择 [1-$((i-1))] (默认1): " CI_SEL
CI_SEL=${CI_SEL:-1}
CITY_ID="${CITY_MAP[$CI_SEL]}"
CITY_NAME="${CITY_NAME_MAP[$CI_SEL]}"
fi
# 清理临时文件
rm -f /tmp/map.json /tmp/countries.txt /tmp/states.txt /tmp/cities.txt
# 清理临时文件 (增加清理 continents.txt)
rm -f /tmp/map.json /tmp/continents.txt /tmp/countries.txt /tmp/states.txt /tmp/cities.txt
# 本地工作目录初始化 (支持 v3.0 的深度层级)
mkdir -p "${INSTALL_DIR}/core"
@@ -178,46 +289,66 @@ if [ "$UPGRADE_MODE" == "false" ]; then
mkdir -p "${INSTALL_DIR}/data/regions/${COUNTRY_ID}/${STATE_ID}"
mkdir -p "${INSTALL_DIR}/logs"
# 3. 功能模块前置开关 (按需加载)
echo -e "\n[3/7] 请选择需要开启的养护模块 (按需开启,节省资源):"
echo " 1) 📍 仅开启 [Google 区域纠偏] (默认,适合流媒体解锁机位漂移)"
echo " 2) 🛡️ 仅开启 [IP 信用净化] (适合高风险机房 IP 降低 Scamalytics 分数)"
echo " 3) 🔥 双管齐下 (同时开启以上两项)"
read -p "请输入选择 [1-3] (默认1): " MODULE_CHOICE
# 3. 功能模块前置开关 (v3.5.3 默认全量加载,后续经由 TG 动态启停)
echo -e "\n[3/7] 正在初始化养护模块 (默认全量部署,支持 TG 远程动态启停)..."
ENABLE_GOOGLE="true"
ENABLE_TRUST="false"
case ${MODULE_CHOICE:-1} in
2) ENABLE_GOOGLE="false"; ENABLE_TRUST="true" ;;
3) ENABLE_GOOGLE="true"; ENABLE_TRUST="true" ;;
*) ENABLE_GOOGLE="true"; ENABLE_TRUST="false" ;;
esac
ENABLE_TRUST="true"
# 4. 接入 Master 中枢配置
echo -e "\n[4/7] 是否接入 Master 司令部(需要配置与主控相同的 TG 机器人) (y/n)"
echo -e "\n[4/7] 是否接入 Master 司令部进行远程联控? (y/n)"
read -p "请输入选择 [y/n] (默认n): " TG_CHOICE
TG_TOKEN=""
CHAT_ID=""
AGENT_PORT="9527"
if [[ "$TG_CHOICE" =~ ^[Yy]$ ]]; then
echo -e "\n\033[33m💡 提示:您可以选择使用自己的机器人,或者直接回车使用官方公共机器人。\033[0m"
echo -e "\033[33m⚠ 注意:若使用官方机器人,请务必先在 TG 中关注 @OmniBeacon_bot 并发送 /start\033[0m"
echo -e "\n请选择中枢接入模式 (推荐私有部署,支持后续 OTA 远程静默升级):"
echo " 1) 🛡️ 私有独立中枢 (需提供自建 Bot Token推荐)"
echo " 2) ☁️ 官方公共网关 (@OmniBeacon_bot新手免配置)"
read -p "请输入选择 [1-2] (默认1): " MASTER_TYPE
MASTER_TYPE=${MASTER_TYPE:-1}
read -p "请输入您的 Telegram Bot Token (回车使用官方默认): " USER_TOKEN
if [ -z "$USER_TOKEN" ]; then
if [ "$MASTER_TYPE" == "2" ]; then
TG_TOKEN="OFFICIAL_GATEWAY_MODE"
TG_API_URL="https://omni-gateway.samanthaestime296.workers.dev"
ENABLE_OTA="false"
echo -e "\033[32m✅ 已自动连接官方安全网关 (@OmniBeacon_bot)。\033[0m"
echo -e "\033[33m👉 请确保您已关注官方机器人并发送过 /start否则将无法接收消息。\033[0m"
echo -e "\033[33m👉 请确保您已在 TG 中关注官方机器人并发送过 /start否则将无法接收消息。\033[0m"
# [v3.6.0 安全熔断]
echo -e "\n\033[33m⚠ 【安全熔断提示】\033[0m"
echo -e "\033[33m由于您使用了官方公共网关为防止潜在的滥用或供应链风险本节点的 [OTA 远程升级] 权限已被系统底层强制禁用。\033[0m"
echo -e "\033[33m💡 若未来需要启用 OTA请自建私有中枢后重新部署本节点。\033[0m"
else
# [v3.6.0 优化] 使用 OSC 8 终端超链接协议,实现“点击即打开”的极客交互
echo -e "\n\033[36m📘 私有 Bot 创建教程: \033[4m\033]8;;https://blog.iot-architect.com/engineering-practice/create-private-telegram-bot-via-botfather/\033\\👉 [点击此处直接在浏览器中打开] 👈\033]8;;\033\\\033[0m"
echo -e "\033[90m (若您的终端较老不支持点击,请手动复制: https://blog.iot-architect.com/engineering-practice/create-private-telegram-bot-via-botfather/ )\033[0m"
read -p "请输入您的私有 Telegram Bot Token: " USER_TOKEN
# 🛡️ 核心防误触修复:拦截空回车或粘贴换行导致的跳过 Bug
while [ -z "$USER_TOKEN" ]; do
read -p "⚠️ Token 不能为空,请重新输入您的 Bot Token: " USER_TOKEN
done
TG_TOKEN="$USER_TOKEN"
TG_API_URL="https://api.telegram.org/bot${TG_TOKEN}/sendMessage"
echo -e "\033[32m✅ 已记录您的私有机器人 Token。\033[0m"
# [v3.6.0] 私有模式开放 OTA 授权向导
echo -e "\n\033[36m[4.1/7] OTA 远程静默升级授权\033[0m"
echo -e "💡 开启后,您可以在 TG 面板一键将本节点热更新至最新版本。"
read -p "是否允许本节点接收 OTA 升级指令?(y/n, 默认y): " OTA_CHOICE
if [[ "$OTA_CHOICE" =~ ^[Nn]$ ]]; then
ENABLE_OTA="false"
echo -e "🛡️ \033[33m已关闭 OTA 权限,本节点未来将只能通过 SSH 手动升级。\033[0m"
else
ENABLE_OTA="true"
echo -e "✅ \033[32m已开启 OTA 权限,核按钮已挂载至您的私有中枢。\033[0m"
fi
fi
echo -e "\033[33m💡 提示:如果您不知道自己的 Chat ID可以关注 @userinfobot 获取。\033[0m"
read -p "请输入你的 Chat ID (与主控一致): " CHAT_ID
echo -e "\n\033[33m💡 提示:如果您不知道下方自己的 Chat ID 是什么,可以关注 @userinfobot 获取。\033[0m"
echo -e "\033[36m📘 查看图文教程: \033[4m\033]8;;https://blog.iot-architect.com/engineering-practice/get-telegram-personal-id-via-userinfobot/\033\\👉 [点击此处直接在浏览器中打开] 👈\033]8;;\033\\\033[0m"
echo -e "\033[90m (若您的终端较老不支持点击,请手动复制: https://blog.iot-architect.com/engineering-practice/get-telegram-personal-id-via-userinfobot/ )\033[0m"
read -p "请输入你的 Chat ID (必须准确,否则无法联控): " CHAT_ID
# ================== [v3.0.3 变更: 智能随机高位端口生成系统] ==================
echo -e "\n\033[36m[4.2/7] 正在构建 Webhook 安全通信隧道...\033[0m"
@@ -307,13 +438,53 @@ if [ "$UPGRADE_MODE" == "false" ]; then
fi
fi
# 终极修复:为 IPv6 自动穿上防护装甲(方括号),解决 Master 拼接 URL 报错问题
# ================== [v3.3.1 核心重构: 身份剥离与双栈实弹嗅探] ==================
# 1. 固化对外通讯身份 (自动穿透方括号护甲)
if [[ "$PUBLIC_IP" == *":"* ]] && [[ "$PUBLIC_IP" != *"["* ]]; then
BIND_IP="[${PUBLIC_IP}]"
SAFE_PUBLIC_IP="[${PUBLIC_IP}]"
else
BIND_IP="$PUBLIC_IP"
SAFE_PUBLIC_IP="$PUBLIC_IP"
fi
# 2. 实弹打靶测试 (NAT 环境嗅探与双栈自适应)
echo -n "🕵️ 正在进行出站链路试射 (NAT环境与双栈嗅探)..."
RAW_TEST_IP=$(echo "$SAFE_PUBLIC_IP" | tr -d '[]')
# 智能切换靶机V6 机器打 Cloudflare V6 节点V4 机器打 1.1.1.1
if [[ "$RAW_TEST_IP" == *":"* ]]; then
TEST_TARGET="https://[2606:4700:4700::1111]"
else
TEST_TARGET="https://1.1.1.1"
fi
# 执行实弹试射
if curl --interface "$RAW_TEST_IP" -sI -m 3 "$TEST_TARGET" >/dev/null 2>&1; then
echo -e " \033[32m✅ 原生直连,物理网卡死锁已激活。\033[0m"
BIND_IP="$SAFE_PUBLIC_IP"
else
echo -e " \033[33m⚠ 发现 NAT/虚拟路由架构,自动卸除网卡枷锁,交由内核路由。\033[0m"
BIND_IP=""
fi
echo -e "\033[32m✅ 哨兵对外联络点已永久锁定至: $SAFE_PUBLIC_IP\033[0m"
# ========================================================================
# ================== [v3.5.2 新增: 节点不可变主键与展示别名] ==================
IP_HASH=$(echo "${SAFE_PUBLIC_IP:-127.0.0.1}" | md5sum | cut -c 1-4 | tr 'a-z' 'A-Z')
NODE_NAME="$(hostname | tr -cd 'a-zA-Z0-9' | cut -c 1-10)-${IP_HASH}"
NODE_ALIAS="$NODE_NAME"
if [[ -n "$TG_TOKEN" ]] && [[ -n "$CHAT_ID" ]]; then
echo -e "\n\033[36m[4.8/7] 节点展示别名设定 (用于面板友好显示)...\033[0m"
echo -e "💡 系统底层的不可变主键为: \033[33m${NODE_NAME}\033[0m"
read -p "请输入节点展示别名 (如'纽约机房', 回车使用默认): " CUSTOM_ALIAS
if [ -n "$CUSTOM_ALIAS" ]; then
# 🛡️ 强制字符清洗:防御 Shell 注入,并限制长度防刷屏
NODE_ALIAS=$(echo "$CUSTOM_ALIAS" | tr -d '"'\''\`\$\|&;<>\n\r' | cut -c 1-20)
[ -z "$NODE_ALIAS" ] && NODE_ALIAS="$NODE_NAME"
fi
echo -e "✅ 已锁定节点展示别名: \033[32m$NODE_ALIAS\033[0m"
fi
echo -e "\033[32m✅ 哨兵锚点已永久锁定至: $BIND_IP\033[0m"
# ========================================================================
# 5. 远程拉取冷数据并解析固化
@@ -333,9 +504,10 @@ if [ "$UPGRADE_MODE" == "false" ]; then
LANG_PARAMS=$(jq -r '.google_module.lang_params' "$REGION_JSON_FILE")
VALID_URL_SUFFIX=$(jq -r '.google_module.valid_url_suffix' "$REGION_JSON_FILE")
# 写入本地静态配置文件
# 写入本地静态配置文件 (v3.4.0 引入版本锚点)
cat > "$CONFIG_FILE" << EOF
# IP-Sentinel 本地固化配置 (生成时间: $(date '+%Y-%m-%d %H:%M:%S'))
AGENT_VERSION="$TARGET_VERSION"
REGION_CODE="$REGION_CODE"
REGION_NAME="$REGION_NAME"
BASE_LAT="$BASE_LAT"
@@ -354,9 +526,17 @@ AGENT_PORT="$AGENT_PORT"
INSTALL_DIR="$INSTALL_DIR"
LOG_FILE="${INSTALL_DIR}/logs/sentinel.log"
# [v3.0.1新增修改 2: 网络栈锚点锁定配置,供其他脚本读取]
# [v3.3.1修改: 双核身份剥离配置]
IP_PREF="$IP_PREF"
PUBLIC_IP="$SAFE_PUBLIC_IP"
BIND_IP="$BIND_IP"
# [v3.5.2新增: 双轨身份系统]
NODE_NAME="$NODE_NAME"
NODE_ALIAS="$NODE_ALIAS"
# [v3.6.0新增: OTA 权限标识]
ENABLE_OTA="$ENABLE_OTA"
EOF
# ================== [v3.0.3 变更: 敏感配置文件权限收敛] ==================
@@ -366,6 +546,69 @@ EOF
fi
# 🛑 拦截块结束 (全套交互配置跳过完毕)
# ================== [v3.3.1 核心修复: 老节点配置无损热迁移] ==================
if [ "$UPGRADE_MODE" == "true" ]; then
if ! grep -q "PUBLIC_IP=" "$CONFIG_FILE"; then
echo -e "\n🔄 [平滑迁移] 正在对老节点进行 v3.3.1 双核身份架构升级..."
# 重新抓取公网面孔 (应对老节点 BIND_IP 可能已被手动清空的情况)
MIGRATE_IP=$(curl -${IP_PREF:-4} -s -m 5 api.ip.sb/ip | tr -d '[:space:]')
[[ "$MIGRATE_IP" == *":"* ]] && [[ "$MIGRATE_IP" != *"["* ]] && MIGRATE_IP="[${MIGRATE_IP}]"
echo -n "🕵️ 正在进行补发链路试射 (NAT与双栈嗅探)..."
RAW_TEST_IP=$(echo "$MIGRATE_IP" | tr -d '[]')
if [[ "$RAW_TEST_IP" == *":"* ]]; then
TEST_TARGET="https://[2606:4700:4700::1111]"
else
TEST_TARGET="https://1.1.1.1"
fi
if curl --interface "$RAW_TEST_IP" -sI -m 3 "$TEST_TARGET" >/dev/null 2>&1; then
echo -e " \033[32m✅ 原生直连,网卡死锁已继承。\033[0m"
NEW_BIND_IP="$MIGRATE_IP"
else
echo -e " \033[33m⚠ 发现 NAT 架构,已自动卸除老版本的物理枷锁。\033[0m"
NEW_BIND_IP=""
fi
# 动态修改旧配置文件 (更新 BIND_IP追加 PUBLIC_IP)
sed -i "s/^BIND_IP=.*/BIND_IP=\"$NEW_BIND_IP\"/" "$CONFIG_FILE"
echo "PUBLIC_IP=\"$MIGRATE_IP\"" >> "$CONFIG_FILE"
# 刷新当前安装脚本的环境变量,防止底部代码报错
SAFE_PUBLIC_IP="$MIGRATE_IP"
BIND_IP="$NEW_BIND_IP"
else
# 如果是未来再升级,配置文件已是最新,直接提取变量供安装脚本尾部使用
SAFE_PUBLIC_IP=$(grep "^PUBLIC_IP=" "$CONFIG_FILE" | cut -d'"' -f2)
fi
# [v3.5.2 热修复] 兼容老版本没有 NODE_NAME 和 NODE_ALIAS 的情况,无损补齐
if ! grep -q "^NODE_NAME=" "$CONFIG_FILE"; then
TMP_HASH=$(echo "${SAFE_PUBLIC_IP:-127.0.0.1}" | md5sum | cut -c 1-4 | tr 'a-z' 'A-Z')
NODE_NAME="$(hostname | tr -cd 'a-zA-Z0-9' | cut -c 1-10)-${TMP_HASH}"
NODE_ALIAS="$NODE_NAME"
echo "NODE_NAME=\"$NODE_NAME\"" >> "$CONFIG_FILE"
echo "NODE_ALIAS=\"$NODE_ALIAS\"" >> "$CONFIG_FILE"
else
NODE_NAME=$(grep "^NODE_NAME=" "$CONFIG_FILE" | cut -d'"' -f2)
NODE_ALIAS=$(grep "^NODE_ALIAS=" "$CONFIG_FILE" | cut -d'"' -f2)
if [ -z "$NODE_ALIAS" ]; then
NODE_ALIAS="$NODE_NAME"
echo "NODE_ALIAS=\"$NODE_ALIAS\"" >> "$CONFIG_FILE"
fi
fi
# [v3.6.0 热修复] 兼容老版本没有 ENABLE_OTA 的情况,无损补齐默认关闭以防滥用
if ! grep -q "^ENABLE_OTA=" "$CONFIG_FILE"; then
echo "ENABLE_OTA=\"false\"" >> "$CONFIG_FILE"
ENABLE_OTA="false"
else
ENABLE_OTA=$(grep "^ENABLE_OTA=" "$CONFIG_FILE" | cut -d'"' -f2)
fi
fi
# ========================================================================
# 6. 拉取全套组件 (按需下载,绝不浪费空间)
echo -e "\n[6/7] 正在根据模块开关部署核心引擎与热数据..."
# 确保目录在升级模式下也能被正确建立
@@ -380,80 +623,212 @@ curl -sL "${REPO_RAW_URL}/core/agent_daemon.sh" -o "${INSTALL_DIR}/core/agent_da
curl -sL "${REPO_RAW_URL}/core/uninstall.sh" -o "${INSTALL_DIR}/core/uninstall.sh"
curl -sL "${REPO_RAW_URL}/data/user_agents.txt" -o "${INSTALL_DIR}/data/user_agents.txt"
# 动态按需组件
if [ "$ENABLE_GOOGLE" == "true" ]; then
curl -sL "${REPO_RAW_URL}/core/mod_google.sh" -o "${INSTALL_DIR}/core/mod_google.sh"
# [v3.2.2 修复] 动态匹配词库下载逻辑
if [ "$UPGRADE_MODE" == "false" ]; then
curl -sL "${REPO_RAW_URL}/data/keywords/${KEYWORD_FILE}" -o "${INSTALL_DIR}/data/keywords/${KEYWORD_FILE}"
else
# 升级模式:利用已有的 REGION_CODE 更新通用词库
curl -sL "${REPO_RAW_URL}/data/keywords/kw_${REGION_CODE}.txt" -o "${INSTALL_DIR}/data/keywords/kw_${REGION_CODE}.txt" 2>/dev/null || true
fi
# [v3.6.4 修复] 废除物理阉割,全量下载模块装甲,交由 config.conf 动态控制底层启停
curl -sL "${REPO_RAW_URL}/core/mod_google.sh" -o "${INSTALL_DIR}/core/mod_google.sh"
# 动态匹配词库下载逻辑
if [ "$UPGRADE_MODE" == "false" ]; then
curl -sL "${REPO_RAW_URL}/data/keywords/${KEYWORD_FILE}" -o "${INSTALL_DIR}/data/keywords/${KEYWORD_FILE}"
else
# 升级模式:利用已有的 REGION_CODE 更新通用词库
curl -sL "${REPO_RAW_URL}/data/keywords/kw_${REGION_CODE}.txt" -o "${INSTALL_DIR}/data/keywords/kw_${REGION_CODE}.txt" 2>/dev/null || true
fi
if [ "$ENABLE_TRUST" == "true" ]; then
curl -sL "${REPO_RAW_URL}/core/mod_trust.sh" -o "${INSTALL_DIR}/core/mod_trust.sh"
fi
curl -sL "${REPO_RAW_URL}/core/mod_trust.sh" -o "${INSTALL_DIR}/core/mod_trust.sh"
chmod +x ${INSTALL_DIR}/core/*.sh
# 7. 配置系统定时任务 (高频调度与看门狗)
echo -e "\n[7/7] 正在注入系统定时任务与看门狗进程..."
crontab -l 2>/dev/null | grep -v "ip_sentinel" > /tmp/cron_backup
echo -e "\n[7/7] 正在注入系统守护进程与调度器..."
# 核心养护模块: 每 30 分钟触发一次
echo "*/30 * * * * ${INSTALL_DIR}/core/runner.sh >/dev/null 2>&1" >> /tmp/cron_backup
# 养料更新模块: 每周日凌晨 3 点静默去云端更新热数据
echo "0 3 * * 0 ${INSTALL_DIR}/core/updater.sh >/dev/null 2>&1" >> /tmp/cron_backup
# [v3.3.0 新增] 初始化 UA 指纹库更新时间戳,确立 30 天滚动周期的计算锚点
echo $(date +%s) > "${INSTALL_DIR}/core/.ua_last_update"
# 如果配置了联控,启动 Webhook 与战报任务
if [[ -n "$TG_TOKEN" ]] && [[ -n "$CHAT_ID" ]]; then
# 每天早上 8 点发送昨天的统计战报
echo "0 8 * * * ${INSTALL_DIR}/core/tg_report.sh >/dev/null 2>&1" >> /tmp/cron_backup
if command -v systemctl >/dev/null 2>&1; then
echo "💡 检测到 Systemd 环境,正在部署原生守护服务..."
# [v3.0.1新增修改 3: 删除原来的 curl 取 IP直接使用我们上方锁定的 BIND_IP]
# 并提前写入 IP 缓存,彻底阻断 agent_daemon 首次启动时的重复推送
# [修复竞态]: 提前写入 IP 缓存,彻底阻断 agent_daemon 首次启动时的抢跑推送
echo "$BIND_IP" > "${INSTALL_DIR}/core/.last_ip"
# 1. Runner 核心养护模块服务与定时器
cat > /etc/systemd/system/ip-sentinel-runner.service << EOF
[Unit]
Description=IP-Sentinel Runner Service
After=network.target
[Service]
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
SyslogIdentifier=ip-sentinel
Type=oneshot
ExecStart=/bin/bash ${INSTALL_DIR}/core/runner.sh
User=root
CPUSchedulingPolicy=idle
IOSchedulingClass=idle
EOF
cat > /etc/systemd/system/ip-sentinel-runner.timer << EOF
[Unit]
Description=Timer for IP-Sentinel Runner Service
[Timer]
OnActiveSec=10s
OnUnitActiveSec=30min
RandomizedDelaySec=180
Persistent=true
Unit=ip-sentinel-runner.service
[Install]
WantedBy=timers.target
EOF
# 2. Updater 养料更新模块服务与定时器
cat > /etc/systemd/system/ip-sentinel-updater.service << EOF
[Unit]
Description=IP-Sentinel Updater Service
After=network.target
[Service]
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
SyslogIdentifier=ip-sentinel
Type=oneshot
ExecStart=/bin/bash ${INSTALL_DIR}/core/updater.sh
User=root
CPUSchedulingPolicy=idle
IOSchedulingClass=idle
EOF
cat > /etc/systemd/system/ip-sentinel-updater.timer << EOF
[Unit]
Description=Timer for IP-Sentinel Updater Service
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
Unit=ip-sentinel-updater.service
[Install]
WantedBy=timers.target
EOF
systemctl daemon-reload
systemctl enable --now ip-sentinel-runner.timer ip-sentinel-updater.timer
if [[ -n "$TG_TOKEN" ]] && [[ -n "$CHAT_ID" ]]; then
# 3. TG 战报服务与定时器
cat > /etc/systemd/system/ip-sentinel-report.service << EOF
[Unit]
Description=IP-Sentinel Telegram Report Service
After=network.target
[Service]
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
SyslogIdentifier=ip-sentinel
Type=oneshot
ExecStart=/bin/bash ${INSTALL_DIR}/core/tg_report.sh
User=root
CPUSchedulingPolicy=idle
IOSchedulingClass=idle
EOF
cat > /etc/systemd/system/ip-sentinel-report.timer << EOF
[Unit]
Description=Timer for IP-Sentinel Telegram Report Service
[Timer]
OnCalendar=*-*-* 08:00:00
Unit=ip-sentinel-report.service
[Install]
WantedBy=timers.target
EOF
# 4. [排雷修复] Agent Daemon Webhook 监听守护服务 (Type=simple, 常驻执行)
cat > /etc/systemd/system/ip-sentinel-agent-daemon.service << EOF
[Unit]
Description=IP-Sentinel Agent Daemon Service
After=network.target
[Service]
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
SyslogIdentifier=ip-sentinel
Type=simple
ExecStart=/bin/bash ${INSTALL_DIR}/core/agent_daemon.sh
Restart=always
RestartSec=5
User=root
CPUSchedulingPolicy=idle
IOSchedulingClass=idle
[Install]
WantedBy=multi-user.target
EOF
# [修复竞态]: 提前写入公网 IP 缓存,阻断重复推送
echo "$SAFE_PUBLIC_IP" > "${INSTALL_DIR}/core/.last_ip"
systemctl daemon-reload
systemctl enable --now ip-sentinel-report.timer
systemctl enable --now ip-sentinel-agent-daemon.service
fi
else
echo "💡 未检测到 Systemd (可能是 Alpine Linux),回退到 Cron 调度模式..."
crontab -l 2>/dev/null | grep -v "ip_sentinel" > /tmp/cron_backup || true
echo "*/30 * * * * ${INSTALL_DIR}/core/runner.sh >/dev/null 2>&1" >> /tmp/cron_backup
echo "0 3 * * * ${INSTALL_DIR}/core/updater.sh >/dev/null 2>&1" >> /tmp/cron_backup
# 双保险守护进程看门狗
echo "@reboot nohup bash ${INSTALL_DIR}/core/agent_daemon.sh >/dev/null 2>&1 &" >> /tmp/cron_backup
echo "* * * * * nohup bash ${INSTALL_DIR}/core/agent_daemon.sh >/dev/null 2>&1 &" >> /tmp/cron_backup
# 安装时立刻启动一次边缘守护进程
nohup bash "${INSTALL_DIR}/core/agent_daemon.sh" >/dev/null 2>&1 &
if [[ -n "$TG_TOKEN" ]] && [[ -n "$CHAT_ID" ]]; then
echo "0 8 * * * ${INSTALL_DIR}/core/tg_report.sh >/dev/null 2>&1" >> /tmp/cron_backup
echo "$SAFE_PUBLIC_IP" > "${INSTALL_DIR}/core/.last_ip"
echo "@reboot nohup bash ${INSTALL_DIR}/core/agent_daemon.sh >/dev/null 2>&1 &" >> /tmp/cron_backup
echo "* * * * * nohup bash ${INSTALL_DIR}/core/agent_daemon.sh >/dev/null 2>&1 &" >> /tmp/cron_backup
nohup bash "${INSTALL_DIR}/core/agent_daemon.sh" >/dev/null 2>&1 &
fi
[ -f /tmp/cron_backup ] && crontab /tmp/cron_backup 2>/dev/null
rm -f /tmp/cron_backup
fi
crontab /tmp/cron_backup
rm -f /tmp/cron_backup
# ================== [v3.2.2 优化: 战报通知分流 (注册/升级)] ==================
# ================== [v3.4.0 核心: 状态机驱动的热更新路由] ==================
if [[ -n "$TG_TOKEN" ]] && [[ -n "$CHAT_ID" ]]; then
NODE_NAME=$(hostname | cut -c 1-15)
# [v3.6.0 核心] 发送携带全套身份属性的注册指令 (追加 ENABLE_OTA 作为第 7 个字段)
REG_MSG="#REGISTER#|${REGION_CODE}|${NODE_NAME}|${SAFE_PUBLIC_IP}|${AGENT_PORT}|${NODE_ALIAS}|${ENABLE_OTA}"
if [ "$UPGRADE_MODE" == "true" ]; then
echo -e "\n📡 正在向指挥部发送升级成功战报..."
curl -s -X POST "${TG_API_URL}" \
-d "chat_id=${CHAT_ID}" \
-d "parse_mode=Markdown" \
-d "text=✨ *IP-Sentinel 引擎热更新完成!*
📍 节点:\`${NODE_NAME}\`
🌐 IP\`${BIND_IP}\`
🚀 状态v3.2.2 协议自适应与高精度探针已就绪" >/dev/null 2>&1
echo -e "\033[32m✅ 升级成功通知已推送到您的 Telegram\033[0m"
else
echo -e "\n📡 正在向指挥部发送注册暗号..."
# 构造注册暗号 (V3.1.3 协议升级: 携带 REGION_CODE 大区标识)
REG_MSG="#REGISTER#|${REGION_CODE}|${NODE_NAME}|${BIND_IP}|${AGENT_PORT}"
# 读取本地老版本号,如果没有则视为远古版本 v3.3.1
OLD_VERSION=$(grep "^AGENT_VERSION=" "$CONFIG_FILE" | cut -d'"' -f2)
[ -z "$OLD_VERSION" ] && OLD_VERSION="3.3.1"
# 执行主动推送
# [路由表 1]: 跨代兼容 (老版本 < v3.3.2)
# 必须强制下发带有 #REGISTER# 的警告,引导长官重新同步哈希身份
if version_lt "$OLD_VERSION" "3.3.2"; then
echo -e "\n📡 [路由枢纽] 正在执行跨代架构重组 (v${OLD_VERSION} -> v${TARGET_VERSION})..."
curl -s -X POST "${TG_API_URL}" \
-d "chat_id=${CHAT_ID}" \
-d "parse_mode=Markdown" \
-d "text=✨ *IP-Sentinel 引擎热更新完成!*
📍 节点:\`${NODE_ALIAS}\`
🌐 IP\`${SAFE_PUBLIC_IP}\`
🚀 状态v${TARGET_VERSION} OTA 动态活体引擎已部署
⚠️ *战区架构已重组,请务必点击下方指令并发送,以同步新的防撞档案:*
\`${REG_MSG}\`" >/dev/null 2>&1
echo -e "\033[32m✅ 升级通知已推送!请前往 TG 点击注册指令完成身份同步!\033[0m"
# [路由表 2]: 现代静默升级 (老版本 >= v3.3.2)
else
echo -e "\n📡 [路由枢纽] 正在执行静默平滑升级 (v${OLD_VERSION} -> v${TARGET_VERSION})..."
curl -s -X POST "${TG_API_URL}" \
-d "chat_id=${CHAT_ID}" \
-d "parse_mode=Markdown" \
-d "text=✨ *IP-Sentinel 引擎热更新完成!*
📍 节点:\`${NODE_ALIAS}\`
🌐 IP\`${SAFE_PUBLIC_IP}\`
🚀 状态v${TARGET_VERSION} OTA 动态活体引擎已部署" >/dev/null 2>&1
echo -e "\033[32m✅ 升级成功通知已推送到您的 Telegram\033[0m"
fi
# [清理遗留垃圾并刷新版本号]
sed -i '/^NAME_HASHED=/d' "$CONFIG_FILE" 2>/dev/null # 抹除上个版本的临时基因锁
if grep -q "^AGENT_VERSION=" "$CONFIG_FILE"; then
sed -i "s/^AGENT_VERSION=.*/AGENT_VERSION=\"$TARGET_VERSION\"/" "$CONFIG_FILE"
else
echo "AGENT_VERSION=\"$TARGET_VERSION\"" >> "$CONFIG_FILE"
fi
else
# [全新安装路由]
echo -e "\n📡 正在向指挥部发送注册暗号..."
PUSH_RESULT=$(curl -s -X POST "${TG_API_URL}" \
-d "chat_id=${CHAT_ID}" \
-d "parse_mode=Markdown" \
-d "text=✨ *IP-Sentinel 部署成功!*
📍 区域:${REGION_NAME}
🌐 IP${BIND_IP}
🌐 IP${SAFE_PUBLIC_IP}
🔌 端口:${AGENT_PORT}
🔑 *请点击下方指令复制并回复给机器人:*
@@ -486,8 +861,8 @@ if [[ -n "$TG_TOKEN" ]]; then
elif command -v firewall-cmd >/dev/null 2>&1 && systemctl is-active firewalld | grep -qw active; then
FW_MSG="firewall-cmd --zone=public --add-port=$AGENT_PORT/tcp --permanent && firewall-cmd --reload"
elif command -v iptables >/dev/null 2>&1; then
# 智能双栈雷达:根据绑定的 IP 属性,动态下发对应的防火墙放行指令
if [[ "$BIND_IP" == *":"* ]]; then
# 智能双栈雷达:根据对外公网 IP 属性,动态下发对应的防火墙放行指令
if [[ "$SAFE_PUBLIC_IP" == *":"* ]]; then
FW_MSG="ip6tables -I INPUT -p tcp --dport $AGENT_PORT -j ACCEPT"
else
FW_MSG="iptables -I INPUT -p tcp --dport $AGENT_PORT -j ACCEPT"
@@ -512,5 +887,5 @@ if [ -n "$AGENT_COUNT" ] && [[ "$AGENT_COUNT" =~ ^[0-9]+$ ]]; then
echo -e "\033[32m✅ 感谢您成为全球第 ${AGENT_COUNT} 名 IP-Sentinel 哨兵!\033[0m"
else
echo -e "\033[32m✅ 感谢您加入 IP-Sentinel 哨兵阵列!\033[0m"
fi
echo -e "\n"
fi
echo -e "\n"

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# ==========================================================
# 脚本名称: mod_google.sh (Google 业务逻辑模块)
# 脚本名称: mod_google.sh (Google 业务逻辑模块 - 动态锚点版)
# 核心功能: 执行坐标微抖动、模拟真实阅读时长、会话行为拉伸
# ==========================================================
@@ -16,11 +16,15 @@ else
exit 1
fi
# 容错机制:如果父进程没有传递 log 函数,则本地定义一个作为 fallback
# 容错机制:如果父进程没有传递 log 函数,则本地定义一个作为 fallback (v3.4.0 引入版本探针)
if ! type log >/dev/null 2>&1; then
log() {
# [v3.4.0 核心] 提取当前配置中的版本锚点
local local_ver="${AGENT_VERSION:-未知}"
mkdir -p "${INSTALL_DIR}/logs"
printf "[$(date '+%Y-%m-%d %H:%M:%S')] [%-5s] [%-7s] [%s] %s\n" "$2" "$1" "$REGION_CODE" "$3" >> "${INSTALL_DIR}/logs/sentinel.log"
# 统一日志格式,注入 [版本号] 追踪标识
printf "[$(date '+%Y-%m-%d %H:%M:%S')] [v%-5s] [%-5s] [%-7s] [%s] %s\n" "$local_ver" "$2" "$1" "$REGION_CODE" "$3" >> "${INSTALL_DIR}/logs/sentinel.log"
}
fi
@@ -48,8 +52,8 @@ get_random_coord() {
}
# --- [环境初始化] ---
# [v3.0.2修复] 直接读取系统已锁定的锚点 IP彻底杜绝“获取IP失败”及隧道偏移
CURRENT_IP="${BIND_IP:-Unknown}"
# [v3.3.1修改] 优先读取对外公网面孔作为哈希种子,兼容 NAT 机的空 BIND_IP
CURRENT_IP="${PUBLIC_IP:-${BIND_IP:-Unknown}}"
# -----------------------------------------------------------
# [V3.1.5] 哈希锚定法 (Hash-Seeded Persona)
@@ -93,14 +97,21 @@ CURL_BIND_OPT=""
DYNAMIC_IP_PREF="-${IP_PREF:-4}" # 默认提取用户配置
if [[ -n "$BIND_IP" && "$BIND_IP" =~ ^[0-9a-fA-F:\.]+$ ]]; then
CURL_BIND_OPT="--interface $BIND_IP"
# 智能探测:带冒号为 V6带点号为 V4
if [[ "$BIND_IP" == *":"* ]]; then
DYNAMIC_IP_PREF="-6"
log "$MODULE_NAME" "INFO " "底层路由锁定: 绑定 IPv6 出口及协议 ($BIND_IP)"
elif [[ "$BIND_IP" == *"."* ]]; then
DYNAMIC_IP_PREF="-4"
log "$MODULE_NAME" "INFO " "底层路由锁定: 绑定 IPv4 出口及协议 ($BIND_IP)"
# [v3.6.3 容错层补丁] 探测物理网卡/虚拟 IP 存活状态
RAW_BIND_IP=$(echo "$BIND_IP" | tr -d '[]')
if ! ip addr show 2>/dev/null | grep -qw "$RAW_BIND_IP"; then
log "$MODULE_NAME" "WARN " "检测到配置的出口 IP ($RAW_BIND_IP) 已丢失,自动降级为系统默认路由出网!"
CURL_BIND_OPT=""
else
CURL_BIND_OPT="--interface $BIND_IP"
# 智能探测:带冒号为 V6带点号为 V4
if [[ "$BIND_IP" == *":"* ]]; then
DYNAMIC_IP_PREF="-6"
log "$MODULE_NAME" "INFO " "底层路由锁定: 绑定 IPv6 出口及协议 ($BIND_IP)"
elif [[ "$BIND_IP" == *"."* ]]; then
DYNAMIC_IP_PREF="-4"
log "$MODULE_NAME" "INFO " "底层路由锁定: 绑定 IPv4 出口及协议 ($BIND_IP)"
fi
fi
fi

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# ==========================================================
# 脚本名称: mod_trust.sh (IP 信用净化模块 V3.1.4 拓扑自适应版)
# 脚本名称: mod_trust.sh (IP 信用净化模块 - 动态锚点版)
# 核心功能: 动态扫描本地 LBS 冷数据,提取权威白名单,执行流量净化
# ==========================================================
@@ -11,7 +11,7 @@ UA_FILE="${INSTALL_DIR}/data/user_agents.txt"
# 你的 GitHub 仓库 Raw 数据直链前缀
REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main"
# 临时改为私库地址用于测试
# REPO_RAW_URL="https://git.94211762.xyz/hotyue/IP-Sentinel/raw/branch/main"
# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/v3.6.2-rc"
# 1. 基础环境校验
[ ! -f "$CONFIG_FILE" ] && exit 1
@@ -41,12 +41,16 @@ if [ ${#TRUST_URLS[@]} -eq 0 ]; then
TRUST_URLS=("https://en.wikipedia.org/wiki/Special:Random" "https://www.apple.com/" "https://www.microsoft.com/")
fi
# 3. 日志规范化
# 3. 日志规范化 (v3.4.0 引入版本探针)
log_msg() {
local TYPE=$1
local MSG=$2
local TIME=$(date "+%Y-%m-%d %H:%M:%S")
echo "[$TIME] [$TYPE] [Trust ] [$REGION] $MSG" | tee -a "$LOG_FILE"
# [v3.4.0 核心] 提取当前配置中的版本锚点
local local_ver="${AGENT_VERSION:-未知}"
# 日志格式注入 [版本号] 追踪标识,保持对齐
echo "[$TIME] [v%-5s] [%-5s] [Trust ] [$REGION] $MSG" | sed "s/%-5s/$local_ver/;s/%-5s/$TYPE/" | tee -a "$LOG_FILE"
}
# 4. 锁定单次会话指纹
@@ -59,8 +63,8 @@ if [ -f "$UA_FILE" ]; then
TOTAL_UA=${#UA_POOL[@]}
if [ "$TOTAL_UA" -gt 0 ]; then
# 以本地锁定的公网 IP (BIND_IP) 为种子计算 CRC32 哈希值
SEED=$(echo -n "${BIND_IP:-127.0.0.1}" | cksum | awk '{print $1}')
# [v3.3.1修改] 优先使用固化的公网 IP 作为哈希种子,防止 NAT 节点指纹同质化
SEED=$(echo -n "${PUBLIC_IP:-${BIND_IP:-127.0.0.1}}" | cksum | awk '{print $1}')
# 利用确定的种子,在全球 4000 的库中,计算出本机的 3 个绝对专属坐标
IDX1=$(( SEED % TOTAL_UA ))
@@ -95,14 +99,21 @@ CURL_BIND_OPT=""
DYNAMIC_IP_PREF="-${IP_PREF:-4}" # 默认提取用户配置
if [[ -n "$BIND_IP" && "$BIND_IP" =~ ^[0-9a-fA-F:\.]+$ ]]; then
CURL_BIND_OPT="--interface $BIND_IP"
# 智能探测:带冒号为 V6带点号为 V4
if [[ "$BIND_IP" == *":"* ]]; then
DYNAMIC_IP_PREF="-6"
log_msg "INFO " "底层路由锁定: 绑定 IPv6 出口及协议 ($BIND_IP)"
elif [[ "$BIND_IP" == *"."* ]]; then
DYNAMIC_IP_PREF="-4"
log_msg "INFO " "底层路由锁定: 绑定 IPv4 出口及协议 ($BIND_IP)"
# [v3.6.3 容错层补丁] 探测物理网卡/虚拟 IP 存活状态
RAW_BIND_IP=$(echo "$BIND_IP" | tr -d '[]')
if ! ip addr show 2>/dev/null | grep -qw "$RAW_BIND_IP"; then
log_msg "WARN " "检测到配置的出口 IP ($RAW_BIND_IP) 已丢失,自动降级为系统默认路由出网!"
CURL_BIND_OPT=""
else
CURL_BIND_OPT="--interface $BIND_IP"
# 智能探测:带冒号为 V6带点号为 V4
if [[ "$BIND_IP" == *":"* ]]; then
DYNAMIC_IP_PREF="-6"
log_msg "INFO " "底层路由锁定: 绑定 IPv6 出口及协议 ($BIND_IP)"
elif [[ "$BIND_IP" == *"."* ]]; then
DYNAMIC_IP_PREF="-4"
log_msg "INFO " "底层路由锁定: 绑定 IPv4 出口及协议 ($BIND_IP)"
fi
fi
fi

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# ==========================================================
# 脚本名称: runner.sh (IP-Sentinel 主控调度引擎 V2.0 智能分配版)
# 脚本名称: runner.sh (IP-Sentinel 主控调度引擎 - 动态锚点版)
# 核心功能: 防并发延迟启动、功能开关(Feature Flag)自适应、多模块概率轮盘调度
# ==========================================================
@@ -15,14 +15,26 @@ if [ ! -f "$CONFIG_FILE" ]; then
fi
source "$CONFIG_FILE"
# 2. 全局日志写入函数 (导出给子进程共享使用)
# ================== [新增: 文件排他锁,防止并发重入引发内存雪崩] ==================
exec 200>"/tmp/ip_sentinel_runner.lock"
if ! flock -n 200; then
echo "[$(date)] ⚠️ 上一轮巡逻任务尚未结束,本次触发自动取消。" >> "$LOG_FILE"
exit 0
fi
# ==================================================================================
# 2. 全局日志写入函数 (导出给子进程共享使用v3.4.0 引入版本探针)
log() {
local module=$1
local level=$2
local msg=$3
# [v3.4.0 核心] 提取当前配置中的版本锚点
local local_ver="${AGENT_VERSION:-未知}"
# 保证日志目录存在
mkdir -p "${INSTALL_DIR}/logs"
printf "[$(date '+%Y-%m-%d %H:%M:%S')] [%-5s] [%-7s] [%s] %s\n" "$level" "$module" "$REGION_CODE" "$msg" >> "$LOG_FILE"
# 日志格式注入 [版本号] 追踪标识
printf "[$(date '+%Y-%m-%d %H:%M:%S')] [v%-5s] [%-5s] [%-7s] [%s] %s\n" "$local_ver" "$level" "$module" "$REGION_CODE" "$msg" >> "$LOG_FILE"
}
export -f log
export CONFIG_FILE INSTALL_DIR

View File

@@ -1,8 +1,8 @@
#!/bin/bash
# ==========================================================
# 脚本名称: tg_daemon.sh (Telegram 互动监听守护进程)
# 核心功能: 极低功耗长轮询监听 TG 指令,实现远程控制
# 脚本名称: tg_daemon.sh (Telegram 互动监听守护进程 - 动态锚点版)
# 核心功能: 极低功耗长轮询监听、节点溯源、版本继承
# ==========================================================
INSTALL_DIR="/opt/ip_sentinel"
@@ -16,6 +16,11 @@ source "$CONFIG_FILE"
# 如果没有配置 TG 机器人,则安静退出守护进程
[ -z "$TG_TOKEN" ] || [ -z "$CHAT_ID" ] && exit 0
# [核心: 动态版本锚点与防撞甲身份载入]
LOCAL_VER="${AGENT_VERSION:-未知}"
IP_HASH=$(echo "${PUBLIC_IP:-127.0.0.1}" | md5sum | cut -c 1-4 | tr 'a-z' 'A-Z')
NODE_NAME="$(hostname | cut -c 1-10)-${IP_HASH}"
# 2. 初始化消息偏移量 (Offset) 记录文件,防止重启后重复处理老消息
OFFSET=0
[ -f "$OFFSET_FILE" ] && OFFSET=$(cat "$OFFSET_FILE")
@@ -44,20 +49,20 @@ while true; do
if [ "$MSG_CHAT_ID" == "$CHAT_ID" ]; then
case "$MSG_TEXT" in
"/run")
send_msg "🚀 **[指令下达]** 正在后台立即触发 IP 养护任务..."
send_msg "🚀 **[${NODE_NAME}]** 正在后台触发 IP 养护任务 (v${LOCAL_VER})..."
# 使用 nohup 另起后台独立进程运行,防止阻塞当前监听器的循环
nohup bash "${INSTALL_DIR}/core/mod_google.sh" >/dev/null 2>&1 &
;;
"/log")
LOG_DATA=$(tail -n 15 "${INSTALL_DIR}/logs/sentinel.log")
send_msg "📄 **[最近 15 行系统日志]**%0A\`\`\`log%0A${LOG_DATA}%0A\`\`\`"
send_msg "📄 **[${NODE_NAME}] 实时日志 (v${LOCAL_VER}):**%0A\`\`\`log%0A${LOG_DATA}%0A\`\`\`"
;;
"/report")
# 触发生成一次战报
bash "${INSTALL_DIR}/core/tg_report.sh"
;;
"/help"|"/start")
HELP_MSG="🛡️ **IP-Sentinel 控制台**%0A/run - 立刻执行一次养护%0A/log - 抓取最新运行日志%0A/report - 手动生成统计简报"
HELP_MSG="🛡️ **IP-Sentinel 边缘控制台**%0A📍 节点: \`${NODE_NAME}\`%0A🔖 版本: \`v${LOCAL_VER}\`%0A%0A/run - 立刻执行一次养护%0A/log - 抓取最新运行日志%0A/report - 手动生成统计简报"
send_msg "$HELP_MSG"
;;
esac

View File

@@ -1,8 +1,8 @@
#!/bin/bash
# ==========================================================
# 脚本名称: tg_report.sh (Telegram 每日战报模块 V6.0 动态拼装版)
# 核心功能: 适配 Feature Flag 架构,按需展示 Google/Trust 独立统计数据
# 脚本名称: tg_report.sh (Telegram 每日战报模块 - 动态锚点版)
# 核心功能: 适配 Feature Flag 架构,按需展示独立统计数据OTA 更新预警
# ==========================================================
INSTALL_DIR="/opt/ip_sentinel"
@@ -19,25 +19,36 @@ if [ -z "$TG_TOKEN" ] || [ -z "$CHAT_ID" ]; then
fi
# 2. 节点元数据抓取 (v3.2.2 协议自适应与多级容灾版)
NODE_NAME=$(hostname | cut -c 1-15)
# [v3.5.2 核心: 引入双轨身份架构]
if [ -z "$NODE_NAME" ]; then
IP_HASH=$(echo "${PUBLIC_IP:-127.0.0.1}" | md5sum | cut -c 1-4 | tr 'a-z' 'A-Z')
NODE_NAME="$(hostname | cut -c 1-10)-${IP_HASH}"
fi
NODE_ALIAS="${NODE_ALIAS:-$NODE_NAME}"
# --- [防线 1: 底层路由锁定与协议自适应] ---
CURL_BIND_OPT=""
DYNAMIC_IP_PREF="-${IP_PREF:-4}"
if [[ -n "$BIND_IP" && "$BIND_IP" =~ ^[0-9a-fA-F:\.]+$ ]]; then
CURL_BIND_OPT="--interface $BIND_IP"
if [[ "$BIND_IP" == *":"* ]]; then
DYNAMIC_IP_PREF="-6"
elif [[ "$BIND_IP" == *"."* ]]; then
DYNAMIC_IP_PREF="-4"
# [v3.6.3 容错层补丁] 探测物理网卡/虚拟 IP 存活状态
RAW_BIND_IP=$(echo "$BIND_IP" | tr -d '[]')
if ! ip addr show 2>/dev/null | grep -qw "$RAW_BIND_IP"; then
CURL_BIND_OPT=""
else
CURL_BIND_OPT="--interface $BIND_IP"
if [[ "$BIND_IP" == *":"* ]]; then
DYNAMIC_IP_PREF="-6"
elif [[ "$BIND_IP" == *"."* ]]; then
DYNAMIC_IP_PREF="-4"
fi
fi
fi
# 多节点容灾探测出口 IP (注入协议自适应)
CURRENT_IP=$( (curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -s -m 5 api.ip.sb/ip || curl $CURL_BIND_OPT $DYNAMIC_IP_PREF -s -m 5 ifconfig.me) 2>/dev/null | tr -d '[:space:]' )
# 强制兜底:如果所有外部 API 挂了,直接使用本地强行锁定的 BIND_IP
[ -z "$CURRENT_IP" ] && CURRENT_IP="$BIND_IP"
# [v3.3.1 修改] 强制兜底:如果外部 API 挂了,优先使用固化的对外公网面孔 (兼容 NAT 机的空 BIND_IP)
[ -z "$CURRENT_IP" ] && CURRENT_IP="${PUBLIC_IP:-$BIND_IP}"
# 为可能获取到的 IPv6 自动添加方括号护甲
[[ "$CURRENT_IP" == *":"* ]] && [[ "$CURRENT_IP" != *"["* ]] && CURRENT_IP="[${CURRENT_IP}]"
@@ -81,17 +92,18 @@ case "$REGION_CODE" in
"SG") FLAG="🇸🇬" ;;
"HK") FLAG="🇭🇰" ;;
"GB"|"UK") FLAG="🇬🇧" ;;
"AU") FLAG="🇦🇺" ;;
*) FLAG="🌐" ;;
esac
# 3. 截取过去 24 小时的日志
LOG_CONTENT=$(find "$LOG_FILE" -mtime -1 -exec cat {} \; 2>/dev/null)
# 3. 截取过去 24 小时的日志 (每天48次轮询保留最新 1000 行足以覆盖单日战报)
LOG_CONTENT=$(tail -n 1000 "$LOG_FILE" 2>/dev/null)
if [ -z "$LOG_CONTENT" ]; then
read -r -d '' MSG <<EOT
🛑 **[IP-Sentinel] 告警:节点异常**
----------------------------
📍 **节点名称**: \`${NODE_NAME}\`
📍 **节点名称**: \`${NODE_ALIAS}\`
⚠️ **警告**: 过去 24 小时无运行日志!
🛠️ **建议**: 节点可能刚部署完毕,请在面板手动执行一次养护动作。
EOT
@@ -109,7 +121,7 @@ else
# 开始组装战报头部
MSG="📊 **IP-Sentinel 每日简报 (${FLAG} ${REGION_NAME})**
----------------------------
📍 **节点名称**: \`${NODE_NAME}\`
📍 **节点名称**: \`${NODE_ALIAS}\`
📡 **出口 IP**: \`${CURRENT_IP}\`
🛡️ **IP 属性**: ${IP_TYPE}"
@@ -153,12 +165,41 @@ else
🕒 **最近执行快照 [${LAST_MOD:-"System"}]:**
时间: ${LAST_TIME:-"暂无数据"}
结论: ${LAST_SCORE:-"暂无数据"}
----------------------------
💡 哨兵正在后台默默守护您的资产。"
结论: ${LAST_SCORE:-"暂无数据"}"
fi
# ==========================================
# 5. [核心: OTA 云端版本探针与告警模块]
# ==========================================
# 从配置文件提取当前本地版本,若无则默认为未知
LOCAL_VER="${AGENT_VERSION:-未知}"
# 极轻量级探针: 抓取 GitHub 云端的 version.txt (超时 3 秒KV解析法)
REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main"
REMOTE_VER=$(curl -s -m 3 "${REPO_RAW_URL}/version.txt" | grep "^AGENT_VERSION=" | cut -d'=' -f2 | tr -d '[:space:]')
# 构建底部引擎状态块
MSG="$MSG
----------------------------
🛡️ **系统引擎状态**
当前运行版本: \`v${LOCAL_VER}\`"
# 比对逻辑:如果成功抓到了远端版本,且和本地不一样
if [ -n "$REMOTE_VER" ] && [ "$REMOTE_VER" != "$LOCAL_VER" ]; then
MSG="$MSG
最新官方版本: \`v${REMOTE_VER}\` (✨有新版)
💡 *司令部提示:检测到新版装甲,请长官登录节点执行平滑热更新!*"
elif [ -n "$REMOTE_VER" ] && [ "$REMOTE_VER" == "$LOCAL_VER" ]; then
MSG="$MSG
最新官方版本: \`v${REMOTE_VER}\` (✅已是最新)
💡 *哨兵正在后台默默守护您的资产。*"
else
# 抓取失败兜底
MSG="$MSG
💡 *哨兵正在后台默默守护您的资产。*"
fi
# 5. 调用 API 推送 (接入安全网关)
RESPONSE=$(curl -s -m 10 -X POST "${TG_API_URL}" \
-d "chat_id=${CHAT_ID}" \

View File

@@ -1,22 +1,57 @@
#!/bin/bash
# ==========================================================
# 脚本名称: uninstall.sh (IP-Sentinel 一键卸载脚本 V3.1.4 焦土版)
# 脚本名称: uninstall.sh (IP-Sentinel 一键卸载脚本 - 动态锚点版)
# 核心功能: 无痕清理守护进程、定时任务、运行目录及临时缓存
# ==========================================================
# ==========================================================
# 🛑 核心权限防线: 检查是否以 root 权限运行
# ==========================================================
if [ "$EUID" -ne 0 ]; then
echo -e "\033[31m❌ 权限被拒绝: 卸载 IP-Sentinel 需要最高系统权限。\033[0m"
echo -e "💡 请切换到 root 用户 (执行 su root 或 sudo -i) 后重新运行指令。"
exit 1
fi
INSTALL_DIR="/opt/ip_sentinel"
echo "========================================================"
echo " 🗑️ 准备卸载 IP-Sentinel (边缘节点 Edge Agent)"
# [核心: 动态读取并播报即将销毁的本地版本号]
CONFIG_FILE="${INSTALL_DIR}/config.conf"
if [ -f "$CONFIG_FILE" ]; then
CURRENT_VER=$(grep "^AGENT_VERSION=" "$CONFIG_FILE" | cut -d'"' -f2)
[ -n "$CURRENT_VER" ] && echo " 📍 目标版本: v${CURRENT_VER}"
fi
echo "========================================================"
# 1. 停止运行中的守护进程与主控模块 (涵盖所有历史版本进程)
echo "[1/3] 正在终止后台守护进程与所有养护任务..."
# 1. 停止并删除 Systemd 服务 (适配新架构)
echo "[1/4] 正在停止并删除 Systemd 服务..."
if command -v systemctl >/dev/null 2>&1; then
echo "💡 检测到 Systemd 环境,正在抹除 Systemd 服务单元..."
systemctl disable --now ip-sentinel-runner.service ip-sentinel-runner.timer \
ip-sentinel-updater.service ip-sentinel-updater.timer \
ip-sentinel-report.service ip-sentinel-report.timer \
ip-sentinel-agent-daemon.service >/dev/null 2>&1
rm -f /etc/systemd/system/ip-sentinel-runner.service
rm -f /etc/systemd/system/ip-sentinel-runner.timer
rm -f /etc/systemd/system/ip-sentinel-updater.service
rm -f /etc/systemd/system/ip-sentinel-updater.timer
rm -f /etc/systemd/system/ip-sentinel-report.service
rm -f /etc/systemd/system/ip-sentinel-report.timer
rm -f /etc/systemd/system/ip-sentinel-agent-daemon.service
systemctl daemon-reload
systemctl reset-failed
else
echo "💡 未检测到 Systemd跳过此步骤..."
fi
# 使用 pkill 替代传统的 pgrep | xargs指令更短、容错率更高
# 2. 停止运行中的守护进程与主控模块 (兜底清理老版进程)
echo "[2/4] 正在终止后台守护进程与所有养护任务..."
pkill -9 -f "tg_daemon.sh" >/dev/null 2>&1
pkill -9 -f "agent_daemon.sh" >/dev/null 2>&1
pkill -9 -f "python3.*webhook.py" >/dev/null 2>&1
pkill -9 -f "webhook.py" >/dev/null 2>&1
pkill -9 -f "runner.sh" >/dev/null 2>&1
pkill -9 -f "updater.sh" >/dev/null 2>&1
@@ -24,16 +59,16 @@ pkill -9 -f "tg_report.sh" >/dev/null 2>&1
pkill -9 -f "mod_google.sh" >/dev/null 2>&1
pkill -9 -f "mod_trust.sh" >/dev/null 2>&1
# 2. 清除系统定时任务 (Cron)
echo "[2/3] 正在清理系统定时任务 (Cron)..."
# 3. 清除系统定时任务 (Cron)
echo "[3/4] 正在清理系统定时任务 (Cron)..."
if crontab -l >/dev/null 2>&1; then
crontab -l | grep -v "ip_sentinel" > /tmp/cron_backup
crontab /tmp/cron_backup
rm -f /tmp/cron_backup
fi
# 3. 删除所有文件、日志与临时缓存
echo "[3/3] 正在抹除核心程序、配置文件与系统痕迹..."
# 4. 删除所有文件、日志与临时缓存
echo "[4/4] 正在抹除核心程序、配置文件与系统痕迹..."
if [ -d "$INSTALL_DIR" ]; then
rm -rf "$INSTALL_DIR"
fi

View File

@@ -1,16 +1,18 @@
#!/bin/bash
# ==========================================================
# 脚本名称: updater.sh (IP-Sentinel V3.1.4 养料注入与维护中枢)
# 核心功能: 静默更新热数据(指纹/词库/LBS规则)、清理瘦身日志
# 脚本名称: updater.sh (IP-Sentinel 养料注入与分频调度中枢 - 动态锚点版)
# 核心功能: 静默更新热数据/LBS、指纹库错峰调度、强制出站死锁、版本无缝继承
# ==========================================================
INSTALL_DIR="/opt/ip_sentinel"
CONFIG_FILE="${INSTALL_DIR}/config.conf"
# 你的 GitHub 仓库 Raw 数据直链前缀 (统一标准)
UA_TIME_FILE="${INSTALL_DIR}/core/.ua_last_update"
# GitHub 仓库 Raw 数据直链前缀
REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main"
# 临时改为私库地址用于测试
# REPO_RAW_URL="https://git.94211762.xyz/hotyue/IP-Sentinel/raw/branch/main"
# 临时改为开发地址用于测试
# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/v3.6.2-rc"
# 1. 加载本地冷数据配置
if [ ! -f "$CONFIG_FILE" ]; then
@@ -18,57 +20,111 @@ if [ ! -f "$CONFIG_FILE" ]; then
fi
source "$CONFIG_FILE"
# 2. 全局日志写入函数
# 2. 全局日志写入函数 (v3.4.0 引入版本探针)
log() {
# [v3.4.0 核心] 提取当前配置中的版本锚点
local local_ver="${AGENT_VERSION:-未知}"
mkdir -p "${INSTALL_DIR}/logs"
printf "[$(date '+%Y-%m-%d %H:%M:%S')] [%-5s] [%-7s] [%s] %s\n" "$2" "$1" "$REGION_CODE" "$3" >> "$LOG_FILE"
# 日志格式注入 [版本号] 追踪标识
printf "[$(date '+%Y-%m-%d %H:%M:%S')] [v%-5s] [%-5s] [%-7s] [%s] %s\n" "$local_ver" "$2" "$1" "$REGION_CODE" "$3" >> "$LOG_FILE"
}
log "Updater" "INFO " "========== 触发后台静默 OTA 热数据更新 =========="
# 3. 容灾机制拉取 UA 指纹池 (强制遵循锚点协议)
TMP_UA="/tmp/ip_sentinel_ua.txt"
curl -${IP_PREF:-4} -sL "${REPO_RAW_URL}/data/user_agents.txt" -o "$TMP_UA"
if [ -s "$TMP_UA" ]; then
mv "$TMP_UA" "${INSTALL_DIR}/data/user_agents.txt"
log "Updater" "INFO " "✅ 设备指纹池 (User-Agents) 更新成功"
else
log "Updater" "WARN " "❌ UA 池拉取失败,保留本地旧数据防崩溃"
rm -f "$TMP_UA"
# ==========================================================
# 🛡️ 终极护城河:构建强锚定出站的 curl 请求引擎
# ==========================================================
# 基础参数:跟随 install.sh 锁定的协议偏好 (4 或 6)
CURL_CMD="curl -${IP_PREF:-4} -sL"
# 【防坑核心】如果用户配置了死锁锚点,必须强制绑定网卡,杜绝流量溢出!
if [ -n "$BIND_IP" ]; then
# curl 的 --interface 参数不支持带方括号的 IPv6 地址,必须强行脱壳
RAW_BIND_IP=$(echo "$BIND_IP" | tr -d '[]')
# [v3.6.3 容错层补丁] 探测网卡存活状态,防止 IP 漂移导致永久断网
if ! ip addr show 2>/dev/null | grep -qw "$RAW_BIND_IP"; then
log "Updater" "WARN " "检测到绑定的出口 IP ($RAW_BIND_IP) 已丢失,自动退回默认路由!"
else
CURL_CMD="$CURL_CMD --interface $RAW_BIND_IP"
fi
fi
# 4. 容灾机制拉取当地最新搜索词库
# ==========================================================
# 3. 容灾机制拉取 UA 指纹池 (V3.3.0 引入 30 天错峰防惊群逻辑)
# ==========================================================
NOW=$(date +%s)
LAST_UPDATE=0
# 读取上一次更新的时间戳
if [ -f "$UA_TIME_FILE" ]; then
# tr -d 清除可能存在的换行或回车符,防止算术崩溃
LAST_UPDATE=$(cat "$UA_TIME_FILE" | tr -d '\r\n')
fi
# 校验数据合法性,防崩溃
if ! [[ "$LAST_UPDATE" =~ ^[0-9]+$ ]]; then
LAST_UPDATE=0
fi
DIFF=$((NOW - LAST_UPDATE))
# 距离上次拉取超过 30 天 (2592000 秒),才执行下载
if [ "$DIFF" -ge 2592000 ] || [ "$LAST_UPDATE" -eq 0 ]; then
TMP_UA="/tmp/ip_sentinel_ua.txt"
# 使用重装升级后的 CURL_CMD
$CURL_CMD "${REPO_RAW_URL}/data/user_agents.txt" -o "$TMP_UA"
if [ -s "$TMP_UA" ]; then
mv "$TMP_UA" "${INSTALL_DIR}/data/user_agents.txt"
echo "$NOW" > "$UA_TIME_FILE"
log "Updater" "INFO " "✅ 设备指纹池 (User-Agents) 30天错峰滚动更新成功"
else
log "Updater" "WARN " "❌ UA 池拉取失败,保留本地旧数据防崩溃"
rm -f "$TMP_UA"
fi
else
DAYS_LEFT=$(((2592000 - DIFF) / 86400))
log "Updater" "INFO " "⏳ 设备指纹池处于 30 天静默期 (剩余约 ${DAYS_LEFT} 天),跳过拉取"
fi
# ==========================================================
# 4. 容灾机制拉取当地最新搜索词库 (每日高频拉取,保证活体新鲜度)
# ==========================================================
TMP_KW="/tmp/ip_sentinel_kw.txt"
curl -${IP_PREF:-4} -sL "${REPO_RAW_URL}/data/keywords/kw_${REGION_CODE}.txt" -o "$TMP_KW"
$CURL_CMD "${REPO_RAW_URL}/data/keywords/kw_${REGION_CODE}.txt" -o "$TMP_KW"
if [ -s "$TMP_KW" ]; then
mv "$TMP_KW" "${INSTALL_DIR}/data/keywords/kw_${REGION_CODE}.txt"
log "Updater" "INFO " "✅ 区域搜索词库 (kw_${REGION_CODE}) 更新成功"
log "Updater" "INFO " "✅ 区域搜索词库 (kw_${REGION_CODE}) 每日同步成功"
else
log "Updater" "WARN " "❌ 搜索词库拉取失败,保留本地旧数据防崩溃"
rm -f "$TMP_KW"
fi
# 5. 【V3.1.4 核心升级】自适应拉取本地 LBS 专属 JSON 规则库
# 利用 find 穿透寻找本地唯一的 json
# ==========================================================
# 5. 自适应拉取本地 LBS 专属 JSON 规则库 (每日同步)
# ==========================================================
REGION_JSON_FILE=$(find "${INSTALL_DIR}/data/regions" -name "*.json" 2>/dev/null | head -n 1)
if [ -n "$REGION_JSON_FILE" ] && [ -f "$REGION_JSON_FILE" ]; then
# 提取本地文件的相对路径 (例如: data/regions/US/CA/San_Jose.json)
REL_PATH=${REGION_JSON_FILE#*${INSTALL_DIR}/}
TMP_JSON="/tmp/ip_sentinel_region.json"
# 按照相同的相对路径去云端拉取更新
curl -${IP_PREF:-4} -sL "${REPO_RAW_URL}/${REL_PATH}" -o "$TMP_JSON"
$CURL_CMD "${REPO_RAW_URL}/${REL_PATH}" -o "$TMP_JSON"
if [ -s "$TMP_JSON" ]; then
mv "$TMP_JSON" "$REGION_JSON_FILE"
log "Updater" "INFO " "✅ 核心战区规则库 ($REL_PATH) 更新成功"
log "Updater" "INFO " "✅ 核心战区规则库 ($REL_PATH) 每日同步成功"
else
log "Updater" "WARN " "❌ 战区规则库拉取失败,保留本地旧数据"
rm -f "$TMP_JSON"
fi
fi
# ==========================================================
# 6. 日志防满瘦身机制 (保留最近 2000 行)
# ==========================================================
if [ -f "$LOG_FILE" ]; then
tail -n 2000 "$LOG_FILE" > "${LOG_FILE}.tmp"
mv "${LOG_FILE}.tmp" "$LOG_FILE"

191
data/keywords/kw_AU.txt Normal file
View File

@@ -0,0 +1,191 @@
lsg vs rr
pakistan super league
kyle sandilands alleged rant jackie o
carrie bickmore
adam levine
alexandra eala
tubi
charles melton
nuclear weapon
janet jackson
justin bieber australia tour
fleche wallonne 2026
ange postecoglou
john hattie
airbus a380
real madrid vs alavés
brighton vs chelsea
woolworth
nitish rana
lyrid meteor shower
世界地球日
youth gang
earth day
crystal palace vs west ham
d4vd
danish malewar
mi vs gt
perth weather
elijah hollands carlton football club
fair work commission fuel
vanguard
sydney sweeney
cailee spaeny
psg vs lyon
sporting vs benfica
celtics vs 76ers
psl
bundesliga
pl
afc cup
mars rover
celtic fc
bayern vs vfb stuttgart
bom radar
sydney weather
melbourne weather
brisbane weather
adelaide weather
myGov login
news.com.au
abc news
nrl ladder
afl scores
afl fixture
matildas
sam kerr
bunnings opening hours
coles catalogue
woolies specials
qantas
virgin australia
jetstar flights
commbank
asx 200
sydney morning herald
the age
ticketek
ticketmaster
opal card top up
myki top up
translink timetable
transperth journey planner
adelaide metro
adelaide 500
adelaide crows
port adelaide
penrith panthers
brisbane broncos
collingwood fc
sydney swans
west coast eagles
fremantle dockers
canberra raiders
mcg events
optus stadium
the gabba
state of origin
australian open
melbourne cup
masterchef australia
mafs australia
petrol prices near me
australia post tracking
service nsw login
vicroads
queensland health
medicare
ato
jb hi-fi
kmart
amazon.com.au
vivid sydney
mona hobart
dark mofo
floriade canberra
rottnest island ferry
sydney airport arrivals
rba interest rate
nsw school holidays
qld school holidays
wa school holidays
m4 traffic updates
west gate tunnel updates
bruce highway traffic
taylor swift
netflix
gemini
chatgpt
margot robbie
oscar piastri
formula 1
supercars championship
ufc
optus sport
telstra outage
kayo sports
domain real estate
realestate.com.au
seek jobs
gumtree
westpac login
anz internet banking
nab login
aldi catalogue
big w
target australia
the good guys
officeworks
dan murphys
bws
chemist warehouse
priceline
uber eats
menulog
dominos
centrelink login
medicare online
passport renewal
aec enrolment
agl energy
origin energy
stan
binge
9now
7plus
abc iview
hoyts cinemas
event cinemas
big bash league
the ashes
socceroos
bathurst 1000
booking.com
airbnb
webjet
bali weather
smartraveller
lotto results
powerball results
oz lotto
public holidays 2026
mothers day 2026
carsales
redbook
nrma
racv
racq
petrol spy
optus login
vodafone
kogan
catch.com.au
mecca
sydney fish market
queen victoria market
taronga zoo
dreamworld
movie world
wotif
anytime fitness
time in london

108
data/keywords/kw_CA.txt Normal file
View File

@@ -0,0 +1,108 @@
graham platner
lsg vs rr
nikki glaser
global news edmonton
policier
nuclear weapon
motorcycle
msc francesca
poet stock
fifa tickets
7 jours
alexandra eala
earth
zara larsson
girona vs real betis
kevyn adams
ali khamenei
inter côme
leicester city vs hull
fenerbahçe
françois bonnardel
missile
real madrid vs alavés
vrabel and russini photos
will trent
ibm
lecce vs fiorentina
celeste rivas hernandez
grand theft auto vi
abhishek bachchan
national guard of the united states
triathlon
vincent trocheck
benyamin netanyahou
kings vs avalanche
crème solaire
trabzonspor vs istanbul başakşehir
indigenous rights
meghan, duchess of sussex
gwyneth paltrow
toronto gas prices
président
mets vs cubs
matt fitzpatrick
sénateurs hurricanes
senators vs hurricanes
man utd
spurs
evan mobley
chelsea vs man united
atlético madrid vs real sociedad
roma vs atalanta
cf montreal
jakob poeltl
ukraine
contrôle routier québec
bachelorette 2026
lens toulouse
arber xhekaj
leylah fernandez
anthropic
paige wwe
inter cagliari
carrie ann inaba
syria
highway hotline sk
real betis vs braga
vincent bolloré
europa conference league
resident alien
battlefield 6
aston villa vs bologna
nottm forest vs porto
soccer
lamour est dans le pré
luis suárez
listeria
strc
bayern
arda güler
aleksandar pavlović
kooora
yalla kora
ina garten
jordan goodwin
jerami grant
jimmy snuggerud
clav
bts
zach galifianakis
billy crystal
club américa vs nashville
allison williams
CBC News
Canada.ca
Toronto Weather
NHL Scores
Amazon.ca
Air Canada
Service Canada
CRA login
Rogers
Bell Internet
Tim Hortons
Indigo
Canadian Tire
Walmart Canada
Toronto Raptors

View File

@@ -1,3 +1,125 @@
queen camilla
clankriminalität
politik
gladbach-news
sara gündogan
krankenversicherung
jan-lennard struff
bryan lasme
republikanische partei
thailand
robin gosens
maremma
tennis madrid
osterburg
برايتون ضد تشيلسي
sebastian hoeneß
ncis
menowin fröhlich
maren gilzer
cineplex
gina schumacher
alexander räuscher
riza kayaalp
heppenheim
ministerpräsident
robbie williams
brian littrell
saarbrücken hauptbahnhof
frauen-bundesliga
lemgo
kommissar rex
hemsbach
benjamin weber
sydney sweeney
martin schindler
robert kennedy
antoni kowalski
luna
paris-sg lyon
arte live
dominik kohr
dumbledores geheimnisse
kampf der realitystars
kerner
tennessee
billy idol
kfc uerdingen
bastian pastewka
gnabry
lok leipzig heute live ticker
true lies wahre lügen
челси манчестер юнайтед
nurburgring
fortnite server status
süperlig
ronaldinho
esther schweins let's dance
michael jackson film 2026
oliver pocher
die queen film
milano
straße von hormus
motsi mabuse
rayo vallecano
harry meghan
irland
betis sevilla
vermisste person
konferenz league
garda
judith hoersch
jörg pilawa
strasbourg
real madrid vs bayern
kicker
mbappe
flashscore
sport1
vini jr
bet365
kompany
jude bellingham
upamecano
gute zeiten, schlechte zeiten
inflation
fog warning
wetter bochum
wetter aachen
wetter bonn
onet
protest
jamie dornan
heizöl
champions league
uefa champions league
keytruda
péter magyar
psg
hechingen
şampiyonlar ligi
tschernobyl 1986
amazon video
paris saint-germain
dietrich grönemeyer
fränkische schweiz
scarlett johansson
jeff bezos
dan brown
паспорт громадянина україни для виїзду за кордон
serena williams
манчестер юнайтед лидс
catherine deneuve
bobzin
sprit
kev
abschiebung
steuer
masters rory mcilroy
großglockner
news38
jessie cave
michael schulte
wetter frankfurt heute
bundesliga ergebnisse
aktuelle nachrichten deutschland

111
data/keywords/kw_ES.txt Normal file
View File

@@ -0,0 +1,111 @@
alaska cantante
raúl gonzález blanco
marta sanchez
roberto bautista
cifras y letras
xbox game pass ultimate
horse powertrain
las hurdes
herbicida cancer colon
lluvia de barro
ripoll
manilva
steve jobs
berrettini
prizmic
laura moure
lens - toulouse
girona vs real betis
yuri berchiche
clasificacion liga
posiciones de la liga
resultados liga
lfp
umar sadiq
реал мадрид алавес
jan virgili
moreirense - estoril
downton abbey
koldo garcía izaguirre
jorge martín
mike james
carla leite
eclipse solar del 12 de agosto de 2026
crystal palace - west ham
luis merlo
luz valdenebro
porto - tondela
santos - fluminense
juventus
almería - málaga
punjab kings vs lucknow super giants standings
mönchengladbach mainz
victor eloy
paris-sg lyon
psg vs lyon
zamora - osasuna b
estrecho
nurburgring
la 1 directo
oyarzabal
enrique cerezo
fraude
tasa
la 1
tve directo
cuántas copas del rey tiene la real sociedad
eugenia martínez de irujo
ccoo
racing de santander
racing
baliza v16
st. pauli köln
iphone 18
st. pauli - colonia
nico paz
lionel messi
armengol
pau víctor
braga fc
fiorentina vs crystal palace
morante hoy
iago aspas
aston villa
real betis vs braga
ministerio de sanidad
az - shakhtar
arsenal
tiktok
harry kane
sudan
lunin
airef
tiempo de juego
fc bayern
militao
bellingham
supervivientes
jalen green
rockstar games
bam adebayo
china
suns - trail blazers
euromillones
ldu quito - mirassol
davion mitchell
universitario - coquimbo unido
El País
Marca
RTVE Noticias
La Liga
Real Madrid
Barcelona FC
Tiempo Madrid
Renfe
Iberia
Amazon España
El Corte Inglés
Hacienda
Mercadona
YouTube Música
Entradas Cine

View File

@@ -1,3 +1,123 @@
mma
roberto calvet
budget
coupe du monde de football 2006
plus belle la vie en avance
mateus fernandes
tour des alpes 2026
lorenzo finn
maine-et-loire
mathieu flamini
kamel daoud
vandalisme
sydney sweeney
julien odoul
france2
xavier dupont de ligonnès
elisabeth 2
antibes
girona betis
christine bravo
الريال ضد ألافيس
unchosen netflix
madonna age
margot haddad
ana riera
hinaupoko devèze
bruce toussaint
cheque energie
reid wiseman
loto 20 avril 2026
from serie
toulouse
racing 92 stade français
juventus - bologna
film une annee difficile
échouement
programme tv ce soir
porto tondela
matthieu pigasse
santos fluminense
gta 6
laetitia milot
loto 18 avril 2026
bercy
pierre lellouche
adele
adil rami
castres toulouse
angel
stéphane bern
anne claire coudray
pmu résultat
laury thilleman et paul mirabel
quinté du jour
euromillions 17 avril 2026
alain bauer
uson
guillaume meurice
pmu
grenoble oyonnax
bagarre
programme télé
tchernobyl
géraldine maillet
biot
racing
liga europa
tv ce soir
programme tv de ce soir
brad pitt
aston villa
michael olise
robert ménard
match ce soir
sporting
ester exposito
bellingham
iptv
militao
jeff goldblum
lunin
kiev
julien royal
viktor orbán
aqababe
nhl
suns trail blazers
bam adebayo
davion mitchell
l
santos recoleta football club
atletico madrid
tf1
uefa champions league
camille cerf
giorgi mamardashvili
streaming football
atlético madryt fc barcelona
miss france
rts
leonardo balerdi
yann barthes
alain delon
loto du 13 avril 2026
juan arbeláez
hbo
katy perry justin trudeau
jacob elordi
tondela gil vicente
le rugbynistère
epstein
kino
horoscope du 13 avril 2026
golf masters augusta 2026
boursorama bourse
cac 40
sept à huit
ligne 12 métro
alice taglioni
pedro sánchez
meteo paris
actualités en direct
résultats ligue 1

View File

@@ -1,3 +1,119 @@
明天的天氣
破產
weather tomorrow
繼承人
英皇群星演唱會
布浩榮
新聞
貨幣貶值
居 屋 2025
3988
李泳豪老婆
皇家馬德里 對 艾拉維斯
李泳漢
鄭欣宜
srh vs dc
鍾嘉欣
張柏芝
江美儀
全港戲院日 2026
江旻憓
陶傑
水晶宮 對 西漢姆聯
吉達艾阿里
山口智子
百佳超級市場
利息
戴祖儀
陳若思
麥當勞
首岸
中国商飞c919
pl
bundesliga
hailey bieber
德甲
cherki
now
曼城
now tv
al nassr
洪金寶
曼聯
車路士
切爾西 對 曼聯
英超
何沛珈
熱刺
tottenham vs brighton
熱刺 對 布萊頓
epl
司機
补贴
華富邨
零售
藍莓
商湯科技
周國豐
啟點
歐聯
神戶勝利船
潘宏彬
姚正菁
木乃伊
ios 26
李克寧木乃伊
田啟文
曼寧加
arsenal
ucl
歐洲聯賽冠軍盃
arsenal vs sporting
bayern vs real madrid
real madrid
皇馬
拜仁慕尼黑 對 皇家馬德里
claude
補貼
nba 直播
航空公司
向華強
李嘉欣
typhoon
nba
nba線上看
nba直播
全民國家安全教育日
運輸署
liverpool vs psg
利物浦
barcelona
歐冠
馬德里競技 對 巴塞隆納
利物浦 對 巴黎聖日耳曼
hkjc
馬會
航空
2035
man united vs leeds
曼聯 對 里茲聯
prediction market
預測市場
polymarket
巴基斯坦
sndk
楊何蓓茵
樂珈嘉
姜濤
日經平均指數
飲茶
上市公司
daniel caesar
中年好聲音4
香港天文台
煤氣
livenation
政府
香港天文台天氣預報
MTR 港鐵路線圖
OpenRice 附近美食

View File

@@ -1,7 +1,126 @@
サイメモリ
b リーグ 順位
日ハム
ナダル
失点
岩瀬洋志
ファイターズ 試合
江村美咲
宝島社
井ノ原 快彦
ファイターズ
西郷隆盛
ボーダー
チェルシー
関税
ブライトン
佳子内親王
rマドリード 対 アラベス
鳥貴族
ブライトン 対 チェルシー
アシエンダ乗馬学校
ngày trái đất
加藤小夏
町田ゼルビア
モンスターハンターシリーズ
クリスタル・パレス 対 ウェストハム
吉田正尚
旭琉會
神戸
kick
てんちむ
浜辺美波
デーブ ロバーツ
皇治
小雪
にじさんじデビュー
ちゃんよた
坂本 花織
松山 千春
dior
リーグアン
伊勢谷友介
bayern vs vfb stuttgart
chelsea vs man united
唐田えりか
102回目のプロポーズ
デゼルビ
アトレティコ 対 ソシエダ
チェルシー 対 マンu
スパーズ
清春
ディエゴ・ゴメス
ps5
ハイウェイ の 堕 天使 興行 収入
カブス 対 メッツ
dazn
サッスオーロ 対 コモ
杉咲花
町田 対 アル・イテハド
家計
週末旅の極意
北斗の拳
qvc
小芝風花
中井亜美
afc u20女子アジアカップ
ネオジオ
uefaヨーロッパリーグ
加藤史帆
志田未来
伊藤英明
島田麻央
al-nassr vs al-ettifaq
arsenal
レアル・マドリード
バイエルン
abema
real madrid
lucknow super giants vs royal challengers bengaluru standings
bayern vs real madrid
給付
wowow
小泉進次郎
政権
ミキティ
ソニック
今日のドジャースの結果
新名神高速道路
わたせせいぞう
ピーチ航空
山本由伸
アレックス・ベシア
リバプール
champions league
エルニーニョ
アトレティコ 対 バルセロナ
オープンワールド
atlético madrid vs barcelona
松田好花
リコール
man united vs leeds
白鵬翔
日本アカデミー賞 最優秀助演男優賞
マンu 対 リーズ u
サンディスク 株価
らじるらじる
マクドナルド
ロシア
広島市
ゲイブル・スティーブソン
日本維新の会
新 日本 繊維
高見沢 俊彦
不登校
後期高齢者医療制度
バーミヤン
宮澤エマ
チケプラ
横綱
宮里美香
東京 天気 明日
新宿 おすすめ 居酒屋
最新のニュース 速報
ゴールド 相場 チャート
近くの静かなカフェ
地震 速報
円安 影響 生活
円安 影響 生活

67
data/keywords/kw_KR.txt Normal file
View File

@@ -0,0 +1,67 @@
삼천당 제약 간담회
김재윤
k리그1 순위
유영찬
이호연
sxmb
문재인
생산직
강훈식
cnn
리그오브레전드
박환희
박지현
카토
와우넷
지구의 날
컴프야
차지연
크리스털 팰리스 대 웨스트 햄
비상계엄
연기금
배틀그라운드
제이홉
두산로보틱스
부부
미노이 우원재
danish malewar
mi vs gt
양치 승
프리미어리그
pl
bundesliga
맨체스터 시티 fc
fotmob
윤아
김영인
манчестер сити арсенал
케이뱅크
날씨
환율
삼성전자 주가
손흥민
토트넘 경기 일정
넷플릭스
국민은행
네이버웹툰
로또 당첨번호
쿠팡
KBO 리그
프로야구 순위
아이폰 15
챗gpt
인스타그램
유튜브 밴스드
이강인
김민재
LCK 일정
T1
페이커
무빙
카카오톡 PC버전
당근마켓
배달의민족
올리브영
메이플스토리

106
data/keywords/kw_NL.txt Normal file
View File

@@ -0,0 +1,106 @@
hoofddorp
kaja kallas
politiek
stroomstoring amersfoort
solvinity digid
wout weghorst
jamie kames
bitvavo
box 3
ronde van de alpen
matthias uhl
taken film
robot
girona - real betis
real madryt deportivo alaves
tbilisi
southampton - bristol city
vittoria guazzini
oppo find x9 ultra
real madrid - alavés
الريال ضد ألافيس
lecce - fiorentina
pogoda jutro
vierhouten
weather tomorrow
over mijn lijk 2026 overleden
crystal palace - west ham
f-16 fighting falcon
klagenfurt
italië
ruud gullit
perfil falso
psg - lyon
juventus - bologna
troy parrott
az - nec opstellingen
caroline tensen
asielbeleid
philippe sandler
keerbergen
peer koopmeiners
nederlands elftal
pogoń szczecin lech poznań
stand premier league
bulgarije
chelsea - man utd
atlético madrid - real sociedad
xavi simons
ayase ueda
roma - atalanta
rtv noord
paraguay
sergio herman
fed
keuken kampioen
legia warszawa zagłębie lubin
ripple
voorzitter fed
bahamas
overtreding
almere city
real betis
sean connery
l1 nieuws
ronaldinho
demi de boer
bondgenoten
frank masmeijer
real betis - braga
ethereum
aston villa - bologna
manuel neuer
neuer
olise
mbappe
sporting
live tv
bayern munchen
arda güler
ziggo
arda guler
netflix
frenkie de jong
kanye west
vandaag inside
at5
veroordeling
verenigde staten
alec baldwin
anna paulowna
şampiyonlar ligi
NOS Nieuws
Buienradar
Rijksoverheid
Albert Heijn
Funda
Marktplaats
KLM
Ziggo
ING Bank
Eredivisie
Amsterdam Weer
Bol.com
Treinkaartjes NS
PostNL
Pathé

View File

@@ -1,3 +1,125 @@
rr vs lsg
primary school
alexandra eala
tan su shan
sundaresh menon
moulin rouge musical singapore
south korea
step
gamba osaka vs avispa fukuoka
honor 600 pro
china shipyards oil tanker orders
coe
lebron james
real madrid vs alavés
brighton vs chelsea
nitish rana
earth day
michael movie
kevin warsh
srh vs dc
chinese aircraft carrier liaoning
andie chen
jesseca liu wins best actress
crystal palace vs west ham
grok
gemini
claude ai
gpt
ai
is chatgpt down
strait of hormuz news
danish malewar
mi vs gt
psg vs lyon
sporting vs benfica
bayern munich
pl
bangkok weather
starhub
廖子妤
曼城 - 阿森纳
bayern vs vfb stuttgart
英超
chelsea vs man united
perfect crown
ayush mhatre
sarfaraz khan
napoli vs lazio
tottenham vs brighton
abhishek sharma
tinie tempah
wrexham vs stoke city
sassuolo vs como
the straits times
india women vs south africa women
beef season 2
loyang valley
world cup 2026
afc champions league
hormuz
malacca strait
kkr vs gt
aston villa vs bologna
mumbai indians vs punjab kings standings
al sadd vs vissel kobe
amd share price
opus 4.7
pete hegseth
naman dhir
yen singapore dollar
mayank rawat
dji pocket 4
real madrid
al-nassr vs al-ettifaq
bayern vs real madrid
arsenal vs sporting
lucknow super giants vs royal challengers bengaluru standings
is claude down
claude
allbirds
red sea
rcb vs lsg
retirement
asia flights delays cancellations
suns vs trail blazers
johnny somali
bam adebayo
zhang linghe pursuit of jade
roman gofman
cruz azul vs lafc
ocbc
santos vs recoleta
atlético madrid vs barcelona
ipl schedule
liverpool vs psg
iran blockade strait of hormuz
kartik tyagi
carlos alcaraz
propertylimbrothers
byeon woo-seok
mahathir mohamad
csk vs kkr
man united vs leeds
cbse class 10 result 2026 date
euphoria season 3
srh vs rr
tamil new year 2026
low de wei
pope
flexar
microsoft outlook
new rolex 2026
medical classification
blasphemy law
big bang coachella 2026
小贩
malaysia fuel price crisis
sbti personality test
cancer survivor
tim cook
spurs vs nuggets
asia flights cancelled delayed
singapore weather forecast
mrt map singapore
straitstimes breaking news

85
data/keywords/kw_TW.txt Normal file
View File

@@ -0,0 +1,85 @@
黃 甘霖
劉家翔
王耿豪
王勝偉
009816
thời tiết ngày mai
明天的天氣
總部
美光科技
cpbl
中華職棒
中職
黃甘霖
西甲
軍 公教
6147
earth day
陳哲遠
台鐵
斯普拉遁 塗擊隊
麥可傑克森
神將彩券行
米可白
洪敬堯
華邦電子
柔美的細胞小將 3
底特律老虎
三 商 美邦
川 普
英雄聯盟
聯電adr
rklb
amd stock
宋仲基
兵工廠
德甲
塞爾提克 對 76人
justin bieber 演唱會
拜仁慕尼黑
何潤東
廖子妤
英超
許凱
tottenham vs brighton
長野縣
交通安全
朋友收集夢想生活
麥克傑克森
王濛
騎士 對 暴龍
熱刺 對 布萊頓
iem rio 2026
garret anderson
墓乃伊
曹格
claude design
柯文哲
金剛
荷 姆 茲 海峽
東北 季風
斯圖加特公開賽
歐聯
菡生婦幼診所
台鐵訂票
飛機
東光路
货币
amd
航空母艦
axti
Yahoo奇摩
天氣
蝦皮購物
PChome
Momo購物網
Mobile01
Dcard
巴哈姆特
中時電子報
聯合新聞網
台灣高鐵
台鐵時刻表
中華電信
統一發票
勞動部

View File

@@ -1,3 +1,124 @@
christopher trybus
lsg vs rr
pension
hebden bridge
sandra bullock practical magic
rolls-royce share price drop
invincible season 5
josé mourinho
chris wakelin
jimmy bullard adam thomas
aer lingus flight cancellations
sam west
oxford united
liam delap
wba
реал мадрид алавес
coppa italia
girona vs real betis
marcus rashford
الريال ضد ألافيس
supreme leader of iran
oscar isaac
xrp ledger
believe me itv
pablo
is tane leaving home and away
julie andrews
danny boyle
nina eastenders
john stones
amazon vega os fire tv
porto vs tondela
santos vs fluminense
martin brundle lost f1 seat
keegan bradley
david attenborough
antoni kowalski
kezia dugdale
car
beef netflix
juventus vs bologna
losc vs nice
david szalay
the killer
joe cole
lille fc
simon cowell
pl
frank lampard everton
nottingham forest fixtures
everton manager
dragons vs bulls
suede
lahore
wrestlemania 2026
giants vs rhinos
glenrothan
york knights vs leopards
tim sherwood
redditch
ccfc
europa conference league
bromley fc
paul merton
chris wood
istanbul
turkey
lucy watson
thiago silva
bednarek
jan bednarek
vincent kompany
mbappe
luis suarez sporting
madrid fc
andriy lunin
what did bec say to rachel mafs
yalla kora
geovany quenda
sporting cp
pavlovic
talktalk
arne slot drops mohamed salah
suns vs trail blazers
italian
used cars
mlb
roman
johnny somali
windows update
davion mitchell
hbo max
bolton wanderers
barca vs atletico
kemi badenoch
warren zaïre-emery
barca
samuel west
barcelona fc
lamine yamal
hbomax
noah okafor
casemiro
talksport
lazio
leeds united fixtures
bruno fernandes
afc champions league
meteor
carlos queiroz
travel warning
tori amos
cloud
reading
rolls-royce smr
istanbul airport
a27
bridget phillipson
tottenham standings
may bank holiday 2026
toto wolff
london weather today
bbc news latest
premier league fixtures

View File

@@ -1,3 +1,121 @@
cleveland browns
nintendo switch gamecube games
lsg vs rr
spirit
atlanta fire
deshaun watson
good morning america
pittsburgh
strands answers
scientist
mark cuban pharmacy
inter milan
lens vs toulouse
david james
andy weir
noah kahan tiny desk concert
jennifer garner 54th birthday photos
troy baker
real madrid - alavés
girona - real betis
girona vs real betis
arc raiders
schd etf dividend yield
deportación
lecce - fiorentina
valley forge high school
betty yee
seth trimble
bill belichick
winter storm
jim parsons
kings vs avalanche
suns vs thunder
wolf
santos - fluminense
mets - cubs
alexander manninger
santos vs fluminense
disclosure day
tobias myers
vladimir putin
knicks game
ben rice
prem
timberwolves vs nuggets
cody bellinger
nik khamenia
real sociedad
nurburgring crash
atlético madrid - real sociedad
ruke orhorhoro
radar
the weather channel
kttc
luke gulbranson
kttc weather
comcast data breach settlement
tornado watch
moisés ballesteros
mets game today
giancarlo stanton
real betis
prosecution of daniel duggan
liv morgan
mikey williams
indiana fever sophie cunningham baptism
gregory donnell morgan jr
why are the sirens going off
leylah fernandez
strasbourg vs mainz
michael olise
ريال مدريد
dazn
paramount
univision
jude bellingham
sam antonacci
real madrid
bayern
arda güler
los angeles dodgers
vandenberg launch schedule
ryan dunn
alex vesia
ken jennings
ucla baseball
padres standings
mets vs dodgers match player stats
bo bichette
jorge polanco
psg
barca
vix
fcb
barcelona schedule
tarjeta roja
a knight of the seven kingdoms season 2
charlotte flair
usa network
natalie sago
carlos queiroz
carlos batista
katie boulter
levante - getafe
levante vs getafe
mcilroy green jacket presentation
man united vs leeds
7-eleven closing locations
cloud
sports
sony playstation
alaska airline
toronto
sydney
paris
tokyo
delhi
sykkuno drama
Los Angeles weather today
S&P 500 stock chart
local coffee shops near me
@@ -7,3 +125,6 @@ AI startups in Silicon ValleySan Jose weather this weekend
Silicon Valley tech news
best tacos in San Jose
Apple park visitor center hours
Seattle Weather
Las Vegas strip
Charlotte Hornets

106
data/keywords/kw_VN.txt Normal file
View File

@@ -0,0 +1,106 @@
trực tiếp bóng đá hôm nay
vtv3
vtv3 trực tiếp
tv
vtv
vtv6
360
lê khánh
ô tô
lê phương
trực tiếp bóng đá u17 hôm nay
inter milan
chelsea
girona đấu với betis
real madrid đấu với alavés
brighton vs chelsea
brighton đấu với chelsea
ath. bilbao đấu với osasuna
pep guardiola
zelvia đấu với shabab al-ahli
cầu thủ
lecce vs fiorentina
fiorentina
crystal palace đấu với west ham
afc champions league
eduardo camavinga
vissel kobe
gemi
idp
bảo hiểm y tế
crystal palace vs west ham
sporting lisbon
psg vs lyon
ca sĩ
juventus đấu với bologna
gladbach đấu với mainz
bayern munich
twitch
psg đấu với lyon
juventus
ligue 1
trận đấu ngoại hạng anh
chelsea đấu với man utd
atlético madrid đấu với real sociedad
roma đấu với atalanta
epl
iem rio 2026
tot
tập đoàn gelex
napoli
đường ray
inter
inter đấu với cagliari
sassuolo vs como
david alaba
claude design
fenerbahçe đấu với rizespor
como
como vs
thẻ đỏ
al ahli
porto vs
crystal palace
porto
uefa europa conference
betis đấu với braga
real betis vs braga
aston villa đấu với bologna
fiorentina đấu với crystal palace
c2
cup c2
thể thao
arda güler
aleksandar pavlović
ars
90
real
real madrid
xoi
luong sơn
fpt
phan văn giang
nhà ở xã hội
club america
giàu
đỗ mỹ linh
sun group
hưng yên
nvl
américa đấu với nashville
neymar
VnExpress
Zing News
Thời tiết Hà Nội
Giá vàng hôm nay
Shopee VN
Tiki
Vietjet Air
Vietnam Airlines
Bóng đá trực tuyến
Lịch thi đấu Euro
Xổ số miền Bắc
Grab Vietnam
VTV Go
Học tiếng Anh
Du lịch Đà Lạt

View File

@@ -1,105 +1,239 @@
{
"version": "3.1.0",
"updated_at": "2026-04-11",
"countries": [
"version": "3.5.2",
"updated_at": "2026-04-19",
"continents": [
{
"id": "US",
"name": "United States (美国)",
"keyword_file": "kw_US.txt",
"states": [
"id": "ASIA",
"name": "亚太战区 (Asia-Pacific)",
"countries": [
{
"id": "JP",
"name": "Japan (日本)",
"keyword_file": "kw_JP.txt",
"states": [
{ "id": "Default", "name": "Default State", "cities": [ { "id": "Tokyo", "name": "Tokyo (东京)" } ] }
]
},
{
"id": "SG",
"name": "Singapore (新加坡)",
"keyword_file": "kw_SG.txt",
"states": [
{ "id": "Default", "name": "Default State", "cities": [ { "id": "Singapore", "name": "Singapore (新加坡)" } ] }
]
},
{
"id": "KR",
"name": "South Korea (韩国)",
"keyword_file": "kw_KR.txt",
"states": [
{ "id": "Default", "name": "Default State", "cities": [ { "id": "Seoul", "name": "Seoul (首尔)" } ] }
]
},
{
"id": "HK",
"name": "Hong Kong (香港)",
"keyword_file": "kw_HK.txt",
"states": [
{ "id": "Default", "name": "Default State", "cities": [ { "id": "HongKong", "name": "Hong Kong (香港)" } ] }
]
},
{
"id": "VN",
"name": "Vietnam (越南)",
"keyword_file": "kw_VN.txt",
"states": [
{ "id": "Default", "name": "Default State", "cities": [ { "id": "Hanoi", "name": "Hanoi (河内)" } ] }
]
},
{
"id": "TW",
"name": "Taiwan (台湾)",
"keyword_file": "kw_TW.txt",
"states": [
{ "id": "Default", "name": "Default State", "cities": [ { "id": "Taipei", "name": "Taipei (台北)" } ] }
]
}
]
},
{
"id": "EUROPE",
"name": "欧洲战区 (Europe)",
"countries": [
{
"id": "UK",
"name": "United Kingdom (英国)",
"keyword_file": "kw_UK.txt",
"states": [
{
"id": "Default",
"name": "Default State",
"cities": [
{ "id": "London", "name": "London (伦敦)" },
{ "id": "Coventry", "name": "Coventry (考文垂)" }
]
}
]
},
{
"id": "DE",
"name": "Germany (德国)",
"keyword_file": "kw_DE.txt",
"states": [
{ "id": "Default", "name": "Default State", "cities": [ { "id": "Frankfurt", "name": "Frankfurt (法兰克福)" } ] }
]
},
{
"id": "FR",
"name": "France (法国)",
"keyword_file": "kw_FR.txt",
"states": [
{ "id": "Default", "name": "Default State", "cities": [ { "id": "Paris", "name": "Paris (巴黎)" } ] }
]
},
{
"id": "NL",
"name": "Netherlands (荷兰)",
"keyword_file": "kw_NL.txt",
"states": [
{ "id": "Default", "name": "Default State", "cities": [ { "id": "Amsterdam", "name": "Amsterdam (阿姆斯特丹)" } ] }
]
},
{
"id": "ES",
"name": "Spain (西班牙)",
"keyword_file": "kw_ES.txt",
"states": [
{ "id": "Default", "name": "Default State", "cities": [ { "id": "Madrid", "name": "Madrid (马德里)" } ] }
]
}
]
},
{
"id": "AMERICAS",
"name": "美洲战区 (Americas)",
"countries": [
{
"id": "US",
"name": "United States (美国)",
"keyword_file": "kw_US.txt",
"states": [
{
"id": "CA",
"name": "California (加州)",
"cities": [
{ "id": "Los_Angeles", "name": "Los Angeles (洛杉矶)" },
{ "id": "San_Jose", "name": "San Jose (圣何塞)" }
]
},
{
"id": "IL",
"name": "Illinois (伊利诺伊州)",
"cities": [
{ "id": "Warrenville", "name": "Warrenville (沃伦维尔)" }
]
},
{
"id": "NC",
"name": "North Carolina (北卡罗来纳州)",
"cities": [
{ "id": "Charlotte", "name": "Charlotte (夏洛特)" }
]
},
{
"id": "NV",
"name": "Nevada (内华达州)",
"cities": [
{ "id": "Las_Vegas", "name": "Las Vegas (拉斯维加斯)" }
]
},
{
"id": "OR",
"name": "Oregon (俄勒冈州)",
"cities": [
{ "id": "Bend", "name": "Bend (本德)" }
]
},
{
"id": "UT",
"name": "Utah (犹他州)",
"cities": [
{ "id": "Salt_Lake_City", "name": "Salt Lake City (盐湖城)" }
]
},
{
"id": "WA",
"name": "Washington (华盛顿州)",
"cities": [
{ "id": "Seattle", "name": "Seattle (西雅图)" }
]
}
]
},
{
"id": "CA",
"name": "California (加)",
"cities": [
{ "id": "Los_Angeles", "name": "Los Angeles (洛杉矶)" },
{ "id": "San_Jose", "name": "San Jose (圣何塞)" }
"name": "Canada (加拿大)",
"keyword_file": "kw_CA.txt",
"states": [
{
"id": "Default",
"name": "Default State",
"cities": [
{ "id": "Toronto", "name": "Toronto (多伦多)" },
{ "id": "Montreal", "name": "Montreal (蒙特利尔)" }
]
}
]
}
]
},
{
"id": "JP",
"name": "Japan (日本)",
"keyword_file": "kw_JP.txt",
"states": [
"id": "OCEANIA",
"name": "大洋洲战区 (Oceania)",
"countries": [
{
"id": "Default",
"name": "Default State",
"cities": [
{ "id": "Tokyo", "name": "Tokyo (东京)" }
]
}
]
},
{
"id": "UK",
"name": "United Kingdom (英国)",
"keyword_file": "kw_UK.txt",
"states": [
{
"id": "Default",
"name": "Default State",
"cities": [
{ "id": "London", "name": "London (伦敦)" }
]
}
]
},
{
"id": "DE",
"name": "Germany (德国)",
"keyword_file": "kw_DE.txt",
"states": [
{
"id": "Default",
"name": "Default State",
"cities": [
{ "id": "Frankfurt", "name": "Frankfurt (法兰克福)" }
]
}
]
},
{
"id": "FR",
"name": "France (法国)",
"keyword_file": "kw_FR.txt",
"states": [
{
"id": "Default",
"name": "Default State",
"cities": [
{ "id": "Paris", "name": "Paris (巴黎)" }
]
}
]
},
{
"id": "SG",
"name": "Singapore (新加坡)",
"keyword_file": "kw_SG.txt",
"states": [
{
"id": "Default",
"name": "Default State",
"cities": [
{ "id": "Singapore", "name": "Singapore (新加坡)" }
]
}
]
},
{
"id": "HK",
"name": "Hong Kong (香港)",
"keyword_file": "kw_HK.txt",
"states": [
{
"id": "Default",
"name": "Default State",
"cities": [
{ "id": "HongKong", "name": "Hong Kong (香港)" }
"id": "AU",
"name": "Australia (澳大利亚)",
"keyword_file": "kw_AU.txt",
"states": [
{
"id": "NSW",
"name": "New South Wales (新南威尔士州)",
"cities": [
{ "id": "Sydney", "name": "Sydney (悉尼)" }
]
},
{
"id": "VIC",
"name": "Victoria (维多利亚州)",
"cities": [
{ "id": "Melbourne", "name": "Melbourne (墨尔本)" }
]
},
{
"id": "QLD",
"name": "Queensland (昆士兰州)",
"cities": [
{ "id": "Brisbane", "name": "Brisbane (布里斯班)" }
]
},
{
"id": "WA",
"name": "Western Australia (西澳大利亚州)",
"cities": [
{ "id": "Perth", "name": "Perth (珀斯)" }
]
},
{
"id": "SA",
"name": "South Australia (南澳大利亚州)",
"cities": [
{ "id": "Adelaide", "name": "Adelaide (阿德莱德)" }
]
}
]
}
]
}
]
}
}

View File

@@ -0,0 +1,50 @@
{
"region_name": "Australia - Sydney",
"google_module": {
"base_lat": -33.8697,
"base_lon": 151.2085,
"lang_params": "hl=en-AU&gl=AU",
"valid_url_suffix": "com.au"
},
"trust_module": {
"white_urls": [
"https://www.abc.net.au/news/2026-04-22/cdu-new-rental-darwin-casuarina-university-student-accommodation/106593324",
"https://www.abc.net.au/news/2026-04-22/queensland-funding-ampol-refinery-renewable-diesel/106591516",
"https://www.abc.net.au/news/2026-04-22/offspring-actor-alicia-gardiner-assault-charges-dropped/106593712",
"https://www.amazon.com.au/",
"https://www.abc.net.au/news/2026-04-22/bombing-of-darwin-war-veteran-largest-foreign-attack-australia/106583230",
"https://www.abc.net.au/news/2026-04-22/netball-australia-ceo-stacey-west-steps-down/106593400",
"https://www.bom.gov.au/",
"https://www.abc.net.au/news/2026-04-22/ndis-overhaul-eligibility-rule-changes-explained/106593778",
"https://www.abc.net.au/news/2026-04-22/jack-avenell-kimberley-drowning-family-tribute/106585272",
"https://www.bunnings.com.au/",
"https://www.commbank.com.au/",
"https://www.abc.net.au/news/2026-04-22/collie-job-cuts-coal-mine-merger-push/106591996",
"https://www.realestate.com.au/",
"https://www.woolworths.com.au/",
"https://www.coles.com.au/",
"https://www.abc.net.au/news/2026-04-22/vuda-point-waste-to-energy-plan-sparks-backlash-in-fiji/106557824",
"https://www.abc.net.au/news/2026-04-22/david-pocock-slams-vested-interests-in-gambling-reform-proposal/106594108",
"https://www.seek.com.au/",
"https://www.abc.net.au/news/2026-04-22/school-infrastructure-anthony-manning-found-corrupt-icac/106594236",
"https://www.abc.net.au/news/2026-04-22/salmon-tasmania-campaign-to-get-truth-out-worker-stories/106592266",
"https://www.abc.net.au/news/2026-04-22/private-health-for-over-65s-to-cost-hundreds-more/106594174",
"https://my.gov.au/",
"https://www.ato.gov.au/",
"https://www.abc.net.au/news/2026-04-22/raymond-wheatley-inquest-hears-of-heavy-public-guardian-caseload/106592890",
"https://www.abc.net.au/news/2026-04-22/dorrigo-anzac-war-memorial-repaired/106589354"
],
"static_urls": [
"https://my.gov.au/",
"https://www.ato.gov.au/",
"https://www.bom.gov.au/",
"https://www.commbank.com.au/",
"https://www.seek.com.au/",
"https://www.realestate.com.au/",
"https://www.woolworths.com.au/",
"https://www.coles.com.au/",
"https://www.amazon.com.au/",
"https://www.bunnings.com.au/"
]
}
}

View File

@@ -0,0 +1,50 @@
{
"region_name": "Australia - Brisbane",
"google_module": {
"base_lat": -27.4697,
"base_lon": 153.0252,
"lang_params": "hl=en-AU&gl=AU",
"valid_url_suffix": "com.au"
},
"trust_module": {
"white_urls": [
"https://www.abc.net.au/news/2026-04-22/cdu-new-rental-darwin-casuarina-university-student-accommodation/106593324",
"https://www.bom.gov.au/",
"https://www.abc.net.au/news/2026-04-22/jack-avenell-kimberley-drowning-family-tribute/106585272",
"https://www.abc.net.au/news/2026-04-22/netball-australia-ceo-stacey-west-steps-down/106593400",
"https://www.commbank.com.au/",
"https://www.coles.com.au/",
"https://www.abc.net.au/news/2026-04-22/salmon-tasmania-campaign-to-get-truth-out-worker-stories/106592266",
"https://www.abc.net.au/news/2026-04-22/vuda-point-waste-to-energy-plan-sparks-backlash-in-fiji/106557824",
"https://www.amazon.com.au/",
"https://www.woolworths.com.au/",
"https://www.ato.gov.au/",
"https://www.abc.net.au/news/2026-04-22/collie-job-cuts-coal-mine-merger-push/106591996",
"https://www.bunnings.com.au/",
"https://www.abc.net.au/news/2026-04-22/school-infrastructure-anthony-manning-found-corrupt-icac/106594236",
"https://www.abc.net.au/news/2026-04-22/offspring-actor-alicia-gardiner-assault-charges-dropped/106593712",
"https://www.seek.com.au/",
"https://www.abc.net.au/news/2026-04-22/private-health-for-over-65s-to-cost-hundreds-more/106594174",
"https://my.gov.au/",
"https://www.abc.net.au/news/2026-04-22/raymond-wheatley-inquest-hears-of-heavy-public-guardian-caseload/106592890",
"https://www.abc.net.au/news/2026-04-22/queensland-funding-ampol-refinery-renewable-diesel/106591516",
"https://www.abc.net.au/news/2026-04-22/bombing-of-darwin-war-veteran-largest-foreign-attack-australia/106583230",
"https://www.abc.net.au/news/2026-04-22/dorrigo-anzac-war-memorial-repaired/106589354",
"https://www.realestate.com.au/",
"https://www.abc.net.au/news/2026-04-22/ndis-overhaul-eligibility-rule-changes-explained/106593778",
"https://www.abc.net.au/news/2026-04-22/david-pocock-slams-vested-interests-in-gambling-reform-proposal/106594108"
],
"static_urls": [
"https://my.gov.au/",
"https://www.ato.gov.au/",
"https://www.bom.gov.au/",
"https://www.commbank.com.au/",
"https://www.seek.com.au/",
"https://www.realestate.com.au/",
"https://www.woolworths.com.au/",
"https://www.coles.com.au/",
"https://www.amazon.com.au/",
"https://www.bunnings.com.au/"
]
}
}

View File

@@ -0,0 +1,50 @@
{
"region_name": "Australia - Adelaide",
"google_module": {
"base_lat": -34.9227,
"base_lon": 138.6016,
"lang_params": "hl=en-AU&gl=AU",
"valid_url_suffix": "com.au"
},
"trust_module": {
"white_urls": [
"https://www.realestate.com.au/",
"https://www.abc.net.au/news/2026-04-22/cdu-new-rental-darwin-casuarina-university-student-accommodation/106593324",
"https://www.abc.net.au/news/2026-04-22/private-health-for-over-65s-to-cost-hundreds-more/106594174",
"https://www.abc.net.au/news/2026-04-22/collie-job-cuts-coal-mine-merger-push/106591996",
"https://www.abc.net.au/news/2026-04-22/queensland-funding-ampol-refinery-renewable-diesel/106591516",
"https://www.coles.com.au/",
"https://www.abc.net.au/news/2026-04-22/salmon-tasmania-campaign-to-get-truth-out-worker-stories/106592266",
"https://www.abc.net.au/news/2026-04-22/david-pocock-slams-vested-interests-in-gambling-reform-proposal/106594108",
"https://www.abc.net.au/news/2026-04-22/vuda-point-waste-to-energy-plan-sparks-backlash-in-fiji/106557824",
"https://www.bom.gov.au/",
"https://www.abc.net.au/news/2026-04-22/ndis-overhaul-eligibility-rule-changes-explained/106593778",
"https://www.abc.net.au/news/2026-04-22/dorrigo-anzac-war-memorial-repaired/106589354",
"https://www.abc.net.au/news/2026-04-22/bombing-of-darwin-war-veteran-largest-foreign-attack-australia/106583230",
"https://www.commbank.com.au/",
"https://www.seek.com.au/",
"https://www.bunnings.com.au/",
"https://www.abc.net.au/news/2026-04-22/netball-australia-ceo-stacey-west-steps-down/106593400",
"https://www.amazon.com.au/",
"https://www.ato.gov.au/",
"https://my.gov.au/",
"https://www.abc.net.au/news/2026-04-22/raymond-wheatley-inquest-hears-of-heavy-public-guardian-caseload/106592890",
"https://www.abc.net.au/news/2026-04-22/jack-avenell-kimberley-drowning-family-tribute/106585272",
"https://www.abc.net.au/news/2026-04-22/offspring-actor-alicia-gardiner-assault-charges-dropped/106593712",
"https://www.abc.net.au/news/2026-04-22/school-infrastructure-anthony-manning-found-corrupt-icac/106594236",
"https://www.woolworths.com.au/"
],
"static_urls": [
"https://my.gov.au/",
"https://www.ato.gov.au/",
"https://www.bom.gov.au/",
"https://www.commbank.com.au/",
"https://www.seek.com.au/",
"https://www.realestate.com.au/",
"https://www.woolworths.com.au/",
"https://www.coles.com.au/",
"https://www.amazon.com.au/",
"https://www.bunnings.com.au/"
]
}
}

View File

@@ -0,0 +1,50 @@
{
"region_name": "Australia - Melbourne",
"google_module": {
"base_lat": -37.8106,
"base_lon": 144.9624,
"lang_params": "hl=en-AU&gl=AU",
"valid_url_suffix": "com.au"
},
"trust_module": {
"white_urls": [
"https://www.bunnings.com.au/",
"https://www.amazon.com.au/",
"https://www.abc.net.au/news/2026-04-22/vuda-point-waste-to-energy-plan-sparks-backlash-in-fiji/106557824",
"https://www.abc.net.au/news/2026-04-22/jack-avenell-kimberley-drowning-family-tribute/106585272",
"https://www.realestate.com.au/",
"https://www.ato.gov.au/",
"https://www.abc.net.au/news/2026-04-22/offspring-actor-alicia-gardiner-assault-charges-dropped/106593712",
"https://www.abc.net.au/news/2026-04-22/netball-australia-ceo-stacey-west-steps-down/106593400",
"https://www.coles.com.au/",
"https://www.abc.net.au/news/2026-04-22/bombing-of-darwin-war-veteran-largest-foreign-attack-australia/106583230",
"https://my.gov.au/",
"https://www.abc.net.au/news/2026-04-22/dorrigo-anzac-war-memorial-repaired/106589354",
"https://www.abc.net.au/news/2026-04-22/school-infrastructure-anthony-manning-found-corrupt-icac/106594236",
"https://www.commbank.com.au/",
"https://www.abc.net.au/news/2026-04-22/salmon-tasmania-campaign-to-get-truth-out-worker-stories/106592266",
"https://www.bom.gov.au/",
"https://www.seek.com.au/",
"https://www.abc.net.au/news/2026-04-22/queensland-funding-ampol-refinery-renewable-diesel/106591516",
"https://www.woolworths.com.au/",
"https://www.abc.net.au/news/2026-04-22/raymond-wheatley-inquest-hears-of-heavy-public-guardian-caseload/106592890",
"https://www.abc.net.au/news/2026-04-22/collie-job-cuts-coal-mine-merger-push/106591996",
"https://www.abc.net.au/news/2026-04-22/ndis-overhaul-eligibility-rule-changes-explained/106593778",
"https://www.abc.net.au/news/2026-04-22/cdu-new-rental-darwin-casuarina-university-student-accommodation/106593324",
"https://www.abc.net.au/news/2026-04-22/private-health-for-over-65s-to-cost-hundreds-more/106594174",
"https://www.abc.net.au/news/2026-04-22/david-pocock-slams-vested-interests-in-gambling-reform-proposal/106594108"
],
"static_urls": [
"https://my.gov.au/",
"https://www.ato.gov.au/",
"https://www.bom.gov.au/",
"https://www.commbank.com.au/",
"https://www.seek.com.au/",
"https://www.realestate.com.au/",
"https://www.woolworths.com.au/",
"https://www.coles.com.au/",
"https://www.amazon.com.au/",
"https://www.bunnings.com.au/"
]
}
}

View File

@@ -0,0 +1,50 @@
{
"region_name": "Australia - Perth",
"google_module": {
"base_lat": -31.9545,
"base_lon": 115.8582,
"lang_params": "hl=en-AU&gl=AU",
"valid_url_suffix": "com.au"
},
"trust_module": {
"white_urls": [
"https://www.ato.gov.au/",
"https://www.abc.net.au/news/2026-04-22/vuda-point-waste-to-energy-plan-sparks-backlash-in-fiji/106557824",
"https://www.abc.net.au/news/2026-04-22/private-health-for-over-65s-to-cost-hundreds-more/106594174",
"https://www.abc.net.au/news/2026-04-22/school-infrastructure-anthony-manning-found-corrupt-icac/106594236",
"https://www.seek.com.au/",
"https://www.commbank.com.au/",
"https://www.abc.net.au/news/2026-04-22/bombing-of-darwin-war-veteran-largest-foreign-attack-australia/106583230",
"https://www.abc.net.au/news/2026-04-22/collie-job-cuts-coal-mine-merger-push/106591996",
"https://www.amazon.com.au/",
"https://www.bunnings.com.au/",
"https://www.abc.net.au/news/2026-04-22/cdu-new-rental-darwin-casuarina-university-student-accommodation/106593324",
"https://www.abc.net.au/news/2026-04-22/ndis-overhaul-eligibility-rule-changes-explained/106593778",
"https://www.abc.net.au/news/2026-04-22/david-pocock-slams-vested-interests-in-gambling-reform-proposal/106594108",
"https://www.abc.net.au/news/2026-04-22/offspring-actor-alicia-gardiner-assault-charges-dropped/106593712",
"https://www.realestate.com.au/",
"https://www.abc.net.au/news/2026-04-22/raymond-wheatley-inquest-hears-of-heavy-public-guardian-caseload/106592890",
"https://www.bom.gov.au/",
"https://www.abc.net.au/news/2026-04-22/salmon-tasmania-campaign-to-get-truth-out-worker-stories/106592266",
"https://my.gov.au/",
"https://www.abc.net.au/news/2026-04-22/jack-avenell-kimberley-drowning-family-tribute/106585272",
"https://www.abc.net.au/news/2026-04-22/dorrigo-anzac-war-memorial-repaired/106589354",
"https://www.abc.net.au/news/2026-04-22/netball-australia-ceo-stacey-west-steps-down/106593400",
"https://www.abc.net.au/news/2026-04-22/queensland-funding-ampol-refinery-renewable-diesel/106591516",
"https://www.woolworths.com.au/",
"https://www.coles.com.au/"
],
"static_urls": [
"https://my.gov.au/",
"https://www.ato.gov.au/",
"https://www.bom.gov.au/",
"https://www.commbank.com.au/",
"https://www.seek.com.au/",
"https://www.realestate.com.au/",
"https://www.woolworths.com.au/",
"https://www.coles.com.au/",
"https://www.amazon.com.au/",
"https://www.bunnings.com.au/"
]
}
}

View File

@@ -0,0 +1,46 @@
{
"region_name": "Canada - Montreal",
"google_module": {
"base_lat": 45.5017,
"base_lon": -73.5673,
"lang_params": "hl=en&gl=CA",
"valid_url_suffix": "ca"
},
"trust_module": {
"white_urls": [
"https://www.cbc.ca/news/canada/premiers-private-flights-commercial-9.7171284?cmp=rss",
"https://www.amazon.ca/",
"https://www.cbc.ca/news/canada/ottawa/kingston-penitentiary-federal-land-bank-could-turn-historic-prison-into-housing-9.7162985?cmp=rss",
"https://www.cbc.ca/news/world/livestory/iran-blockade-us-israel-lebanon-strait-hormuz-9.7172875?cmp=rss",
"https://www.utoronto.ca/",
"https://www.cbc.ca/news/world/trump-iran-regime-change-new-leaders-irgc-9.7170933?cmp=rss",
"https://www.cbc.ca/player/play/9.7172163?cmp=rss",
"https://www.rbcroyalbank.com/",
"https://www.cbc.ca/radio/whatonearth/environment-protection-movement-social-justice-india-canada-united-states-9.7166739?cmp=rss",
"https://www.canadapost-postescanada.ca/",
"https://www.td.com/",
"https://www.cbc.ca/news/politics/two-blocks-from-the-white-house-9.7042430?cmp=rss",
"https://www.cbc.ca/news/canada/calgary/slopaganda-youtube-alberta-separatism-9.7171993?cmp=rss",
"https://www.cbc.ca/news/indigenous/john-amagoalik-rcmp-surveillance-9.7171894?cmp=rss",
"https://www.canada.ca/en.html",
"https://www.theweathernetwork.com/ca",
"https://www.cra-arc.gc.ca/",
"https://www.cbc.ca/news/business/instagram-plus-rollout-9.7172486?cmp=rss",
"https://www.cbc.ca/news/canada/ai-baby-slop-9.7166873?cmp=rss",
"https://www.cbc.ca/news/politics/washington-demanding-entry-fee-from-ottawa-before-trade-talks-sources-9.7172340?cmp=rss",
"https://www.cbc.ca/news/world/eu-ukraine-loan-hungary-orban-9.7172861?cmp=rss",
"https://www.cbc.ca/news/canada/toronto/doug-ford-jet-airport-runways-9.7172500?cmp=rss",
"https://www.cbc.ca/news/business/john-ternus-apple-ceo-9.7172364?cmp=rss"
],
"static_urls": [
"https://www.canada.ca/en.html",
"https://www.cra-arc.gc.ca/",
"https://www.canadapost-postescanada.ca/",
"https://www.utoronto.ca/",
"https://www.td.com/",
"https://www.rbcroyalbank.com/",
"https://www.amazon.ca/",
"https://www.theweathernetwork.com/ca"
]
}
}

View File

@@ -0,0 +1,46 @@
{
"region_name": "Canada - Toronto",
"google_module": {
"base_lat": 43.6532,
"base_lon": -79.3832,
"lang_params": "hl=en&gl=CA",
"valid_url_suffix": "ca"
},
"trust_module": {
"white_urls": [
"https://www.cbc.ca/news/business/john-ternus-apple-ceo-9.7172364?cmp=rss",
"https://www.rbcroyalbank.com/",
"https://www.utoronto.ca/",
"https://www.cbc.ca/news/canada/ottawa/kingston-penitentiary-federal-land-bank-could-turn-historic-prison-into-housing-9.7162985?cmp=rss",
"https://www.cbc.ca/news/canada/toronto/doug-ford-jet-airport-runways-9.7172500?cmp=rss",
"https://www.cbc.ca/news/world/trump-iran-regime-change-new-leaders-irgc-9.7170933?cmp=rss",
"https://www.cbc.ca/news/canada/ai-baby-slop-9.7166873?cmp=rss",
"https://www.cra-arc.gc.ca/",
"https://www.theweathernetwork.com/ca",
"https://www.amazon.ca/",
"https://www.cbc.ca/news/canada/premiers-private-flights-commercial-9.7171284?cmp=rss",
"https://www.cbc.ca/radio/whatonearth/environment-protection-movement-social-justice-india-canada-united-states-9.7166739?cmp=rss",
"https://www.canada.ca/en.html",
"https://www.cbc.ca/news/indigenous/john-amagoalik-rcmp-surveillance-9.7171894?cmp=rss",
"https://www.cbc.ca/news/world/livestory/iran-blockade-us-israel-lebanon-strait-hormuz-9.7172875?cmp=rss",
"https://www.cbc.ca/news/canada/calgary/slopaganda-youtube-alberta-separatism-9.7171993?cmp=rss",
"https://www.cbc.ca/news/business/instagram-plus-rollout-9.7172486?cmp=rss",
"https://www.cbc.ca/news/politics/washington-demanding-entry-fee-from-ottawa-before-trade-talks-sources-9.7172340?cmp=rss",
"https://www.cbc.ca/player/play/9.7172163?cmp=rss",
"https://www.cbc.ca/news/politics/two-blocks-from-the-white-house-9.7042430?cmp=rss",
"https://www.cbc.ca/news/world/eu-ukraine-loan-hungary-orban-9.7172861?cmp=rss",
"https://www.canadapost-postescanada.ca/",
"https://www.td.com/"
],
"static_urls": [
"https://www.canada.ca/en.html",
"https://www.cra-arc.gc.ca/",
"https://www.canadapost-postescanada.ca/",
"https://www.utoronto.ca/",
"https://www.td.com/",
"https://www.rbcroyalbank.com/",
"https://www.amazon.ca/",
"https://www.theweathernetwork.com/ca"
]
}
}

View File

@@ -8,13 +8,39 @@
},
"trust_module": {
"white_urls": [
"https://www.tagesschau.de/inland/regional/hessen/lufthansa-flugstreichungen-100.html",
"https://www.tagesschau.de/ausland/amerika/fifa-wm-usa-stimmung-100.html",
"https://www.amazon.de/",
"https://www.bundesregierung.de/",
"https://www.tagesschau.de/inland/warken-pflegereform-vorschlaege-100.html",
"https://www.tagesschau.de/wirtschaft/verbraucher/air-new-zealand-etagenbetten-100.html",
"https://www.sparkasse.de/",
"https://www.tagesschau.de/investigativ/ndr-wdr/bka-is-islamischer-staat-geheimdokumente-100.html",
"https://www.tagesschau.de/inland/regional/nordrheinwestfalen/castortransport-juelich-ahaus-100.html",
"https://www.arbeitsagentur.de/",
"https://www.tagesschau.de/wissen/forschung/hannover-messe-krebs-zelltherapie-100.html",
"https://www.tagesschau.de/ausland/europa/druschba-pipeline-ukraine-100.html",
"https://www.tagesschau.de/ausland/amerika/trump-iran-waffenruhe-ultimatum-100.html",
"https://www.tum.de/",
"https://www.bahn.de/",
"https://www.spiegel.de/",
"https://www.tagesschau.de/",
"https://de.wikipedia.org/wiki/Spezial:Zuf%C3%A4llige_Seite",
"https://www.tagesschau.de/inland/innenpolitik/warken-pflegereform-kritik-100.html",
"https://www.tagesschau.de/newsticker/liveblog-iran-mittwoch-112.html",
"https://www.tagesschau.de/wirtschaft/verbraucher/preisanstieg-strom-gas-102.html",
"https://www.ebay.de/",
"https://www.bild.de/",
"https://www.kicker.de/"
"https://www.tagesschau.de/wirtschaft/unternehmen/terminal-3-frankfurt-flughafen-100.html",
"https://www.tagesschau.de/ausland/israel-memorial-day-100.html",
"https://www.tagesschau.de/wirtschaft/verbraucher/kerosin-flugpreise-passagierrechte-pauschalreisen-100.html"
],
"static_urls": [
"https://www.bundesregierung.de/",
"https://www.arbeitsagentur.de/",
"https://www.tum.de/",
"https://www.sparkasse.de/",
"https://www.bahn.de/",
"https://www.amazon.de/",
"https://www.ebay.de/",
"https://www.spiegel.de/"
]
}
}
}

View File

@@ -0,0 +1,44 @@
{
"region_name": "Spain - Madrid",
"google_module": {
"base_lat": 40.4168,
"base_lon": -3.7038,
"lang_params": "hl=es&gl=ES",
"valid_url_suffix": "es"
},
"trust_module": {
"white_urls": [
"https://www.santander.es/",
"https://elpais.com/clima-y-medio-ambiente/2026-04-22/mas-alla-de-los-combustibles-fosiles-una-coalicion-dispuesta-a-avanzar.html",
"https://elpais.com/comunicacion/2026-04-19/marc-bassets-nuevo-subdirector-de-opinion-de-el-pais.html",
"https://elpais.com/opinion/2026-04-22/the-onion-y-el-troleo-justiciero.html",
"https://elpais.com/espana/2026-04-22/lanzarote-aparta-al-canal-de-isabel-ii-de-la-gestion-del-agua-tras-constatar-una-perturbacion-grave-estructural-y-continuada-del-sistema.html",
"https://www.zara.com/es/",
"https://administracion.gob.es/",
"https://elpais.com/espana/galicia/2026-04-22/el-pp-se-alia-con-una-transfuga-para-una-mocion-de-censura-en-lugo-tras-27-anos-de-alcaldias-socialistas.html",
"https://elpais.com/television/2026-04-22/el-podcast-que-retrata-a-una-victima-de-agresiones-sexuales-que-no-encontro-ayuda-en-el-sistema.html",
"https://elpais.com/espana/2026-04-22/la-fiscalia-pide-el-archivo-de-la-investigacion-contra-begona-gomez.html",
"https://elpais.com/economia/negocios/2026-04-18/el-enorme-poder-de-la-nueva-plutocracia-asi-condicionan-nuestra-vida-y-la-democracia-milmillonarios-como-musk-bezos-o-zuckerberg.html",
"https://elpais.com/educacion/2026-04-21/el-crea-y-el-detector-de-chorradas.html",
"https://www.elcorteingles.es/",
"https://www.renfe.com/",
"https://elpais.com/television/2026-04-22/cara-al-show-de-marc-giro-gana-por-poco-a-al-cielo-con-ellas-de-henar-alvarez-en-su-primer-duelo-mientras-telecinco-arrasa.html",
"https://elpais.com/elviajero/escapadas/espana/2026-04-22/bodegas-un-tesoro-extraterrestre-y-un-castillo-medieval-convierten-a-villena-en-una-alternativa-al-circuito-turistico-de-alicante.html",
"https://www.agenciatributaria.es/",
"https://elpais.com/internacional/2026-04-22/italia-ofrecera-un-bonus-a-los-abogados-que-faciliten-la-repatriacion-de-migrantes.html",
"https://elpais.com/sociedad/2026-04-22/ojos-que-no-ven-por-que-estos-parques-de-animales-son-vitales-contra-la-perdida-de-biodiversidad.html",
"https://elpais.com/tecnologia/2026-04-20/elon-musk-planta-a-la-justicia-francesa-que-investiga-la-manipulacion-del-algoritmo-de-x.html",
"https://elpais.com/gastronomia/el-comidista/2026-04-19/menu-semanal-de-el-comidista-20-a-26-de-abril.html",
"https://www.amazon.es/"
],
"static_urls": [
"https://administracion.gob.es/",
"https://www.agenciatributaria.es/",
"https://www.santander.es/",
"https://www.renfe.com/",
"https://www.amazon.es/",
"https://www.zara.com/es/",
"https://www.elcorteingles.es/"
]
}
}

View File

@@ -8,13 +8,37 @@
},
"trust_module": {
"white_urls": [
"https://www.lemonde.fr/",
"https://www.lefigaro.fr/",
"https://www.amazon.fr/",
"https://www.service-public.fr/",
"https://fr.wikipedia.org/wiki/Sp%C3%A9cial:Page_au_hasard",
"https://www.cdiscount.com/",
"https://www.fnac.com/"
"https://www.france24.com/fr/moyen-orient/20260422-en-direct-cessez-feu-avec-iran-prolonge-sine-die-iran-menace-guerre-moyen-orient-donald-trump-etats-unis-liban-hezbollah-ormuz-detroit-blocus",
"https://www.france24.com/fr/vid%C3%A9o/20260422-replay-emmanuel-macron-re%C3%A7oit-le-premier-ministre-libanais-nawaf-salam",
"https://www.impots.gouv.fr/",
"https://www.france24.com/fr/sports/20260422-sport-footballeuses-r%C3%A9clament-convention-collective-syndicat-le-sommer",
"https://www.france24.com/fr/vid%C3%A9o/20260422-%C3%A9tats-unis-le-directeur-du-fbi-kash-patel-dans-la-tourmente",
"https://www.france24.com/fr/%C3%A9missions/info-%C3%A9co/20260422-d%C3%A9pendance-%C3%A9nerg%C3%A9tique-emmanuel-macron-parie-sur-le-lithium-fran%C3%A7ais",
"https://www.france24.com/fr/vid%C3%A9o/20260422-l-ol%C3%A9oduc-droujba-reprendra-le-transport-du-brut-russe-vers-la-hongrie",
"https://www.service-public.fr/",
"https://www.france24.com/fr/vid%C3%A9o/20260422-liban-la-guerre-entre-isra%C3%ABl-et-le-hezbollah-a-fait-2-454-morts-selon-un-nouveau-bilan",
"https://www.france24.com/fr/vid%C3%A9o/20260422-gaza-une-biblioth%C3%A8que-sauv%C3%A9e-des-ruines-rouvre-ses-portes",
"https://www.amazon.fr/",
"https://www.france24.com/fr/afrique/20260422-madagascar-gen-z-mobilisation-peur-arrestations-militants-junte-randrianirina",
"https://www.france24.com/fr/europe/20260422-l-ue-donne-son-feu-vert-au-pr%C3%AAt-%C3%A0-l-ukraine-vote-d-un-20e-paquet-de-sanctions-contre-la-russie",
"https://www.sncf.com/",
"https://www.france24.com/fr/sports/20260422-nba-les-spurs-perdent-le-match-2-et-victor-wembanyama-sur-protocole-commotion",
"https://www.france24.com/fr/moyen-orient/20260422-accord-17-mai-1983-discussions-liban-israel-gemayel-hezbollah-assad",
"https://www.france24.com/fr/%C3%A9missions/dans-la-presse/20260422-r%C3%A9gularisation-des-sans-papiers-voir-un-excellent-ouvrier-expuls%C3%A9-c-est-du-g%C3%A2chis-pour-tous",
"https://www.sorbonne-universite.fr/",
"https://www.france24.com/fr/vid%C3%A9o/20260422-le-japon-l%C3%A8ve-les-barri%C3%A8res-%C3%A0-l-exportation-d-armes-un-revirement-historique",
"https://www.france24.com/fr/vid%C3%A9o/20260422-les-%C3%A9tats-unis-annoncent-la-prolongation-du-cessez-le-feu-avec-l-iran",
"https://www.credit-agricole.fr/"
],
"static_urls": [
"https://www.service-public.fr/",
"https://www.impots.gouv.fr/",
"https://www.sorbonne-universite.fr/",
"https://www.credit-agricole.fr/",
"https://www.sncf.com/",
"https://www.amazon.fr/",
"https://www.cdiscount.com/"
]
}
}
}

View File

@@ -8,13 +8,37 @@
},
"trust_module": {
"white_urls": [
"https://hk.news.yahoo.com/%E7%A9%BA%E9%99%8D%E6%97%85%E9%81%8A%E7%95%8C%E8%AD%B0%E5%B8%AD-%E6%B1%9F%E6%97%BB%E6%86%93%E5%B7%B2%E5%AE%8C%E6%88%90%E6%94%BE%E6%A3%84%E5%8A%A0%E6%8B%BF%E5%A4%A7%E8%AD%B7%E7%85%A7%E6%89%8B%E7%BA%8C-110901574.html",
"https://www.hko.gov.hk/",
"https://hk.news.yahoo.com/%E5%AE%8F%E7%A6%8F%E8%8B%91%E8%81%BD%E8%AD%89%E6%9C%83-%E6%B6%88%E9%98%B2%E8%99%95%E5%8A%A9%E7%90%86%E8%99%95%E9%95%B7-%E7%99%BC%E6%B3%A1%E8%86%A0%E5%B0%81%E7%AA%97%E5%8F%8A-%E7%94%9F%E5%8F%A3-%E4%B8%8D%E6%98%AF%E6%B6%88%E9%98%B2%E8%B2%A0%E8%B2%AC-050337364.html",
"https://www.hku.hk/",
"https://hk.news.yahoo.com/%E8%B2%BF%E7%99%BC%E5%B1%807%E5%A4%A7%E7%9B%9B%E4%BA%8B%E4%B8%8B%E5%91%A8%E8%88%89%E8%A1%8C-%E6%9C%AC%E5%9C%B0%E7%9B%B8%E6%A9%9F%E5%93%81%E7%89%8C%E8%88%87ip%E8%A8%AD%E8%A8%88%E5%B8%AB%E6%8E%A8%E7%9B%B2%E7%9B%92%E7%AA%81%E5%9C%8D-200000911.html",
"https://hk.news.yahoo.com/%E7%B6%AD%E5%90%89%E5%B0%BC%E4%BA%9E%E5%B7%9E%E5%85%AC%E6%8A%95%E6%94%AF%E6%8C%81%E6%96%B0%E9%81%B8%E5%8D%80%E5%9C%B0%E5%9C%96-%E5%B7%9D%E6%99%AE%E9%87%8D%E5%8A%83%E7%AD%96%E7%95%A5%E5%8F%97%E6%8C%AB-042003783.html",
"https://yahoo-news.com.hk/BBCChineseNews/41442/?yptr=yahoo",
"https://hk.news.yahoo.com/%E9%A6%96%E4%BB%BD%E4%BA%94%E5%B9%B4%E8%A6%8F%E5%8A%83%E7%88%AD%E4%BB%8A%E5%AD%A3%E8%AB%AE%E8%A9%A2-%E6%9D%8E%E5%AE%B6%E8%B6%85-%E9%A6%96%E9%95%B7%E5%95%8F%E8%B2%AC%E5%88%B6%E9%9D%9E%E6%90%9E%E5%80%8B%E4%BA%BA%E9%87%9D%E5%B0%8D-200000903.html",
"https://hk.news.yahoo.com/%E5%AE%8F%E7%A6%8F%E8%8B%91%E4%B8%8A%E6%A8%93%E5%9F%B7%E6%8B%BE-%E5%AD%90%E6%9B%BF%E5%85%AB%E6%97%AC%E7%88%B6%E4%B8%8A24%E6%A8%93-%E5%A6%82%E4%BB%A3%E7%88%B6%E5%BE%9E%E8%BB%8D%E7%9B%A1%E5%AD%9D-%E9%95%B7%E8%80%85%E6%86%BE%E6%9C%AA%E8%83%BD%E8%A6%AA%E8%BA%AB%E8%88%8740%E8%BC%89%E5%AE%B6%E5%9C%92%E5%91%8A%E5%88%A5-%E5%BC%B5%E6%9B%BC%E7%90%B3%E5%A0%B1%E9%81%93-050837706.html",
"https://hk.news.yahoo.com/%E7%BE%8E%E8%BB%8D%E6%BE%84%E6%B8%85%E8%96%A9%E5%BE%B7%E7%BA%8C%E7%95%99%E9%9F%93%E5%9C%8B-%E5%83%85%E5%90%91%E5%89%8D%E7%B7%9A%E4%B8%AD%E6%9D%B1%E8%AA%BF%E9%85%8D%E5%BD%88%E8%97%A5-030502616.html",
"https://hk.news.yahoo.com/%E6%B5%B7%E9%97%9C%E6%9F%A5%E5%85%A5%E5%A2%83%E8%B2%A8%E6%AA%A27200%E4%BB%B6%E6%87%B7%E7%96%91%E5%86%92%E7%89%8C%E8%B2%A8-44%E6%AD%B2%E5%8F%B8%E6%A9%9F%E8%A2%AB%E6%8D%95-200000540.html",
"https://hk.news.yahoo.com/%E6%94%9C%E9%9B%BB%E5%8B%95%E8%A1%8C%E6%9D%8E%E7%AF%8B%E9%97%96%E6%B8%AF%E9%90%B5%E7%88%86%E8%88%8C%E6%88%B0-%E6%8B%90%E6%9D%96%E7%94%B7%E8%81%B2%E5%A4%A7%E5%A4%BE%E6%83%A1-%EF%BC%9A-%E3%80%8C%E5%94%94%E5%95%B1%E5%92%AA%E5%91%8A%E6%88%91%E5%96%87%EF%BC%81%E3%80%8D-002334297.html",
"https://www.mtr.com.hk/",
"https://www.hktvmall.com/",
"https://www.gov.hk/",
"https://hk.news.yahoo.com/%E6%99%BA%E6%85%A7%E7%B6%A0%E8%89%B2%E9%9B%86%E9%AB%94%E9%81%8B%E8%BC%B8%E7%B3%BB%E7%B5%B1%E6%93%AC%E8%A8%AD%E6%96%B0%E8%A6%8F%E7%AE%A1%E6%A1%86%E6%9E%B6-%E4%B8%BB%E9%AB%94%E6%B3%95%E4%BE%8B%E8%8D%89%E6%A1%88%E7%AC%AC%E5%9B%9B%E5%AD%A3%E4%BA%A4%E7%AB%8B%E6%B3%95%E6%9C%83-200000187.html",
"https://www.hsbc.com.hk/",
"https://hk.news.yahoo.com/%E4%BF%84%E9%9B%BB%E8%A6%96%E5%90%8D%E5%98%B4%E8%BE%B1%E7%BD%B5%E6%A2%85%E6%B4%9B%E5%B0%BC-%E7%BE%A9%E5%8F%AC%E8%A6%8B%E5%A4%A7%E4%BD%BF%E5%9A%B4%E6%AD%A3%E6%8A%97%E8%AD%B0-013502721.html",
"https://hk.news.yahoo.com/%E5%B7%9D%E6%99%AE%E5%BB%B6%E9%95%B7%E5%81%9C%E7%81%AB%E4%BD%86%E7%B6%AD%E6%8C%81%E5%B0%81%E9%8E%96%E4%BC%8A%E6%9C%97%E6%B8%AF%E5%8F%A3-%E4%B8%AD%E6%9D%B1%E5%B1%80%E5%8B%A2%E6%8C%81%E7%BA%8C%E5%8B%95%E7%9B%AA-020502336.html",
"https://www.police.gov.hk/",
"https://yahoo-news.com.hk/BBCChineseNews/41437/?yptr=yahoo",
"https://hk.news.yahoo.com/%E9%86%AB%E7%AE%A1%E5%B1%80%E9%86%AB%E7%94%9F%E7%96%91%E6%9C%AA%E7%B6%93%E6%8E%88%E6%AC%8A%E9%96%B1%E8%A6%BD47%E7%97%85%E4%BA%BA%E9%86%AB%E7%99%82%E7%B4%80%E9%8C%84-%E8%A1%9B%E7%94%9F%E7%BD%B2-%E8%BD%89%E4%BB%8B%E8%AD%A6%E6%96%B9%E8%B7%9F%E9%80%B2-200000352.html"
],
"static_urls": [
"https://www.gov.hk/",
"https://www.hko.gov.hk/",
"https://www.scmp.com/",
"https://www.hk01.com/",
"https://zh.wikipedia.org/wiki/Special:Random",
"https://www.hktvmall.com/",
"https://www.mtr.com.hk/"
"https://www.police.gov.hk/",
"https://www.hku.hk/",
"https://www.hsbc.com.hk/",
"https://www.mtr.com.hk/",
"https://www.hktvmall.com/"
]
}
}
}

View File

@@ -4,17 +4,36 @@
"base_lat": 35.6812,
"base_lon": 139.7671,
"lang_params": "hl=ja&gl=JP",
"valid_url_suffix": "com"
"valid_url_suffix": "com"
},
"trust_module": {
"white_urls": [
"https://ja.wikipedia.org/wiki/Special:Random",
"https://www.yahoo.co.jp/",
"https://www.jreast.co.jp/",
"https://news.yahoo.co.jp/pickup/6577251?source=rss",
"https://www.rakuten.co.jp/",
"https://www.nhk.or.jp/",
"kakaku.com/",
"https://www.goo.ne.jp/",
"https://www.amazon.co.jp/"
"https://www.smbc.co.jp/",
"https://www.amazon.co.jp/",
"https://news.yahoo.co.jp/pickup/6577254?source=rss",
"https://news.yahoo.co.jp/pickup/6577260?source=rss",
"https://www.mhlw.go.jp/",
"https://news.yahoo.co.jp/pickup/6577252?source=rss",
"https://www.u-tokyo.ac.jp/",
"https://news.yahoo.co.jp/pickup/6577265?source=rss",
"https://news.yahoo.co.jp/pickup/6577219?source=rss",
"https://news.yahoo.co.jp/pickup/6577263?source=rss",
"https://www.japan.go.jp/",
"https://www.yahoo.co.jp/",
"https://news.yahoo.co.jp/pickup/6577264?source=rss"
],
"static_urls": [
"https://www.japan.go.jp/",
"https://www.mhlw.go.jp/",
"https://www.u-tokyo.ac.jp/",
"https://www.smbc.co.jp/",
"https://www.jreast.co.jp/",
"https://www.yahoo.co.jp/",
"https://www.amazon.co.jp/",
"https://www.rakuten.co.jp/"
]
}
}

View File

@@ -0,0 +1,36 @@
{
"region_name": "South Korea - Seoul",
"google_module": {
"base_lat": 37.5665,
"base_lon": 126.978,
"lang_params": "hl=ko&gl=KR",
"valid_url_suffix": "co.kr"
},
"trust_module": {
"white_urls": [
"https://www.naver.com/",
"https://www.korea.kr/",
"https://www.yonhapnewstv.co.kr/news/MYH20260422204802JNu",
"https://www.yonhapnewstv.co.kr/news/MYH20260422201823TIG",
"https://www.snu.ac.kr/",
"https://www.hometax.go.kr/",
"https://www.yonhapnewstv.co.kr/news/AKR20260422215011UlR",
"https://www.kakao.com/",
"https://www.coupang.com/",
"https://www.kbstar.com/",
"https://www.yonhapnewstv.co.kr/news/AKR20260422204757U0M",
"https://www.yonhapnewstv.co.kr/news/MYH20260422201458YXI",
"https://www.daum.net/"
],
"static_urls": [
"https://www.korea.kr/",
"https://www.hometax.go.kr/",
"https://www.snu.ac.kr/",
"https://www.kbstar.com/",
"https://www.naver.com/",
"https://www.daum.net/",
"https://www.coupang.com/",
"https://www.kakao.com/"
]
}
}

View File

@@ -0,0 +1,44 @@
{
"region_name": "Netherlands - Amsterdam",
"google_module": {
"base_lat": 52.3676,
"base_lon": 4.9041,
"lang_params": "hl=nl&gl=NL",
"valid_url_suffix": "nl"
},
"trust_module": {
"white_urls": [
"https://www.marktplaats.nl/",
"https://www.rijksoverheid.nl/",
"https://nos.nl/l/2611539",
"https://nos.nl/l/2611544",
"https://nos.nl/l/2611558",
"https://nos.nl/l/2611517",
"https://www.ing.nl/",
"https://nos.nl/l/2611510",
"https://nos.nl/l/2611513",
"https://www.belastingdienst.nl/",
"https://nos.nl/l/2611533",
"https://www.buienradar.nl/",
"https://www.ns.nl/",
"https://www.bol.com/",
"https://nos.nl/l/2611543",
"https://nos.nl/l/2611529",
"https://nos.nl/l/2611522",
"https://nos.nl/l/2611521",
"https://nos.nl/l/2611536",
"https://nos.nl/l/2611534",
"https://nos.nl/l/2611509",
"https://nos.nl/l/2611537"
],
"static_urls": [
"https://www.rijksoverheid.nl/",
"https://www.belastingdienst.nl/",
"https://www.ing.nl/",
"https://www.ns.nl/",
"https://www.bol.com/",
"https://www.marktplaats.nl/",
"https://www.buienradar.nl/"
]
}
}

View File

@@ -8,13 +8,39 @@
},
"trust_module": {
"white_urls": [
"https://www.straitstimes.com/",
"https://www.channelnewsasia.com/",
"https://www.gov.sg/",
"https://shopee.sg/",
"https://en.wikipedia.org/wiki/Special:Random",
"https://www.channelnewsasia.com/business/siriusxm-sell-youtube-audio-ads-exclusively-in-us-6073691",
"https://www.channelnewsasia.com/singapore/kurt-tay-share-intimate-video-photo-without-consent-fine-jail-6073786",
"https://www.cpf.gov.sg/",
"https://www.channelnewsasia.com/asia/south-korea-vietnam-lam-nuclear-energy-6073801",
"https://www.channelnewsasia.com/asia/duterte-icc-judges-reject-bid-release-hague-6073761",
"https://www.channelnewsasia.com/business/tencent-alibaba-in-talks-invest-in-deepseek-over-20-billion-valuation-information-reports-6073626",
"https://www.dbs.com.sg/",
"https://www.channelnewsasia.com/business/teledyne-lifts-annual-profit-forecast-beats-quarterly-estimates-6073636",
"https://www.channelnewsasia.com/business/youtube-complies-indonesias-social-media-curbs-minister-says-6073646",
"https://www.singpass.gov.sg/",
"https://www.channelnewsasia.com/singapore/strait-malacca-open-indonesia-malaysia-vivian-balakrishnan-6073151",
"https://www.nus.edu.sg/",
"https://www.channelnewsasia.com/business/paint-planes-iran-war-lifts-costs-darkens-outlooks-6073746",
"https://www.fairprice.com.sg/",
"https://www.dbs.com.sg/"
"https://www.channelnewsasia.com/sport/us-womens-soccer-league-joins-global-project-cut-acl-injuries-6073831",
"https://www.channelnewsasia.com/business/societe-generale-takes-more-crypto-firms-clients-sg-forge-ceo-says-6073611",
"https://www.iras.gov.sg/",
"https://www.channelnewsasia.com/business/gaming-industry-could-unlock-22-billion-in-profits-ai-driven-cost-cuts-says-morgan-stanley-6073866",
"https://www.channelnewsasia.com/business/honeywells-quantinuum-confidentially-files-us-ipo-6073881",
"https://www.channelnewsasia.com/business/traders-place-430-million-bet-lower-oil-price-trump-ceasefire-extension-6073876",
"https://www.gov.sg/",
"https://www.shopee.sg/",
"https://www.channelnewsasia.com/business/uk-targets-illegal-crypto-trading-in-london-crackdown-6073696"
],
"static_urls": [
"https://www.gov.sg/",
"https://www.cpf.gov.sg/",
"https://www.iras.gov.sg/",
"https://www.singpass.gov.sg/",
"https://www.nus.edu.sg/",
"https://www.dbs.com.sg/",
"https://www.shopee.sg/",
"https://www.fairprice.com.sg/"
]
}
}
}

View File

@@ -0,0 +1,48 @@
{
"region_name": "Taiwan - Taipei",
"google_module": {
"base_lat": 25.033,
"base_lon": 121.5654,
"lang_params": "hl=zh-TW&gl=TW",
"valid_url_suffix": "com.tw"
},
"trust_module": {
"white_urls": [
"https://news.google.com/rss/articles/CBMiuANBVV95cUxPMUtIaGFILVJubWx6Y3ZLak41OS1HYlJ2TnhRZUJrMEhrOE1HU1FZU2dHUVlnTzRSSUR5djNJdlNPc3g0dUdpaW9pZm4wYUtnM2R2OGY2aXl1WDdNMU9fWmRDTGpHRTVvODhvZTRoZTZXeTFoS2RNdk9zTllVdXNkby1zZkxva0dfZXloVEhCdWdpaXJlMEpJTEJRTU43VVNfRFlvcWttTkVYMkZVakJfV2dlbnVYeElKVTV0WDgwRWVkZm5rVEk4S2w4MG9vQWE1eHdKYllPYkdGVXVJeVBCN1NBUC1Zb0NRaEduZWxWZ2NKcVJCSU12MzB4OVZDMXB6QWdqcWtvd05kRnlwZWJWZUVDel9uYkFNZFdnT2dkNXR0Qzd5b1ItTGExWThHRXRJMF9hNmFGb1FwMUhCMUdWcTlWOG13Rjl3cV9HX3RiU1lpOFY2ZTF2UV9ucHNsbDk2SzRobnd3a3hlNU04UFNOUU42cEFaMmFxcnFWbUNTMEVEVUVmX2U3ejhRNTJMSHpYY0tsaGl1N01ia3JkNjJld3VRZnViOWRqeHdacWQ5QXkwNUJINzNTMw?oc=5",
"https://news.google.com/rss/articles/CBMiX0FVX3lxTE5leFVYMGNSSnhUYVlkX21icUZtQ3NoaE9kNHl1ek15YkNlaDk4T05lNVZfNFR2MldFY2F0Q2VfNDdmMVVac3NZd1dBalpKZkxNNWpPdkxPS191VVFqMnRN?oc=5",
"https://www.post.gov.tw/",
"https://news.google.com/rss/articles/CBMiigNBVV95cUxQaFAwZ3RlS2JkeE1aSWxjb0FUWEZoSGNodVdLcEVxYUZmbmg5Y18zVkVDYUdSS0NlU1BjS1cwYV9oNzNoaEdoNG5oWS1kaHpLZzJQQ2owVTNybUR2QkVQZXJmdlF4QUh2TGdZbVA5QjdrdWl3bGxxY2xnUVFjZVhaaEc2OWRhQTh6dEtZTEI2TENuWGI1QXFUWllRSWVvTGNmRHUtQ0xISlZoNGx5eS0zUnA5MXl2MzhGS0JEQzJRUnd1R1VQeTV5ZHM2Z3V0emtyelEzR193NlJuby1CMHdvTjNPN1FlRE41WThYTk1rN25mQWwyajJvaXB4NHFOOXd1MEtzdm9Sa0x3RGk3MGthQWhtT3lPSDk0M2o2MGN0MkxnUTZza0NhWFItb2gyc3VlUTF4QkhGQnJzb3I4N3JGYUJ1dmRyNHQ0eG81OEk3Q0I0TGkzUTgtSEctaXQyakxlSjBGWjJIZEFmNFczaTA4Ti1mR0cwTXhpa3FMOW1uNmV3NFBiMktCd21B?oc=5",
"https://news.google.com/rss/articles/CBMiU0FVX3lxTE5PMHNGTnh0NmxNVEhOMlRFdXowaDFhbDZKNUU2M1FBNjBXVmpXRFJHcGYxd3M4dGtQVkVlZkxwV0p1QUFQSkRtaWNyV2o4Qy1yNUJz0gFYQVVfeXFMTlVfU3oybndqR3RiVElTV0lZa0taaWVSSDgzRzZDd3pXMnJ6c0xjVXhPazdEM0VCWVR5SW9CVVMzdjFHdkNhaTQ1MS1MYWY3U1pjZkoxNHhnSw?oc=5",
"https://www.thsrc.com.tw/",
"https://www.momoshop.com.tw/",
"https://www.cathaybk.com.tw/",
"https://news.google.com/rss/articles/CBMiU0FVX3lxTFBYZTd6anAtZ2VhZVRRN3d5MGZHZVZrYlZHaWxzSmJyaklOd2pYX0w1RTVraFZsWnRqRTZZb042YTlSVjJYdzhVWTMzUm9qalc0cW1z0gFYQVVfeXFMT3JyTUJwRHJlNDlfeFAyLUdWMFFLclJ4WWF3TG1UM0JpTTAxdFZGRV96eThjYnp0YUMtNDlybEd5VWp2dDlhVlR0UHk2eTZUNGVueVd6ZHQ1LQ?oc=5",
"https://news.google.com/rss/articles/CBMiU0FVX3lxTE9zdFMyOGF1RmJIRi14NGw0Z3RCSEUzZzl0V19XN0pQaDZQdlRHUUxNMUhTbTFGamY0cWtfb2FNcUoxdTJFajNwemlZV244VGVFSE5R?oc=5",
"https://news.google.com/rss/articles/CBMiwgJBVV95cUxPNWdHTTAxTV9ZbUR1V25acWhZYmhMa1hTZlpHcGpQaUpxa2hOcFFkX1ZYZko5U3QteEpjVkxQM3lCUWpaWDdBMHNKWlRYTEFVYVNoN2dOclQ3WTJPOExBajhwaURrSjBLUENTN2ZySVQwV3pQaTZydDFyUUhnZzdnT0NINFFlMWhhZ25WbDVGZU9YUmVyaFQ3TF9pLXAwc0lZTDNpdEFuWV9ad2FscWZ4YVhQdVhzX2pRa21UZG9uSkRxQ1BVTDBDcGtrQ193eDFpTXlyN09jZ1VIcWR1NGxrdmF3VjJqMzd0eEJ0aHNseTRKRm0tQ0ttLW1oMW9EcW9GZ0xhbzNPaHg5MVEwSW1nS2RiVjFNajRVSUl2eUJLRHktVEc2RGhUaTdZQUJUN3RHVmM5ZXktU1ZSNlBFU0RsMTVR?oc=5",
"https://www.gov.tw/",
"https://news.google.com/rss/articles/CBMiW0FVX3lxTFB0WDdNMVkwbkZRSXRZU1RqYWlpejF0WFNMVkVrSlNWUlpqSzRZeFNZdVNRRlZFR005d1VEZzVZNTJ1SjFYZ3dpZUVOYmhLenFkWUpfdzlBSXMydkHSAWBBVV95cUxPbXprNmM5NF9KN3pnaklrZFhKU1lzMnhBbDZiYmkxNmNBeDRDU3FXZF9LOFU4aDBwWG9tQUhieDdmejA1UmV3a0lYbnRqZGRSUHFGajRXZHJRQ3NqX055WFE?oc=5",
"https://tw.yahoo.com/",
"https://news.google.com/rss/articles/CBMiggNBVV95cUxPeXhmYWx6TEE1OFA2eHlwWktXVTRPSDlINXdWT0JtbldiNVAwWG9qaGdJcThUUEZIUV9kVlZJaWVOd3NuaEZnZU9CZ3hyeGk2V0UwQ1BTR0NLZWFXR1ZIbjhnUWNxZ1pQS0hvVm5vZkdpMG02dEF2LWxOQThSTzBzX0M0ck8tY1hVV2FYMVFURkhSTmdweUNFZDkxd2gyeFc3WGk5c1BGWTRwQUdiVDd5dEFJM0NYQ3pyVURtWVJIRmp6MVZCdWxtM1BDcG4tUDUydUt1OG9OWUxNcGkycVR0X25YNWlPVm9xMC00Q2xMaFhxWTZkd1BsUlRBa0YxajRXN0F2Mi04Z2RpY3U1UEh1N3RvSkxPQ2N5YzhVcGtTaWprRjVQQVlkQk0za2FMYkE0SkQ5Y1Zpczg5UDBkNHRlZ3lYem9YRTJjTnBvdWlENEs0bjhEMTVleGFtdmhSUzVHTHFYWXVvdzU1NFBKR0tNcnM5Nm05bjg0amFuZVZHa0dWQQ?oc=5",
"https://news.google.com/rss/articles/CBMiW0FVX3lxTE1VdE04M05vQ0g1MHRtMFF1NXVROFJxdzFIdjlTXy1veE1MWmFFdVhGUGhDdm1udU5fRjg2OElPZUxZVUY1MjZaTDFyS1N6T0QwVjhFOW52ei1iWFk?oc=5",
"https://news.google.com/rss/articles/CBMigwFBVV95cUxPbHdMQWJoUWNuSElHMVc5UTBEb1pyMEpEd0RZVlpFRW5EUkVpU2pKczNMVmF5RWl0bWlYUEdiQkFLU1FQbWo0UEFqZTZaeTVtZTlpbFdVN05YbUNOY3MwWVB2aGo0cWhfVGVSci1SQnYzbkdFc3JhQ2stcU9POGgxMGNVTQ?oc=5",
"https://www.ntu.edu.tw/",
"https://news.google.com/rss/articles/CBMiUEFVX3lxTE1XOG1FNkhBT2s3aEZmVjEtOHFjdFgyVnBCOGVLeS02bkZwYzRqQTJxekNQVS1USTAtanhjMFp0eG50WURKY3ZnRVg0OXpGeFdN0gFWQVVfeXFMUC00VEY3TnFaU1VGRUFNeVUtN1BDRmNYN3p2bW1LNS1iWURPN1dScFgwbjJ0elRReUg1bDFLU0pQT2ZDX00tUDdid292QVI0VUlVNlJWSlE?oc=5",
"https://www.pchome.com.tw/",
"https://www.dcard.tw/",
"https://news.google.com/rss/articles/CBMiX0FVX3lxTE85a1R0ZFF6NnVLd09XUmRIQ3JEdUZQRTB4THlILXJoWHYzWnVzUFlXTl9HTXUybGNHSU5mMHR2d2swRlE5YUpoYTc2TEhwM1NtSm9ZOThZa3hYdHAxSFUw0gFkQVVfeXFMTnVURVBzazlRczRzRTlqZFBXazI2eml5SjVYLTJUWDZzU01PREdDQ1lSbHdJeFNqUXJWWks4N2lhazdYLXVLYmtrUFZzVlViZHhRdVQ4S0VhcE5aeUVwVXNCdE9HLQ?oc=5",
"https://news.google.com/rss/articles/CBMi0AJBVV95cUxNM1ZxNmlnb0ZzdnoxVnZDSFlBbHdqUFFmUTVYbEFPVU9RTGNld2VHekh5SlJIc051VmlXazJzMzgtYzliYzljcUpmQmJ6TGRyWEFHT29FNTFKSmRyYkxndk1qQ3NZZWVYLUMycEs3cXVzQm1wemFuMEliMF9fV2YtXzQ2Mlo0OG5tT0lNS2ZFa3R4azdmZGJfTmhJbTVYRTQyQmVQYWdBRHF6M2xldUUzTUhPR2dta1MyUVY2X2FyRmZnbzUxZnpHMFNHemhGVEdCNUc0OVhsUGttUHZoMmV1VTlsR2otVHV2eXJKNTBzTzNfa2cwU0ZRWENFcGJjNVZzbmFYVUlERDFUMDhSMUQ4MHkycFFaWnVvYnM4Z3c1X0trUGFpNDQ0cGY1Z2VOVWhfY3RJUE9JRVZLaTFzN2NMdXJZdXhCMmRZbWRVVWRLbW8?oc=5",
"https://news.google.com/rss/articles/CBMiZEFVX3lxTE82ZE9remRVeUdQMTVTblh6QmZZNU5DNjczSi1LOXBhY2kzZHE3d0hFQlhGRzQ4ZGNMQjl2T3pBbGZadjEwX0k5M2pEellBc3ZpcGtuQS1RVWRQRUdEUUM0WHRmQ0rSAWpBVV95cUxPVTJsbzVPeDRhQmpUTnZoVXAwMkxGRjBNQ2JqWm83TGFmRkRVdWlKOWh0Q0FFMWFVVEZaRHJMNVNfQ2w1bzlYVUVSTWRsQXh3eXEzMk5iM2k5V0ZQM3Uya2VfdUMxNmVMaEtB?oc=5"
],
"static_urls": [
"https://www.gov.tw/",
"https://www.post.gov.tw/",
"https://www.ntu.edu.tw/",
"https://www.cathaybk.com.tw/",
"https://www.thsrc.com.tw/",
"https://tw.yahoo.com/",
"https://www.momoshop.com.tw/",
"https://www.pchome.com.tw/",
"https://www.dcard.tw/"
]
}
}

View File

@@ -0,0 +1,46 @@
{
"region_name": "United Kingdom - Coventry",
"google_module": {
"base_lat": 52.4068,
"base_lon": -1.5197,
"lang_params": "hl=en&gl=GB",
"valid_url_suffix": "co.uk"
},
"trust_module": {
"white_urls": [
"https://www.bbc.com/sport/golf/articles/ce3drrggndwo?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/news/articles/cqj8kk0z0l5o?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/news/articles/cj0v632yddzo?at_medium=RSS&at_campaign=rss",
"https://www.bbc.co.uk/iplayer/episode/m002hzg7?at_mid=UpOeB35B7u&at_campaign=Wild_London&at_medium=display_ad&at_campaign_type=owned&at_nation=NET&at_audience_id=SS&at_product=iplayer&at_brand=m002hzg7&at_ptr_name=bbc&at_ptr_type=media&at_format=image&at_objective=consumption&at_link_title=Wild_London&at_bbc_team=BBC",
"https://www.postoffice.co.uk/",
"https://www.ox.ac.uk/",
"https://www.bbc.com/news/articles/cre1r4n5j5wo?at_medium=RSS&at_campaign=rss",
"https://www.bbc.co.uk/sounds/play/p0nfg11p?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/news/articles/cz78zj74548o?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/news/articles/cvg4yr90jr2o?at_medium=RSS&at_campaign=rss",
"https://www.barclays.co.uk/",
"https://www.bbc.com/sport/football/articles/cgld7jn1rkpo?at_medium=RSS&at_campaign=rss",
"https://www.amazon.co.uk/",
"https://www.ebay.co.uk/",
"https://www.gov.uk/",
"https://www.bbc.com/weather/articles/cede7gpjn85o?at_medium=RSS&at_campaign=rss",
"https://www.nationalrail.co.uk/",
"https://www.bbc.com/sport/football/articles/c145vyjypevo?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/news/articles/cy41zejp9pko?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/news/articles/c4glkwww345o?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/news/articles/c0krl571l67o?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/news/articles/cy41zknw3m3o?at_medium=RSS&at_campaign=rss",
"https://www.nhs.uk/"
],
"static_urls": [
"https://www.gov.uk/",
"https://www.nhs.uk/",
"https://www.ox.ac.uk/",
"https://www.barclays.co.uk/",
"https://www.postoffice.co.uk/",
"https://www.nationalrail.co.uk/",
"https://www.amazon.co.uk/",
"https://www.ebay.co.uk/"
]
}
}

View File

@@ -8,13 +8,39 @@
},
"trust_module": {
"white_urls": [
"https://www.bbc.co.uk/",
"https://www.gov.uk/",
"https://www.bbc.com/news/articles/cz78zj74548o?at_medium=RSS&at_campaign=rss",
"https://www.bbc.co.uk/iplayer/episode/m002hzg7?at_mid=UpOeB35B7u&at_campaign=Wild_London&at_medium=display_ad&at_campaign_type=owned&at_nation=NET&at_audience_id=SS&at_product=iplayer&at_brand=m002hzg7&at_ptr_name=bbc&at_ptr_type=media&at_format=image&at_objective=consumption&at_link_title=Wild_London&at_bbc_team=BBC",
"https://www.amazon.co.uk/",
"https://www.theguardian.com/uk",
"https://www.bbc.com/news/articles/cvg4yr90jr2o?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/weather/articles/cede7gpjn85o?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/sport/football/articles/c145vyjypevo?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/news/articles/cj0v632yddzo?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/sport/golf/articles/ce3drrggndwo?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/news/articles/cqj8kk0z0l5o?at_medium=RSS&at_campaign=rss",
"https://www.bbc.co.uk/sounds/play/p0nfg11p?at_medium=RSS&at_campaign=rss",
"https://www.barclays.co.uk/",
"https://www.gov.uk/",
"https://www.bbc.com/news/articles/c4glkwww345o?at_medium=RSS&at_campaign=rss",
"https://www.nationalrail.co.uk/",
"https://www.bbc.com/news/articles/cy41zejp9pko?at_medium=RSS&at_campaign=rss",
"https://www.postoffice.co.uk/",
"https://www.ox.ac.uk/",
"https://www.bbc.com/news/articles/c0krl571l67o?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/news/articles/cy41zknw3m3o?at_medium=RSS&at_campaign=rss",
"https://www.nhs.uk/",
"https://en.wikipedia.org/wiki/Special:Random",
"https://www.bbc.com/sport/football/articles/cgld7jn1rkpo?at_medium=RSS&at_campaign=rss",
"https://www.bbc.com/news/articles/cre1r4n5j5wo?at_medium=RSS&at_campaign=rss",
"https://www.ebay.co.uk/"
],
"static_urls": [
"https://www.gov.uk/",
"https://www.nhs.uk/",
"https://www.ox.ac.uk/",
"https://www.barclays.co.uk/",
"https://www.postoffice.co.uk/",
"https://www.nationalrail.co.uk/",
"https://www.amazon.co.uk/",
"https://www.ebay.co.uk/"
]
}
}
}

View File

@@ -8,13 +8,43 @@
},
"trust_module": {
"white_urls": [
"https://en.wikipedia.org/wiki/Special:Random",
"https://www.yahoo.com/",
"https://www.cnn.com/2023/04/18/us/mccurtain-county-oklahoma-officials-recording/index.html",
"https://www.cnn.com/2023/04/18/tech/lina-khan-ai-warning/index.html",
"https://www.cdc.gov/",
"https://www.target.com/",
"https://www.npr.org/",
"https://www.weather.com/",
"https://www.cnn.com/2023/04/18/politics/clarence-thomas-ethics-democrats/index.html",
"https://www.cnn.com/audio/podcasts/the-assignment/episodes/42a2f0e2-066a-4675-82ff-afe2016a0bb5",
"https://www.cnn.com/2023/04/17/health/rise-type-2-diabetes-global-wellness/index.html",
"https://www.cnn.com/videos/travel/2023/04/18/century-old-shipwrecks-lake-superior-discovery-contd-orig-zt.cnn",
"https://www.cnn.com/2023/04/14/entertainment/barry-season-4-review/index.html",
"https://www.usps.com/",
"https://www.cnn.com/videos/us/2023/04/18/jeremy-renner-snowplow-accident-bodycam-nc-melas-contd-vpx.cnn",
"https://www.npr.org/2026/04/22/nx-s1-5787684/tree-hugger-history-earth-day",
"https://www.irs.gov/",
"https://www.cnn.com/2023/04/18/us/kansas-city-ralph-yarl-shooting-tuesday/index.html",
"https://www.bankofamerica.com/",
"https://www.amazon.com/",
"https://www.cdc.gov/"
"https://www.walmart.com/",
"https://www.chase.com/",
"https://www.cnn.com/2023/04/18/media/fox-dominion-settlement/index.html",
"https://www.cnn.com/2023/04/17/opinions/us-tax-system-wealthy-disney-pearl/index.html",
"https://www.npr.org/2026/04/22/nx-s1-5791744/faa-dot-air-traffic-control-system-revamp",
"https://www.usa.gov/",
"https://www.npr.org/2026/04/22/nx-s1-5791680/doj-disability-web-access-delay-schools",
"https://www.harvard.edu/",
"https://www.cnn.com/videos/politics/2023/04/18/kevin-mccarthy-wall-street-speech-debt-ceiling-biden-economy-vpx.cnn"
],
"static_urls": [
"https://www.usa.gov/",
"https://www.irs.gov/",
"https://www.cdc.gov/",
"https://www.harvard.edu/",
"https://www.chase.com/",
"https://www.bankofamerica.com/",
"https://www.amazon.com/",
"https://www.target.com/",
"https://www.walmart.com/",
"https://www.usps.com/"
]
}
}

View File

@@ -8,14 +8,43 @@
},
"trust_module": {
"white_urls": [
"https://en.wikipedia.org/wiki/Special:Random",
"https://www.yahoo.com/",
"https://www.target.com/",
"https://www.npr.org/",
"https://www.weather.com/",
"https://www.amazon.com/",
"https://www.usps.com/",
"https://www.cnn.com/videos/politics/2023/04/18/kevin-mccarthy-wall-street-speech-debt-ceiling-biden-economy-vpx.cnn",
"https://www.cnn.com/2023/04/18/us/mccurtain-county-oklahoma-officials-recording/index.html",
"https://www.harvard.edu/",
"https://www.cnn.com/2023/04/17/opinions/us-tax-system-wealthy-disney-pearl/index.html",
"https://www.cnn.com/2023/04/18/tech/lina-khan-ai-warning/index.html",
"https://www.walmart.com/",
"https://www.cnn.com/2023/04/18/us/kansas-city-ralph-yarl-shooting-tuesday/index.html",
"https://www.irs.gov/",
"https://www.cdc.gov/",
"https://www.mercurynews.com/"
"https://www.usa.gov/",
"https://www.npr.org/2026/04/22/nx-s1-5787684/tree-hugger-history-earth-day",
"https://www.cnn.com/videos/travel/2023/04/18/century-old-shipwrecks-lake-superior-discovery-contd-orig-zt.cnn",
"https://www.cnn.com/2023/04/14/entertainment/barry-season-4-review/index.html",
"https://www.cnn.com/audio/podcasts/the-assignment/episodes/42a2f0e2-066a-4675-82ff-afe2016a0bb5",
"https://www.cnn.com/2023/04/18/politics/clarence-thomas-ethics-democrats/index.html",
"https://www.chase.com/",
"https://www.target.com/",
"https://www.cnn.com/2023/04/17/health/rise-type-2-diabetes-global-wellness/index.html",
"https://www.cnn.com/2023/04/18/media/fox-dominion-settlement/index.html",
"https://www.cnn.com/videos/us/2023/04/18/jeremy-renner-snowplow-accident-bodycam-nc-melas-contd-vpx.cnn",
"https://www.npr.org/2026/04/22/nx-s1-5791680/doj-disability-web-access-delay-schools",
"https://www.npr.org/2026/04/22/nx-s1-5791744/faa-dot-air-traffic-control-system-revamp",
"https://www.amazon.com/",
"https://www.bankofamerica.com/"
],
"static_urls": [
"https://www.usa.gov/",
"https://www.irs.gov/",
"https://www.cdc.gov/",
"https://www.harvard.edu/",
"https://www.chase.com/",
"https://www.bankofamerica.com/",
"https://www.amazon.com/",
"https://www.target.com/",
"https://www.walmart.com/",
"https://www.usps.com/"
]
}
}
}

View File

@@ -0,0 +1,50 @@
{
"region_name": "United States - Warrenville",
"google_module": {
"base_lat": 41.8164,
"base_lon": -88.1748,
"lang_params": "hl=en&gl=US",
"valid_url_suffix": "com"
},
"trust_module": {
"white_urls": [
"https://www.cnn.com/audio/podcasts/the-assignment/episodes/42a2f0e2-066a-4675-82ff-afe2016a0bb5",
"https://www.cnn.com/2023/04/18/tech/lina-khan-ai-warning/index.html",
"https://www.cnn.com/videos/us/2023/04/18/jeremy-renner-snowplow-accident-bodycam-nc-melas-contd-vpx.cnn",
"https://www.walmart.com/",
"https://www.chase.com/",
"https://www.cnn.com/2023/04/17/opinions/us-tax-system-wealthy-disney-pearl/index.html",
"https://www.target.com/",
"https://www.irs.gov/",
"https://www.cnn.com/2023/04/18/us/mccurtain-county-oklahoma-officials-recording/index.html",
"https://www.cnn.com/videos/politics/2023/04/18/kevin-mccarthy-wall-street-speech-debt-ceiling-biden-economy-vpx.cnn",
"https://www.cnn.com/2023/04/17/health/rise-type-2-diabetes-global-wellness/index.html",
"https://www.harvard.edu/",
"https://www.amazon.com/",
"https://www.npr.org/2026/04/22/nx-s1-5787684/tree-hugger-history-earth-day",
"https://www.bankofamerica.com/",
"https://www.cnn.com/2023/04/18/politics/clarence-thomas-ethics-democrats/index.html",
"https://www.usps.com/",
"https://www.cnn.com/videos/travel/2023/04/18/century-old-shipwrecks-lake-superior-discovery-contd-orig-zt.cnn",
"https://www.cnn.com/2023/04/14/entertainment/barry-season-4-review/index.html",
"https://www.npr.org/2026/04/22/nx-s1-5791680/doj-disability-web-access-delay-schools",
"https://www.cnn.com/2023/04/18/media/fox-dominion-settlement/index.html",
"https://www.npr.org/2026/04/22/nx-s1-5791744/faa-dot-air-traffic-control-system-revamp",
"https://www.cnn.com/2023/04/18/us/kansas-city-ralph-yarl-shooting-tuesday/index.html",
"https://www.usa.gov/",
"https://www.cdc.gov/"
],
"static_urls": [
"https://www.usa.gov/",
"https://www.irs.gov/",
"https://www.cdc.gov/",
"https://www.harvard.edu/",
"https://www.chase.com/",
"https://www.bankofamerica.com/",
"https://www.amazon.com/",
"https://www.target.com/",
"https://www.walmart.com/",
"https://www.usps.com/"
]
}
}

View File

@@ -0,0 +1,50 @@
{
"region_name": "United States - Charlotte",
"google_module": {
"base_lat": 35.2271,
"base_lon": -80.8431,
"lang_params": "hl=en&gl=US",
"valid_url_suffix": "com"
},
"trust_module": {
"white_urls": [
"https://www.npr.org/2026/04/22/nx-s1-5793900/republican-strategist-on-trumps-cabinet-turnover-and-how-it-could-affect-his-agenda",
"https://www.cnn.com/2023/04/17/opinions/us-tax-system-wealthy-disney-pearl/index.html",
"https://www.chase.com/",
"https://www.cnn.com/videos/us/2023/04/18/jeremy-renner-snowplow-accident-bodycam-nc-melas-contd-vpx.cnn",
"https://www.usa.gov/",
"https://www.bankofamerica.com/",
"https://www.npr.org/2026/04/22/nx-s1-5787684/tree-hugger-history-earth-day",
"https://www.amazon.com/",
"https://www.cnn.com/2023/04/14/entertainment/barry-season-4-review/index.html",
"https://www.cdc.gov/",
"https://www.irs.gov/",
"https://www.cnn.com/2023/04/18/us/mccurtain-county-oklahoma-officials-recording/index.html",
"https://www.cnn.com/videos/politics/2023/04/18/kevin-mccarthy-wall-street-speech-debt-ceiling-biden-economy-vpx.cnn",
"https://www.cnn.com/videos/travel/2023/04/18/century-old-shipwrecks-lake-superior-discovery-contd-orig-zt.cnn",
"https://www.walmart.com/",
"https://www.npr.org/2026/04/22/nx-s1-5791680/doj-disability-web-access-delay-schools",
"https://www.npr.org/2026/04/22/nx-s1-5791744/faa-dot-air-traffic-control-system-revamp",
"https://www.cnn.com/2023/04/18/media/fox-dominion-settlement/index.html",
"https://www.cnn.com/2023/04/18/us/kansas-city-ralph-yarl-shooting-tuesday/index.html",
"https://www.harvard.edu/",
"https://www.cnn.com/audio/podcasts/the-assignment/episodes/42a2f0e2-066a-4675-82ff-afe2016a0bb5",
"https://www.cnn.com/2023/04/17/health/rise-type-2-diabetes-global-wellness/index.html",
"https://www.target.com/",
"https://www.cnn.com/2023/04/18/tech/lina-khan-ai-warning/index.html",
"https://www.usps.com/"
],
"static_urls": [
"https://www.usa.gov/",
"https://www.irs.gov/",
"https://www.cdc.gov/",
"https://www.harvard.edu/",
"https://www.chase.com/",
"https://www.bankofamerica.com/",
"https://www.amazon.com/",
"https://www.target.com/",
"https://www.walmart.com/",
"https://www.usps.com/"
]
}
}

View File

@@ -0,0 +1,50 @@
{
"region_name": "United States - Las Vegas",
"google_module": {
"base_lat": 36.1699,
"base_lon": -115.1398,
"lang_params": "hl=en&gl=US",
"valid_url_suffix": "com"
},
"trust_module": {
"white_urls": [
"https://www.cnn.com/2023/04/18/us/kansas-city-ralph-yarl-shooting-tuesday/index.html",
"https://www.usa.gov/",
"https://www.cnn.com/2023/04/17/health/rise-type-2-diabetes-global-wellness/index.html",
"https://www.cnn.com/audio/podcasts/the-assignment/episodes/42a2f0e2-066a-4675-82ff-afe2016a0bb5",
"https://www.cnn.com/2023/04/14/entertainment/barry-season-4-review/index.html",
"https://www.cnn.com/videos/politics/2023/04/18/kevin-mccarthy-wall-street-speech-debt-ceiling-biden-economy-vpx.cnn",
"https://www.walmart.com/",
"https://www.cnn.com/2023/04/18/us/mccurtain-county-oklahoma-officials-recording/index.html",
"https://www.cdc.gov/",
"https://www.usps.com/",
"https://www.npr.org/2026/04/22/nx-s1-5787684/tree-hugger-history-earth-day",
"https://www.cnn.com/2023/04/18/media/fox-dominion-settlement/index.html",
"https://www.irs.gov/",
"https://www.harvard.edu/",
"https://www.amazon.com/",
"https://www.bankofamerica.com/",
"https://www.cnn.com/videos/us/2023/04/18/jeremy-renner-snowplow-accident-bodycam-nc-melas-contd-vpx.cnn",
"https://www.chase.com/",
"https://www.target.com/",
"https://www.npr.org/2026/04/22/nx-s1-5791680/doj-disability-web-access-delay-schools",
"https://www.cnn.com/2023/04/17/opinions/us-tax-system-wealthy-disney-pearl/index.html",
"https://www.npr.org/2026/04/22/nx-s1-5791744/faa-dot-air-traffic-control-system-revamp",
"https://www.cnn.com/2023/04/18/politics/clarence-thomas-ethics-democrats/index.html",
"https://www.cnn.com/videos/travel/2023/04/18/century-old-shipwrecks-lake-superior-discovery-contd-orig-zt.cnn",
"https://www.cnn.com/2023/04/18/tech/lina-khan-ai-warning/index.html"
],
"static_urls": [
"https://www.usa.gov/",
"https://www.irs.gov/",
"https://www.cdc.gov/",
"https://www.harvard.edu/",
"https://www.chase.com/",
"https://www.bankofamerica.com/",
"https://www.amazon.com/",
"https://www.target.com/",
"https://www.walmart.com/",
"https://www.usps.com/"
]
}
}

View File

@@ -0,0 +1,50 @@
{
"region_name": "United States - Bend",
"google_module": {
"base_lat": 44.0582,
"base_lon": -121.3153,
"lang_params": "hl=en&gl=US",
"valid_url_suffix": "com"
},
"trust_module": {
"white_urls": [
"https://www.irs.gov/",
"https://www.cnn.com/2023/04/18/politics/clarence-thomas-ethics-democrats/index.html",
"https://www.cnn.com/videos/travel/2023/04/18/century-old-shipwrecks-lake-superior-discovery-contd-orig-zt.cnn",
"https://www.cnn.com/2023/04/18/media/fox-dominion-settlement/index.html",
"https://www.cdc.gov/",
"https://www.amazon.com/",
"https://www.npr.org/2026/04/22/nx-s1-5791744/faa-dot-air-traffic-control-system-revamp",
"https://www.cnn.com/2023/04/18/tech/lina-khan-ai-warning/index.html",
"https://www.cnn.com/2023/04/18/us/kansas-city-ralph-yarl-shooting-tuesday/index.html",
"https://www.harvard.edu/",
"https://www.usps.com/",
"https://www.target.com/",
"https://www.cnn.com/2023/04/18/us/mccurtain-county-oklahoma-officials-recording/index.html",
"https://www.chase.com/",
"https://www.walmart.com/",
"https://www.usa.gov/",
"https://www.npr.org/2026/04/22/nx-s1-5791680/doj-disability-web-access-delay-schools",
"https://www.cnn.com/audio/podcasts/the-assignment/episodes/42a2f0e2-066a-4675-82ff-afe2016a0bb5",
"https://www.cnn.com/2023/04/14/entertainment/barry-season-4-review/index.html",
"https://www.bankofamerica.com/",
"https://www.cnn.com/videos/us/2023/04/18/jeremy-renner-snowplow-accident-bodycam-nc-melas-contd-vpx.cnn",
"https://www.cnn.com/2023/04/17/health/rise-type-2-diabetes-global-wellness/index.html",
"https://www.cnn.com/2023/04/17/opinions/us-tax-system-wealthy-disney-pearl/index.html",
"https://www.npr.org/2026/04/22/nx-s1-5787684/tree-hugger-history-earth-day",
"https://www.cnn.com/videos/politics/2023/04/18/kevin-mccarthy-wall-street-speech-debt-ceiling-biden-economy-vpx.cnn"
],
"static_urls": [
"https://www.usa.gov/",
"https://www.irs.gov/",
"https://www.cdc.gov/",
"https://www.harvard.edu/",
"https://www.chase.com/",
"https://www.bankofamerica.com/",
"https://www.amazon.com/",
"https://www.target.com/",
"https://www.walmart.com/",
"https://www.usps.com/"
]
}
}

View File

@@ -0,0 +1,50 @@
{
"region_name": "United States - Salt Lake City",
"google_module": {
"base_lat": 40.7608,
"base_lon": -111.891,
"lang_params": "hl=en&gl=US",
"valid_url_suffix": "com"
},
"trust_module": {
"white_urls": [
"https://www.usps.com/",
"https://www.cnn.com/videos/us/2023/04/18/jeremy-renner-snowplow-accident-bodycam-nc-melas-contd-vpx.cnn",
"https://www.cnn.com/2023/04/14/entertainment/barry-season-4-review/index.html",
"https://www.cnn.com/2023/04/17/health/rise-type-2-diabetes-global-wellness/index.html",
"https://www.target.com/",
"https://www.cnn.com/2023/04/18/us/kansas-city-ralph-yarl-shooting-tuesday/index.html",
"https://www.bankofamerica.com/",
"https://www.walmart.com/",
"https://www.npr.org/2026/04/22/nx-s1-5787684/tree-hugger-history-earth-day",
"https://www.cnn.com/videos/politics/2023/04/18/kevin-mccarthy-wall-street-speech-debt-ceiling-biden-economy-vpx.cnn",
"https://www.cnn.com/2023/04/18/us/mccurtain-county-oklahoma-officials-recording/index.html",
"https://www.amazon.com/",
"https://www.chase.com/",
"https://www.cnn.com/audio/podcasts/the-assignment/episodes/42a2f0e2-066a-4675-82ff-afe2016a0bb5",
"https://www.npr.org/2026/04/22/nx-s1-5791680/doj-disability-web-access-delay-schools",
"https://www.npr.org/2026/04/22/nx-s1-5791744/faa-dot-air-traffic-control-system-revamp",
"https://www.cdc.gov/",
"https://www.cnn.com/2023/04/18/politics/clarence-thomas-ethics-democrats/index.html",
"https://www.irs.gov/",
"https://www.usa.gov/",
"https://www.cnn.com/videos/travel/2023/04/18/century-old-shipwrecks-lake-superior-discovery-contd-orig-zt.cnn",
"https://www.cnn.com/2023/04/18/media/fox-dominion-settlement/index.html",
"https://www.harvard.edu/",
"https://www.cnn.com/2023/04/18/tech/lina-khan-ai-warning/index.html",
"https://www.cnn.com/2023/04/17/opinions/us-tax-system-wealthy-disney-pearl/index.html"
],
"static_urls": [
"https://www.usa.gov/",
"https://www.irs.gov/",
"https://www.cdc.gov/",
"https://www.harvard.edu/",
"https://www.chase.com/",
"https://www.bankofamerica.com/",
"https://www.amazon.com/",
"https://www.target.com/",
"https://www.walmart.com/",
"https://www.usps.com/"
]
}
}

View File

@@ -0,0 +1,50 @@
{
"region_name": "United States - Seattle",
"google_module": {
"base_lat": 47.6062,
"base_lon": -122.3321,
"lang_params": "hl=en&gl=US",
"valid_url_suffix": "com"
},
"trust_module": {
"white_urls": [
"https://www.cnn.com/2023/04/18/us/mccurtain-county-oklahoma-officials-recording/index.html",
"https://www.usa.gov/",
"https://www.amazon.com/",
"https://www.cnn.com/2023/04/17/opinions/us-tax-system-wealthy-disney-pearl/index.html",
"https://www.bankofamerica.com/",
"https://www.target.com/",
"https://www.cnn.com/videos/travel/2023/04/18/century-old-shipwrecks-lake-superior-discovery-contd-orig-zt.cnn",
"https://www.cnn.com/videos/us/2023/04/18/jeremy-renner-snowplow-accident-bodycam-nc-melas-contd-vpx.cnn",
"https://www.cnn.com/2023/04/18/us/kansas-city-ralph-yarl-shooting-tuesday/index.html",
"https://www.cnn.com/2023/04/18/politics/clarence-thomas-ethics-democrats/index.html",
"https://www.npr.org/2026/04/22/nx-s1-5791680/doj-disability-web-access-delay-schools",
"https://www.walmart.com/",
"https://www.irs.gov/",
"https://www.npr.org/2026/04/22/nx-s1-5791744/faa-dot-air-traffic-control-system-revamp",
"https://www.cnn.com/2023/04/14/entertainment/barry-season-4-review/index.html",
"https://www.usps.com/",
"https://www.cnn.com/videos/politics/2023/04/18/kevin-mccarthy-wall-street-speech-debt-ceiling-biden-economy-vpx.cnn",
"https://www.cnn.com/2023/04/18/media/fox-dominion-settlement/index.html",
"https://www.cnn.com/2023/04/18/tech/lina-khan-ai-warning/index.html",
"https://www.harvard.edu/",
"https://www.chase.com/",
"https://www.npr.org/2026/04/22/nx-s1-5787684/tree-hugger-history-earth-day",
"https://www.cnn.com/audio/podcasts/the-assignment/episodes/42a2f0e2-066a-4675-82ff-afe2016a0bb5",
"https://www.cnn.com/2023/04/17/health/rise-type-2-diabetes-global-wellness/index.html",
"https://www.cdc.gov/"
],
"static_urls": [
"https://www.usa.gov/",
"https://www.irs.gov/",
"https://www.cdc.gov/",
"https://www.harvard.edu/",
"https://www.chase.com/",
"https://www.bankofamerica.com/",
"https://www.amazon.com/",
"https://www.target.com/",
"https://www.walmart.com/",
"https://www.usps.com/"
]
}
}

View File

@@ -0,0 +1,44 @@
{
"region_name": "Vietnam - Hanoi",
"google_module": {
"base_lat": 21.0285,
"base_lon": 105.8542,
"lang_params": "hl=vi&gl=VN",
"valid_url_suffix": "vn"
},
"trust_module": {
"white_urls": [
"https://vnexpress.net/",
"https://vnu.edu.vn/",
"https://vnexpress.net/dan-dai-bac-khai-hoa-trong-le-don-tong-thong-han-quoc-5065884.html",
"https://vnexpress.net/pvcfc-lap-ky-luc-doanh-thu-chia-co-tuc-tien-mat-20-5065565.html",
"https://vnexpress.net/fpt-academy-international-hop-tac-saolatek-dao-tao-drone-thuc-chien-5065838.html",
"https://vnexpress.net/duoc-uu-tien-mua-nha-o-xa-hoi-ban-se-sinh-du-hai-con-5065730.html",
"https://vnexpress.net/nguoi-ban-thit-cho-tu-vong-vi-benh-dai-5065876.html",
"https://chinhphu.vn/",
"https://vnexpress.net/cuon-sach-giup-nguoi-kinh-doanh-su-dung-va-khai-thac-du-lieu-5065768.html",
"https://vnexpress.net/diem-tin-17h-ong-pham-nhat-vuong-noi-ve-dinh-huong-xe-dien-ong-trump-gia-han-lenh-ngung-ban-voi-iran-5065842.html",
"https://shopee.vn/",
"https://vnexpress.net/gia-lai-giu-hon-60-ha-che-phuc-vu-du-lich-5065855.html",
"https://vnexpress.net/iran-tuyen-bo-bat-giu-hai-tau-hang-tim-cach-qua-eo-bien-hormuz-5065867.html",
"https://vnexpress.net/chu-tich-yeah1-chung-toi-khong-bo-tien-de-mua-doanh-thu-5065727.html",
"https://www.vietcombank.com.vn/",
"https://vnexpress.net/ceo-vpbank-lai-suat-co-the-ha-nhiet-tu-cuoi-quy-ii-5065790.html",
"https://tiki.vn/",
"https://vnexpress.net/mua-da-30-phut-tren-dinh-fansipan-5065886.html",
"https://dichvucong.gov.vn/",
"https://vnexpress.net/mb-tang-loa-thanh-toan-mien-phi-5-nam-cho-ho-kinh-doanh-5064445.html",
"https://vnexpress.net/carlsberg-viet-nam-5-nam-dong-hanh-vnexpress-marathon-hue-5065799.html",
"https://vnexpress.net/thu-tuong-yeu-cau-tang-ty-trong-chi-phat-trien-cong-nghe-loi-5065878.html"
],
"static_urls": [
"https://chinhphu.vn/",
"https://dichvucong.gov.vn/",
"https://vnu.edu.vn/",
"https://www.vietcombank.com.vn/",
"https://shopee.vn/",
"https://tiki.vn/",
"https://vnexpress.net/"
]
}
}

View File

@@ -1,64 +1,114 @@
#!/bin/bash
# ==========================================================
# 脚本名称: install_master.sh (IP-Sentinel 控制中枢部署脚本 v3.2.3)
# 脚本名称: install_master.sh (IP-Sentinel 控制中枢部署脚本 - 动态锚点版)
# 核心功能: 部署/卸载调度中枢、SQLite 资产管理、平滑热更新引擎
# ==========================================================
# [新增] 提取仓库直链前缀变量,方便后续在官方库和私库间一键切换
# ==========================================================
# 🛑 核心权限防线: 检查是否以 root 权限运行
# ==========================================================
if [ "$EUID" -ne 0 ]; then
echo -e "\033[31m❌ 权限被拒绝: 部署 IP-Sentinel 需要最高系统权限。\033[0m"
echo -e "💡 请切换到 root 用户 (执行 su root 或 sudo -i) 后重新运行指令。"
exit 1
fi
# 你的 GitHub 仓库 Raw 数据直链前缀
REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main"
# 临时改为私库地址用于测试
# REPO_RAW_URL="https://git.94211762.xyz/hotyue/IP-Sentinel/raw/branch/main"
# 临时改为开发地址用于测试
# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/v3.6.2-rc"
# [核心: 动态提取 Master 专属版本锚点 (KV 解析法)]
# 通过 grep 定位 MASTER_VERSION 行,再通过 cut 提取等号右侧的值
TARGET_VERSION=$(curl -s -m 3 "${REPO_RAW_URL}/version.txt" | grep "^MASTER_VERSION=" | cut -d'=' -f2 | tr -d '[:space:]')
# 🛡️ 兜底防线:如果网络波动拉取失败,启用内置的安全兜底版本
TARGET_VERSION=${TARGET_VERSION:-"3.5.0"}
MASTER_DIR="/opt/ip_sentinel_master"
DB_FILE="${MASTER_DIR}/sentinel.db"
echo "========================================================"
# [修改] 将欢迎语改为更通用的文案,因为现在不仅能部署,还能卸载
echo " 🧠 欢迎使用 IP-Sentinel Master (控制中枢) v3.2.2"
echo " 🧠 欢迎使用 IP-Sentinel Master (控制中枢) v${TARGET_VERSION}"
echo "========================================================"
# [新增] 交互式操作菜单:支持选择部署或调用卸载程序
echo -e "\n请选择操作:"
echo " 1) 🚀 部署 Master 控制中枢"
echo " 2) 🗑️ 一键卸载 Master 中枢"
read -p "请输入选择 [1-2] (默认1): " ACTION_CHOICE
if [ "$ACTION_CHOICE" == "2" ]; then
echo -e "\n⏳ 正在拉取卸载程序..."
# [新增逻辑] 使用上面定义的 REPO_RAW_URL 动态拉取卸载脚本,执行后自动销毁临时文件
curl -sL "${REPO_RAW_URL}/master/uninstall_master.sh" -o "/tmp/uninstall_master.sh"
chmod +x "/tmp/uninstall_master.sh"
bash "/tmp/uninstall_master.sh"
rm -f "/tmp/uninstall_master.sh"
exit 0
fi
# ================== [v3.2.2 新增: 平滑升级模式嗅探] ==================
UPGRADE_MODE="false"
KEEP_DB="true"
if [ "$ACTION_CHOICE" == "1" ] && [ -f "${MASTER_DIR}/master.conf" ]; then
echo -e "\n\033[33m💡 司令部雷达提示:检测到本机已部署过 Master 中枢。\033[0m"
read -p "👉 是否按原配置直接进行平滑升级?(y/n, 默认y): " UPGRADE_CHOICE
if [[ -z "$UPGRADE_CHOICE" || "$UPGRADE_CHOICE" =~ ^[Yy]$ ]]; then
UPGRADE_MODE="true"
read -p "👉 是否保留历史节点数据库 (SQLite)(y/n, 默认y): " DB_CHOICE
if [[ "$DB_CHOICE" =~ ^[Nn]$ ]]; then
KEEP_DB="false"
fi
# 汲取原配置进入内存
# ==========================================================
# [v3.6.1 核心] 拦截司令部静默 OTA 升级模式 (强行接管执行流)
# ==========================================================
if [ "$SILENT_MASTER_OTA" == "true" ]; then
echo -e "\n⏳ [OTA] 中枢重构指令已确认,正在剥离控制台交互..."
ACTION_CHOICE=1
UPGRADE_MODE="true"
KEEP_DB="true"
# 汲取原配置进入内存
if [ -f "${MASTER_DIR}/master.conf" ]; then
source "${MASTER_DIR}/master.conf"
echo -e "\033[32m✅ 已激活 [平滑升级模式],即将跳过基础配置,直接更新核心中枢...\033[0m"
else
echo -e "\033[33m🔄 您选择了重新配置,旧的中枢数据将被彻底抹除。\033[0m"
# 同步新版本号至配置文件
if grep -q "^MASTER_VERSION=" "${MASTER_DIR}/master.conf"; then
sed -i "s/^MASTER_VERSION=.*/MASTER_VERSION=\"$TARGET_VERSION\"/" "${MASTER_DIR}/master.conf"
else
echo "MASTER_VERSION=\"$TARGET_VERSION\"" >> "${MASTER_DIR}/master.conf"
fi
fi
echo -e "\033[32m✅ 已激活 [中枢静默重构模式],即将无损覆写内核...\033[0m"
else
# [新增] 交互式操作菜单:支持选择部署或调用卸载程序
echo -e "\n请选择操作:"
echo " 1) 🚀 部署 Master 控制中枢"
echo " 2) 🗑️ 一键卸载 Master 中枢"
read -p "请输入选择 [1-2] (默认1): " ACTION_CHOICE
# [v3.5.2 修复] 防止用户直接回车导致变量为空,从而漏过下方的平滑升级判定被误删档
ACTION_CHOICE=${ACTION_CHOICE:-1}
if [ "$ACTION_CHOICE" == "2" ]; then
echo -e "\n⏳ 正在拉取卸载程序..."
curl -sL "${REPO_RAW_URL}/master/uninstall_master.sh" -o "/tmp/uninstall_master.sh"
chmod +x "/tmp/uninstall_master.sh"
bash "/tmp/uninstall_master.sh"
rm -f "/tmp/uninstall_master.sh"
exit 0
fi
# ================== [v3.2.2 新增: 平滑升级模式嗅探] ==================
UPGRADE_MODE="false"
KEEP_DB="true"
if [ "$ACTION_CHOICE" == "1" ] && [ -f "${MASTER_DIR}/master.conf" ]; then
echo -e "\n\033[33m💡 司令部雷达提示:检测到本机已部署过 Master 中枢。\033[0m"
read -p "👉 是否按原配置直接进行平滑升级?(y/n, 默认y): " UPGRADE_CHOICE
if [[ -z "$UPGRADE_CHOICE" || "$UPGRADE_CHOICE" =~ ^[Yy]$ ]]; then
UPGRADE_MODE="true"
read -p "👉 是否保留历史节点数据库 (SQLite)(y/n, 默认y): " DB_CHOICE
if [[ "$DB_CHOICE" =~ ^[Nn]$ ]]; then
KEEP_DB="false"
fi
source "${MASTER_DIR}/master.conf"
if grep -q "^MASTER_VERSION=" "${MASTER_DIR}/master.conf"; then
sed -i "s/^MASTER_VERSION=.*/MASTER_VERSION=\"$TARGET_VERSION\"/" "${MASTER_DIR}/master.conf"
else
echo "MASTER_VERSION=\"$TARGET_VERSION\"" >> "${MASTER_DIR}/master.conf"
fi
echo -e "\033[32m✅ 已激活 [平滑升级模式],版本已锚定为 v${TARGET_VERSION}...\033[0m"
else
echo -e "\033[33m🔄 您选择了重新配置,旧的中枢数据将被彻底抹除。\033[0m"
fi
fi
fi
# ====================================================================
# ================== [v3.2.2 优化: 安装前环境纯净度清理与数据保护] ==================
echo -e "\n⏳ 正在清理旧版 Master 守护进程..."
# [新增] 优雅停止 Systemd 服务,防止代码替换时引发无限复活风暴
if command -v systemctl >/dev/null 2>&1; then
systemctl stop ip-sentinel-master.service >/dev/null 2>&1 || true
fi
pkill -9 -f "tg_master.sh" >/dev/null 2>&1 || true
if [ "$UPGRADE_MODE" == "true" ]; then
@@ -77,14 +127,67 @@ fi
echo -e "\033[32m✅ 旧进程已肃清!\033[0m"
# =======================================================================
# 1. 环境依赖安装
echo -e "\n[1/4] 安装核心依赖 (curl, jq, sqlite3)..."
if [ -f /etc/debian_version ]; then
apt-get update -y >/dev/null 2>&1
apt-get install -y curl jq sqlite3 procps >/dev/null 2>&1
elif [ -f /etc/redhat-release ]; then
yum install -y curl jq sqlite >/dev/null 2>&1
# 1. 依赖检查与智能安装 (v3.6.0 兼容性与优雅性升级)
echo -e "\n[1/4] 正在探测核心依赖 (curl, jq, sqlite3, crontab, pgrep)..."
REQUIRED_CMDS=("curl" "jq" "sqlite3" "crontab" "pgrep")
MISSING_CMDS=()
# 基础探测:预检查缺失的命令
for cmd in "${REQUIRED_CMDS[@]}"; do
if ! command -v "$cmd" >/dev/null 2>&1; then
MISSING_CMDS+=("$cmd")
fi
done
# 如果有缺失,才执行包管理器拉取逻辑
if [ ${#MISSING_CMDS[@]} -gt 0 ]; then
echo "⏳ 发现缺失依赖: ${MISSING_CMDS[*]},正在尝试自动补齐..."
if command -v apt-get >/dev/null 2>&1; then
apt-get update -y >/dev/null 2>&1
# [v3.6.3 抽脂级优化] 注入 --no-install-recommends 拒绝捆绑销售
apt-get install -y --no-install-recommends curl jq sqlite3 cron procps >/dev/null 2>&1
systemctl enable cron >/dev/null 2>&1 && systemctl start cron >/dev/null 2>&1
elif command -v yum >/dev/null 2>&1 || command -v dnf >/dev/null 2>&1; then
PKG_MGR="yum"
OPT_ARGS=""
if command -v dnf >/dev/null 2>&1; then
PKG_MGR="dnf"
# [v3.6.3 抽脂级优化] 强行关闭 DNF 的弱依赖拉取
OPT_ARGS="--setopt=install_weak_deps=False"
fi
$PKG_MGR install -y $OPT_ARGS curl jq sqlite cronie procps-ng >/dev/null 2>&1
systemctl enable crond >/dev/null 2>&1 && systemctl start crond >/dev/null 2>&1
elif command -v apk >/dev/null 2>&1; then
echo "Alpine 探测到系统类型为 Alpine Linux正在执行轻量级安装..."
apk add --no-cache curl jq sqlite dcron procps bash >/dev/null 2>&1
mkdir -p /var/spool/cron/crontabs
rc-update add crond default >/dev/null 2>&1
service crond start >/dev/null 2>&1
elif command -v pacman >/dev/null 2>&1; then
pacman -Sy --noconfirm curl jq sqlite cronie procps-ng >/dev/null 2>&1
mkdir -p /root/.cache/crontab 2>/dev/null
systemctl enable cronie >/dev/null 2>&1 && systemctl start cronie >/dev/null 2>&1
else
echo -e "\033[31m❌ 自动安装失败:系统未知的包管理器。\033[0m"
echo -e "\033[33m⚠ 请手动执行以下安装命令后重新运行本脚本:\033[0m"
echo -e " Debian/Ubuntu: \033[36mapt-get update && apt-get install -y --no-install-recommends curl jq sqlite3 cron procps\033[0m"
echo -e " CentOS/RHEL: \033[36myum install -y curl jq sqlite cronie procps-ng\033[0m"
echo -e " Alpine Linux: \033[36mapk add --no-cache curl jq sqlite dcron procps bash\033[0m"
exit 1
fi
# 安装后二次复检
for cmd in "${REQUIRED_CMDS[@]}"; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo -e "\033[31m❌ 致命错误:核心命令 '$cmd' 仍未找到!\033[0m"
echo -e "请手动修复您的包管理器源,或联系 VPS 供应商。"
exit 1
fi
done
fi
echo -e "\033[32m✅ 基础环境检测通过。\033[0m"
mkdir -p "$MASTER_DIR"
@@ -95,16 +198,58 @@ if [ "$UPGRADE_MODE" == "false" ]; then
# 2. 交互配置机器人
echo -e "\n[2/4] 配置控制中枢机器人:"
read -p "请输入 Telegram Bot Token: " TG_TOKEN
# [v3.6.0 新增] 官方网关模式选项 (用于屏蔽全局 OTA 按钮)
echo -e "\n请选择您的部署环境身份:"
echo " 1) 🛡️ 私有独立中枢 (默认推荐,保留完整 OTA 遥控权限)"
echo " 2) ☁️ 官方公共网关 (面向大众服务,将强制物理隐藏全局 OTA 按钮防滥用)"
read -p "请输入选择 [1-2] (默认1): " GATEWAY_TYPE
GATEWAY_TYPE=${GATEWAY_TYPE:-1}
IS_OFFICIAL_GATEWAY="false"
ENABLE_MASTER_OTA="false"
if [ "$GATEWAY_TYPE" == "2" ]; then
IS_OFFICIAL_GATEWAY="true"
echo -e "\033[33m⚠ 已开启官方公共网关模式,全舰队与司令部的 OTA 将被强制屏蔽。\033[0m"
else
# [v3.6.1] 私有模式开放中枢 OTA 授权向导
echo -e "\n[2.1/4] 司令部自我进化授权"
echo -e "💡 开启后,您可以在 TG 菜单一键将中枢核心系统热更新至最新版本。"
read -p "是否允许司令部接收 OTA 重构指令?(y/n, 默认y): " M_OTA_CHOICE
if [[ "$M_OTA_CHOICE" =~ ^[Nn]$ ]]; then
ENABLE_MASTER_OTA="false"
echo -e "🛡️ \033[33m已关闭司令部 OTA 权限,中枢内核未来仅支持 SSH 升级。\033[0m"
else
ENABLE_MASTER_OTA="true"
echo -e "✅ \033[32m已开启司令部 OTA 权限,金蝉脱壳引信已挂载。\033[0m"
fi
fi
cat > "${MASTER_DIR}/master.conf" << EOF
# IP-Sentinel Master 本地固化配置 (v${TARGET_VERSION})
MASTER_VERSION="$TARGET_VERSION"
TG_TOKEN="$TG_TOKEN"
DB_FILE="$DB_FILE"
MASTER_DIR="$MASTER_DIR"
# [v3.6.0 核心] 官方网关 UI 熔断标识
IS_OFFICIAL_GATEWAY="$IS_OFFICIAL_GATEWAY"
# [v3.6.1 新增] 司令部自身 OTA 授权标识
ENABLE_MASTER_OTA="$ENABLE_MASTER_OTA"
EOF
fi
# [v3.6.1 热修复] 老司令部平滑升级时,自动补齐缺失字段
if [ "$UPGRADE_MODE" == "true" ]; then
if ! grep -q "^IS_OFFICIAL_GATEWAY=" "${MASTER_DIR}/master.conf"; then
echo "IS_OFFICIAL_GATEWAY=\"false\"" >> "${MASTER_DIR}/master.conf"
fi
if ! grep -q "^ENABLE_MASTER_OTA=" "${MASTER_DIR}/master.conf"; then
echo "ENABLE_MASTER_OTA=\"false\"" >> "${MASTER_DIR}/master.conf"
fi
fi
# 🛑 拦截块结束
# 3. 初始化 SQLite 数据库 (幂等操作,升级模式下可安全修补表结构)
# 3. 初始化 SQLite 数据库 (幂等操作,升级模式下由 tg_master.sh 负责热修补)
echo -e "\n[3/4] 正在初始化 SQLite 数据库表结构..."
sqlite3 "$DB_FILE" <<EOF
CREATE TABLE IF NOT EXISTS nodes (
@@ -113,6 +258,11 @@ CREATE TABLE IF NOT EXISTS nodes (
agent_ip TEXT,
agent_port TEXT,
last_seen DATETIME DEFAULT CURRENT_TIMESTAMP,
region TEXT DEFAULT 'UNKNOWN',
node_alias TEXT,
enable_google TEXT DEFAULT 'true',
enable_trust TEXT DEFAULT 'true',
enable_ota TEXT DEFAULT 'false',
PRIMARY KEY(chat_id, node_name)
);
EOF
@@ -129,20 +279,64 @@ echo -e "\n[4/4] 部署 TG 调度守护进程..."
curl -sL "${REPO_RAW_URL}/master/tg_master.sh" -o "${MASTER_DIR}/tg_master.sh"
chmod +x "${MASTER_DIR}/tg_master.sh"
# 写入看门狗 Cron
crontab -l 2>/dev/null | grep -v "tg_master.sh" > /tmp/cron_master
echo "* * * * * pgrep -f tg_master.sh >/dev/null || nohup bash ${MASTER_DIR}/tg_master.sh >/dev/null 2>&1 &" >> /tmp/cron_master
crontab /tmp/cron_master
rm -f /tmp/cron_master
if command -v systemctl >/dev/null 2>&1; then
echo "💡 检测到 Systemd 环境,正在部署原生守护服务..."
cat > /etc/systemd/system/ip-sentinel-master.service << EOF
[Unit]
Description=IP-Sentinel Master Command Center Service
After=network.target
# 立刻启动
pgrep -f tg_master.sh >/dev/null || nohup bash "${MASTER_DIR}/tg_master.sh" >/dev/null 2>&1 &
[Service]
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
SyslogIdentifier=ip-sentinel
Type=simple
ExecStart=/bin/bash ${MASTER_DIR}/tg_master.sh
Restart=always
RestartSec=5
User=root
WorkingDirectory=${MASTER_DIR}
CPUSchedulingPolicy=idle
IOSchedulingClass=idle
# ================== [v3.2.2 优化: 战报文案分流] ==================
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now ip-sentinel-master.service
systemctl restart ip-sentinel-master.service
# 清理可能残留的历史 Cron
crontab -l 2>/dev/null | grep -v "tg_master.sh" > /tmp/cron_master || true
[ -f /tmp/cron_master ] && crontab /tmp/cron_master 2>/dev/null
rm -f /tmp/cron_master
else
echo "💡 未检测到 Systemd回退到 Cron 看门狗调度模式..."
crontab -l 2>/dev/null | grep -v "tg_master.sh" > /tmp/cron_master || true
echo "* * * * * pgrep -f tg_master.sh >/dev/null || nohup bash ${MASTER_DIR}/tg_master.sh >/dev/null 2>&1 &" >> /tmp/cron_master
[ -f /tmp/cron_master ] && crontab /tmp/cron_master 2>/dev/null
rm -f /tmp/cron_master
pgrep -f tg_master.sh >/dev/null || { nohup bash "${MASTER_DIR}/tg_master.sh" >/dev/null 2>&1 & disown 2>/dev/null; }
fi
# ================== [v3.2.2 优化 & v3.6.1 OTA捷报: 战报文案分流] ==================
echo "========================================================"
if [ "$UPGRADE_MODE" == "true" ]; then
echo "🎉 Master 控制中枢平滑热更新完成!"
echo "🤖 新版中枢引擎已接管数据库,继续等待边缘节点汇报。"
# [v3.6.1 核心] 静默 OTA 完成后,由幽灵进程主动向指挥官发送捷报
if [ "$SILENT_MASTER_OTA" == "true" ] && [ -n "$OTA_CHAT_ID" ] && [ -n "$TG_TOKEN" ]; then
echo -e "\n📡 正在向指挥官发送司令部重构捷报..."
curl -s -X POST "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
-d "chat_id=${OTA_CHAT_ID}" \
-d "parse_mode=Markdown" \
-d "text=✨ *司令部中枢热重载完成!*
🚀 当前内核已跃升至:\`v${TARGET_VERSION}\`
🤖 新版金蝉脱壳引擎已接管阵地,全舰队指控链路恢复正常。" > /dev/null
fi
else
echo "🎉 Master 控制中枢部署完成!"
echo "🤖 机器人现已开始全局接客,等待边缘节点注册。"

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# ==========================================================
# 脚本名称: tg_master.sh (Master 端调度枢纽 V3.0.4 动态签名版)
# 脚本名称: tg_master.sh (Master 端调度枢纽 - 动态锚点版)
# 核心功能: 监听 TG、操作 SQLite、Webhook 精准调度、403权限拦截、僵尸节点清理
# ==========================================================
@@ -9,30 +9,45 @@ CONF="/opt/ip_sentinel_master/master.conf"
[ ! -f "$CONF" ] && exit 1
source "$CONF"
# [核心: 运行态版本继承与云通信地址]
REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main"
# 临时改为开发地址用于测试
# REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/v3.6.2-rc"
# MASTER_VERSION 已经在上方的 source "$CONF" 中被载入
# 如果本地极度陈旧没有该变量,才给定一个基础兜底值,避免变量为空导致崩溃
MASTER_VERSION=${MASTER_VERSION:-"3.5.0"}
OFFSET_FILE="${MASTER_DIR}/.tg_offset"
[[ -f $OFFSET_FILE ]] || echo "0" > $OFFSET_FILE
# --- 工具函数 ---
send_ui() {
curl -s -X POST "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
curl -s --connect-timeout 5 -m 10 -X POST "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
-H "Content-Type: application/json" \
-d "{\"chat_id\":\"$1\",\"text\":\"$2\",\"parse_mode\":\"Markdown\",\"reply_markup\":{\"inline_keyboard\":$3}}" > /dev/null
}
send_msg() {
curl -s -X POST "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
curl -s --connect-timeout 5 -m 10 -X POST "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
-d "chat_id=$1" -d "text=$2" -d "parse_mode=Markdown" > /dev/null
}
# ================== [v3.0.1 新增: 消息原位刷新函数] ==================
edit_msg() {
curl -s -X POST "https://api.telegram.org/bot${TG_TOKEN}/editMessageText" \
curl -s --connect-timeout 5 -m 10 -X POST "https://api.telegram.org/bot${TG_TOKEN}/editMessageText" \
-d "chat_id=$1" -d "message_id=$2" -d "text=$3" -d "parse_mode=Markdown" > /dev/null
}
# 数据库执行函数
# [v3.5.3 新增: 支持内联键盘的原位 UI 重绘函数]
edit_ui() {
curl -s --connect-timeout 5 -m 10 -X POST "https://api.telegram.org/bot${TG_TOKEN}/editMessageText" \
-H "Content-Type: application/json" \
-d "{\"chat_id\":\"$1\",\"message_id\":\"$2\",\"text\":\"$3\",\"parse_mode\":\"Markdown\",\"reply_markup\":{\"inline_keyboard\":$4}}" > /dev/null
}
# 数据库执行函数 (v3.6.3 终极静默版: 动用 .timeout 点命令防泄露)
db_exec() {
sqlite3 "$DB_FILE" "$1"
printf ".timeout 5000\n%s\n" "$1" | sqlite3 "$DB_FILE"
}
# ================== [v3.0.4 核心: 动态 HMAC 签名生成器] ==================
@@ -50,19 +65,28 @@ generate_signed_url() {
local signature=$(echo -n "$payload" | openssl dgst -sha256 -hmac "$CHAT_ID" | awk '{print $NF}')
# 返回最终带签名的 URL
echo "http://${target_ip}:${target_port}${action_path}?t=${current_t}&sign=${signature}"
echo "https://${target_ip}:${target_port}${action_path}?t=${current_t}&sign=${signature}"
}
# ========================================================================
# ================== [v3.1.3 核心: 数据库结构无损热升级] ==================
# 自动探测并增加 region 字段,屏蔽已存在的报错,保护老节点数据
# ================== [v3.6.3 核心: 激活 SQLite 高并发 WAL 引擎] ==================
db_exec "PRAGMA journal_mode=WAL;" > /dev/null 2>&1
db_exec "PRAGMA synchronous=NORMAL;" > /dev/null 2>&1
# ==============================================================================
# ================== [v3.1.3-v3.6.0 核心: 数据库结构无损热升级] ==================
# 自动探测并增加缺失字段,屏蔽已存在的报错,保护老节点数据
db_exec "ALTER TABLE nodes ADD COLUMN region TEXT DEFAULT 'UNKNOWN';" 2>/dev/null
db_exec "ALTER TABLE nodes ADD COLUMN node_alias TEXT;" 2>/dev/null
db_exec "ALTER TABLE nodes ADD COLUMN enable_google TEXT DEFAULT 'true';" 2>/dev/null
db_exec "ALTER TABLE nodes ADD COLUMN enable_trust TEXT DEFAULT 'true';" 2>/dev/null
db_exec "ALTER TABLE nodes ADD COLUMN enable_ota TEXT DEFAULT 'false';" 2>/dev/null
# ========================================================================
# --- 核心轮询循环 ---
while true; do
OFFSET=$(cat $OFFSET_FILE)
UPDATES=$(curl -s "https://api.telegram.org/bot${TG_TOKEN}/getUpdates?offset=${OFFSET}&timeout=30")
UPDATES=$(curl -s --connect-timeout 5 -m 35 "https://api.telegram.org/bot${TG_TOKEN}/getUpdates?offset=${OFFSET}&timeout=30")
COUNT=$(echo "$UPDATES" | jq -r '.result | length' 2>/dev/null)
@@ -73,6 +97,23 @@ while true; do
CHAT_ID=$(echo "$UPDATE" | jq -r '.message.chat.id // .callback_query.message.chat.id')
TEXT=$(echo "$UPDATE" | jq -r '.message.text // .callback_query.data')
REPLY_TO_TEXT=$(echo "$UPDATE" | jq -r '.message.reply_to_message.text // empty')
# ================== [v3.5.2 新增: 拦截别名修改的对话回复] ==================
if [[ "$REPLY_TO_TEXT" == *"✏️ 请回复本消息以重命名节点:"* ]]; then
# 精准提取被回复消息中的节点主键名
TARGET_NODE=$(echo "$REPLY_TO_TEXT" | grep -v "✏️" | grep -v "仅限" | tr -d '\` ' | tr -cd 'a-zA-Z0-9_.-' | head -n 1)
# [v3.5.2 热修复] 废除 Bash 原生 tr 命令的中文白名单 (不支持 Unicode 会误删中文)。
# 改用黑名单策略:仅自动转化下划线,剔除引号、特殊符号和冒号(防止破坏内部路由)
# 将完整的中文原样送入 Base64 编码,最终严格正则清洗交由 Agent 的 Python 引擎处理!
NEW_ALIAS=$(echo "$TEXT" | sed 's/_/-/g' | tr -d '"'\''\`\$\|&;<>\n\r:' | cut -c 1-30)
if [ -n "$TARGET_NODE" ] && [ -n "$NEW_ALIAS" ]; then
# 强行重写内部路由
TEXT="do_rename:${TARGET_NODE}:${NEW_ALIAS}"
fi
fi
# ================== [v3.0.1 新增: 消除转圈圈与获取消息ID] ==================
CB_ID=$(echo "$UPDATE" | jq -r '.callback_query.id // empty')
@@ -80,7 +121,7 @@ while true; do
# 告诉 TG 官方“指令已收到”,立刻消除按钮上的加载圈圈
if [ -n "$CB_ID" ]; then
curl -s -X POST "https://api.telegram.org/bot${TG_TOKEN}/answerCallbackQuery" -d "callback_query_id=${CB_ID}" > /dev/null
curl -s --connect-timeout 5 -m 10 -X POST "https://api.telegram.org/bot${TG_TOKEN}/answerCallbackQuery" -d "callback_query_id=${CB_ID}" > /dev/null
fi
# ==========================================
@@ -89,21 +130,34 @@ while true; do
if [[ "$TEXT" == *"#REGISTER#"* ]]; then
REG_LINE=$(echo "$TEXT" | grep "#REGISTER#" | head -n 1 | tr -d '\` ')
# V3.1.3 兼容性拆包: 判断是新版协议 (5个字段) 还是老版协议 (4个字段)
# V3.6.0 兼容性拆包: 支持 7字段(OTA)、6字段(双轨)、5字段(单轨)、4字段(远古)
FIELD_COUNT=$(echo "$REG_LINE" | awk -F'|' '{print NF}')
if [ "$FIELD_COUNT" -ge 5 ]; then
if [ "$FIELD_COUNT" -ge 7 ]; then
IFS='|' read -r MAGIC RAW_REGION RAW_NODE RAW_IP RAW_PORT RAW_ALIAS RAW_OTA <<< "$REG_LINE"
elif [ "$FIELD_COUNT" -eq 6 ]; then
IFS='|' read -r MAGIC RAW_REGION RAW_NODE RAW_IP RAW_PORT RAW_ALIAS <<< "$REG_LINE"
RAW_OTA="false"
elif [ "$FIELD_COUNT" -eq 5 ]; then
IFS='|' read -r MAGIC RAW_REGION RAW_NODE RAW_IP RAW_PORT <<< "$REG_LINE"
RAW_ALIAS="$RAW_NODE"
RAW_OTA="false"
else
IFS='|' read -r MAGIC RAW_NODE RAW_IP RAW_PORT <<< "$REG_LINE"
RAW_REGION="UNKNOWN"
RAW_ALIAS="$RAW_NODE"
RAW_OTA="false"
fi
# 🛡️ 强制字符白名单过滤:保留历史特征不变
CHAT_ID=$(echo "$CHAT_ID" | tr -cd '0-9-')
AGENT_REGION=$(echo "$RAW_REGION" | tr -cd 'a-zA-Z0-9' | cut -c 1-10) # 提取国家大区
AGENT_REGION=$(echo "$RAW_REGION" | tr -cd 'a-zA-Z0-9' | cut -c 1-10)
NODE_NAME=$(echo "$RAW_NODE" | tr -cd 'a-zA-Z0-9_.-' | cut -c 1-30)
AGENT_IP=$(echo "$RAW_IP" | tr -cd 'a-zA-Z0-9.:\[\]-' | cut -c 1-50)
AGENT_PORT=$(echo "$RAW_PORT" | tr -cd '0-9' | cut -c 1-5)
NODE_ALIAS=$(echo "$RAW_ALIAS" | tr -d '"'\''\`\$\|&;<>\n\r' | cut -c 1-30)
[ -z "$NODE_ALIAS" ] && NODE_ALIAS="$NODE_NAME"
AGENT_OTA=$(echo "$RAW_OTA" | tr -cd 'a-z')
[ -z "$AGENT_OTA" ] && AGENT_OTA="false"
if [[ "$AGENT_IP" =~ ^127\.|^10\.|^192\.168\.|^172\.(1[6-9]|2[0-9]|3[0-1])\.|^::1$|^localhost$ ]]; then
send_msg "$CHAT_ID" "⛔ **安全拦截**:禁止注册内网或回环 IP防止 SSRF 攻击渗透。"
@@ -115,9 +169,9 @@ while true; do
continue
fi
# 入库时追加 region 字段
db_exec "INSERT INTO nodes (chat_id, node_name, agent_ip, agent_port, last_seen, region) VALUES ('$CHAT_ID', '$NODE_NAME', '$AGENT_IP', '$AGENT_PORT', CURRENT_TIMESTAMP, '$AGENT_REGION') ON CONFLICT(chat_id, node_name) DO UPDATE SET agent_ip='$AGENT_IP', agent_port='$AGENT_PORT', last_seen=CURRENT_TIMESTAMP, region='$AGENT_REGION';"
send_msg "$CHAT_ID" "✅ 司令部确认!节点接入成功: \`$NODE_NAME\` ($AGENT_IP:$AGENT_PORT)"
# [核心] 入库时追加 node_alias 与 enable_ota 字段
db_exec "INSERT INTO nodes (chat_id, node_name, agent_ip, agent_port, last_seen, region, node_alias, enable_ota) VALUES ('$CHAT_ID', '$NODE_NAME', '$AGENT_IP', '$AGENT_PORT', CURRENT_TIMESTAMP, '$AGENT_REGION', '$NODE_ALIAS', '$AGENT_OTA') ON CONFLICT(chat_id, node_name) DO UPDATE SET agent_ip='$AGENT_IP', agent_port='$AGENT_PORT', last_seen=CURRENT_TIMESTAMP, region='$AGENT_REGION', node_alias='$NODE_ALIAS', enable_ota='$AGENT_OTA';"
send_msg "$CHAT_ID" "**司令部确认 (v${MASTER_VERSION})**%0A节点 \`${NODE_ALIAS}\` 档案已录入!"
# ================== [v3.1.3 丝滑连招: 直接呼出全球大区雷达] ==================
REGION_DATA=$(db_exec "SELECT region, COUNT(*) FROM nodes WHERE chat_id='$CHAT_ID' GROUP BY region;")
@@ -129,6 +183,8 @@ while true; do
case "$REGION_NAME" in
"US") FLAG="🇺🇸" ;; "JP") FLAG="🇯🇵" ;; "HK") FLAG="🇭🇰" ;;
"SG") FLAG="🇸🇬" ;; "UK"|"GB") FLAG="🇬🇧" ;; "DE") FLAG="🇩🇪" ;; "FR") FLAG="🇫🇷" ;;
"CA") FLAG="🇨🇦" ;; "AU") FLAG="🇦🇺" ;; "KR") FLAG="🇰🇷" ;; "NL") FLAG="🇳🇱" ;;
"BR") FLAG="🇧🇷" ;; "IN") FLAG="🇮🇳" ;; "TW") FLAG="🇹🇼" ;;
esac
BTNS="$BTNS[{\"text\":\"$FLAG $REGION_NAME ($NODE_COUNT 台)\",\"callback_data\":\"region:$REGION_NAME\"}],"
done <<< "$REGION_DATA"
@@ -145,8 +201,97 @@ while true; do
# ==========================================
case "$TEXT" in
"/start"|"/menu")
BTNS="[[{\"text\":\"🖥️ 我的节点列表\",\"callback_data\":\"list_nodes\"}], [{\"text\":\"🚀 全节点日报汇总\",\"callback_data\":\"all_reports\"}], [{\"text\":\"🛠️ 全节点一键维护\",\"callback_data\":\"all_run\"}]]"
send_ui "$CHAT_ID" "🛡️ **IP-Sentinel 司令部**\n欢迎回来长官。请下达指令" "$BTNS"
# [核心: 抓取云端最新 Master 版本 (KV 解析法)]
REMOTE_VER=$(curl -s -m 2 "${REPO_RAW_URL}/version.txt" | grep "^MASTER_VERSION=" | cut -d'=' -f2 | tr -d '[:space:]')
VER_INFO="当前版本: \`v${MASTER_VERSION}\`"
BTN_MASTER_OTA=""
if [ -n "$REMOTE_VER" ] && [ "$REMOTE_VER" != "$MASTER_VERSION" ]; then
VER_INFO="${VER_INFO}\n✨ **发现新版本**: \`v${REMOTE_VER}\` (可执行中枢热重载)"
# 仅当非官方网关 且 开启了中枢 OTA 权限时,才渲染升级按钮
if [ "$IS_OFFICIAL_GATEWAY" != "true" ] && [ "${ENABLE_MASTER_OTA:-false}" == "true" ]; then
BTN_MASTER_OTA="[{\"text\":\"🆙 升级司令部至 v${REMOTE_VER}\",\"callback_data\":\"master_ota_confirm\"}],"
fi
fi
NODE_COUNT=$(db_exec "SELECT COUNT(*) FROM nodes WHERE chat_id='$CHAT_ID';")
[ -z "$NODE_COUNT" ] && NODE_COUNT=0
# L0 扁平化重构:将司令部升级按钮动态置于最顶层
if [ "$IS_OFFICIAL_GATEWAY" != "true" ]; then
BTNS="[${BTN_MASTER_OTA}[{\"text\":\"🌍 进入全球战区雷达 (管理节点)\",\"callback_data\":\"list_nodes\"}], [{\"text\":\"🚀 全军总攻\",\"callback_data\":\"all_run\"}, {\"text\":\"📊 全军简报\",\"callback_data\":\"all_reports\"}], [{\"text\":\"☢️ 全舰队 OTA 热重载\",\"callback_data\":\"all_ota_confirm\"}]]"
else
BTNS="[[{\"text\":\"🌍 进入全球战区雷达 (管理节点)\",\"callback_data\":\"list_nodes\"}], [{\"text\":\"🚀 全军总攻\",\"callback_data\":\"all_run\"}, {\"text\":\"📊 全军简报\",\"callback_data\":\"all_reports\"}]]"
fi
TEXT_MSG="🛡️ **IP-Sentinel 司令部**\n${VER_INFO}\n\n📊 舰队状态: 共有 \`${NODE_COUNT}\` 台哨兵在线\n欢迎回来长官。请下达战略指令"
send_ui "$CHAT_ID" "$TEXT_MSG" "$BTNS"
;;
"all_ota_confirm")
CONFIRM_BTNS="[[{\"text\":\"🚨 我已了解风险,下发核按钮指令!\",\"callback_data\":\"all_ota_execute\"}], [{\"text\":\"取消操作\",\"callback_data\":\"/start\"}]]"
WARNING_MSG="☢️ **【最高指令:全舰队 OTA 升级】**\n\n此操作将向您名下**所有开启 OTA 权限的节点**下发重组指令,强制从云端拉取最新代码并进行热重载。\n\n⚠ **核按钮风险提示**\n1. 升级过程中守护进程会短暂重启,节点可能出现临时离线。\n2. 若遇 GitHub 源屏蔽或网络极度恶劣,少数节点可能需要手动干预。\n\n**是否确定挂载并执行 OTA 指令?**"
send_ui "$CHAT_ID" "$WARNING_MSG" "$CONFIRM_BTNS"
;;
"all_ota_execute")
NODE_DATA=$(db_exec "SELECT node_name, agent_ip, agent_port FROM nodes WHERE chat_id='$CHAT_ID' AND enable_ota='true';")
if [ -z "$NODE_DATA" ]; then
send_msg "$CHAT_ID" "⚠️ 您名下暂无开启 OTA 权限的在线节点。"
else
send_msg "$CHAT_ID" "📢 **司令部指令下达:正在唤醒全舰队执行 OTA 升级...**%0A*(节点升级成功后会主动发回新的入库确认,请注意查收)*"
echo "$NODE_DATA" | while IFS='|' read -r NNAME AIP APORT; do
TARGET_URL=$(generate_signed_url "$AIP" "$APORT" "/trigger_ota")
{ curl -k -s -m 5 "$TARGET_URL" || curl -s -m 5 "${TARGET_URL/https:\/\//http:\/\/}"; } > /dev/null &
sleep 0.3 # 严格流量削峰
done
fi
;;
"master_ota_confirm")
CONFIRM_BTNS="[[{\"text\":\"🚨 确认重构司令部\",\"callback_data\":\"master_ota_execute\"}], [{\"text\":\"取消操作\",\"callback_data\":\"/start\"}]]"
WARNING_MSG="☢️ **【最高指令:中枢金蝉脱壳】**\n\n此操作将拉取最新源码并强行覆盖司令部核心进程。\n\n⚠ **风险提示**\n升级期间司令部将短暂失联约3-5秒。完成后会自动发送捷报。\n\n**是否确定执行司令部自我升级?**"
if [ -n "$MSG_ID" ]; then
edit_ui "$CHAT_ID" "$MSG_ID" "$WARNING_MSG" "$CONFIRM_BTNS"
else
send_ui "$CHAT_ID" "$WARNING_MSG" "$CONFIRM_BTNS"
fi
;;
"master_ota_execute")
if [ -n "$MSG_ID" ]; then
edit_msg "$CHAT_ID" "$MSG_ID" "⏳ 正在下载重构图纸,司令部即将进入静默重启..."
else
send_msg "$CHAT_ID" "⏳ 正在下载重构图纸,司令部即将进入静默重启..."
fi
# 下载最新的 master install 脚本作为幽灵进程
curl -fsSL "${REPO_RAW_URL}/master/install_master.sh" -o "/tmp/install_master.sh"
# [v3.6.3 修复] 🚀 OTA 防砖机制:严格校验脚本完整性
if ! bash -n "/tmp/install_master.sh" >/dev/null 2>&1; then
if [ -n "$MSG_ID" ]; then
edit_msg "$CHAT_ID" "$MSG_ID" "❌ OTA 传输受损:脚本下载不完整,已触发防砖熔断,升级取消!"
else
send_msg "$CHAT_ID" "❌ OTA 传输受损:脚本下载不完整,已触发防砖熔断,升级取消!"
fi
continue
fi
chmod +x "/tmp/install_master.sh"
# 抛出幽灵进程进行脱壳升级,传递静默变量与回执 ID
# [修复] 必须显式将环境变量注入到 bash -c 的指令串中,防止被 systemd-run 沙盒隔离丢弃
if command -v systemd-run >/dev/null 2>&1; then
systemd-run --quiet --no-block /bin/bash -c "export SILENT_MASTER_OTA='true'; export OTA_CHAT_ID='$CHAT_ID'; bash /tmp/install_master.sh"
else
export SILENT_MASTER_OTA="true"
export OTA_CHAT_ID="$CHAT_ID"
nohup bash /tmp/install_master.sh >/dev/null 2>&1 & disown
fi
# 当前旧进程休眠并等待被幽灵进程处决
sleep 10
;;
"all_reports")
@@ -154,11 +299,13 @@ while true; do
if [ -z "$NODE_DATA" ]; then
send_msg "$CHAT_ID" "⚠️ 您名下暂无在线节点。"
else
send_msg "$CHAT_ID" "📢 **司令部指令下达:正在召唤所有哨兵回传简报...**"
# [文案优化] 提前告知指挥官需要排队等待
send_msg "$CHAT_ID" "📢 **司令部指令下达:正在召唤所有哨兵回传简报...**%0A*(为防止触发 TG 官方限流,简报将排队依次送达,请耐心等待)*"
echo "$NODE_DATA" | while IFS='|' read -r NNAME AIP APORT; do
# 🛡️ [v3.0.4] 动态签名防重放批量下发
TARGET_URL=$(generate_signed_url "$AIP" "$APORT" "/trigger_report")
curl -s -m 5 "$TARGET_URL" > /dev/null &
{ curl -k -s -m 5 "$TARGET_URL" || curl -s -m 5 "${TARGET_URL/https:\/\//http:\/\/}"; } > /dev/null &
# [致命修复] 强行休眠 2 秒!错开 TG 官方 1条/秒 的发信红线
sleep 2
done
fi
;;
@@ -171,9 +318,9 @@ while true; do
else
send_msg "$CHAT_ID" "📢 **司令部指令下达:正在唤醒所有哨兵执行系统维护...**"
echo "$NODE_DATA" | while IFS='|' read -r NNAME AIP APORT; do
# 🛡️ [v3.0.4] 动态签名防重放批量下发 (维护模块)
TARGET_URL=$(generate_signed_url "$AIP" "$APORT" "/trigger_run")
curl -s -m 5 "$TARGET_URL" > /dev/null &
curl -k -s -m 5 "$TARGET_URL" > /dev/null &
sleep 0.2 # [新增] 流量削峰:防止瞬间 fork 导致句柄耗尽
done
fi
;;
@@ -192,11 +339,14 @@ while true; do
case "$REGION_NAME" in
"US") FLAG="🇺🇸" ;; "JP") FLAG="🇯🇵" ;; "HK") FLAG="🇭🇰" ;;
"SG") FLAG="🇸🇬" ;; "UK"|"GB") FLAG="🇬🇧" ;; "DE") FLAG="🇩🇪" ;; "FR") FLAG="🇫🇷" ;;
"CA") FLAG="🇨🇦" ;; "AU") FLAG="🇦🇺" ;; "KR") FLAG="🇰🇷" ;; "NL") FLAG="🇳🇱" ;;
"BR") FLAG="🇧🇷" ;; "IN") FLAG="🇮🇳" ;; "TW") FLAG="🇹🇼" ;;
esac
BTNS="$BTNS[{\"text\":\"$FLAG $REGION_NAME ($NODE_COUNT 台)\",\"callback_data\":\"region:$REGION_NAME\"}],"
done <<< "$REGION_DATA"
BTNS="${BTNS%,}]"
send_ui "$CHAT_ID" "🌍 **全视界战略雷达**\n请选择要检阅的战区" "$BTNS"
# L1 追加返回中枢逃生舱
BTNS="$BTNS[{\"text\":\"🏠 回到司令部\",\"callback_data\":\"/start\"}]]"
send_ui "$CHAT_ID" "🌍 **全视界战略雷达**\n已为您聚合当前舰队的部署大区请选择要检阅的战区" "$BTNS"
fi
;;
@@ -205,15 +355,17 @@ while true; do
TARGET_REGION=$(echo "${TEXT#*:}" | tr -cd 'a-zA-Z0-9')
CHAT_ID=$(echo "$CHAT_ID" | tr -cd '0-9-')
NODE_LIST=$(db_exec "SELECT node_name FROM nodes WHERE chat_id='$CHAT_ID' AND region='$TARGET_REGION';")
# [v3.5.2] 提取物理主键和展示别名
NODE_LIST=$(db_exec "SELECT node_name, IFNULL(node_alias, node_name) FROM nodes WHERE chat_id='$CHAT_ID' AND region='$TARGET_REGION';")
if [ -z "$NODE_LIST" ]; then
send_msg "$CHAT_ID" "⚠️ 该战区下暂无可用节点。"
else
BTNS="["
COL=0
ROW_STR="["
for N in $NODE_LIST; do
ROW_STR="$ROW_STR{\"text\":\"🖥️ $N\",\"callback_data\":\"manage:$N\"},"
while IFS='|' read -r N_NAME N_ALIAS; do
[ -z "$N_NAME" ] && continue
ROW_STR="$ROW_STR{\"text\":\"🖥️ $N_ALIAS\",\"callback_data\":\"manage:$N_NAME\"},"
COL=$((COL+1))
if [ $COL -eq 2 ]; then
ROW_STR="${ROW_STR%,}]"
@@ -221,24 +373,123 @@ while true; do
COL=0
ROW_STR="["
fi
done
done <<< "$NODE_LIST"
# 如果是奇数,补齐最后的尾巴
if [ $COL -eq 1 ]; then
ROW_STR="${ROW_STR%,}]"
BTNS="$BTNS$ROW_STR,"
fi
# 添加返回上级大区雷达的按钮
BTNS="$BTNS[{\"text\":\"⬅️ 返回全球战区分布\",\"callback_data\":\"list_nodes\"}]]"
send_ui "$CHAT_ID" "📍 **[$TARGET_REGION] 战区哨兵矩阵**\n请下达控制指令" "$BTNS"
# L2 追加双重逃生舱
BTNS="$BTNS[{\"text\":\"⬅️ 返回战区地图\",\"callback_data\":\"list_nodes\"}, {\"text\":\"🏠 回到司令部\",\"callback_data\":\"/start\"}]]"
send_ui "$CHAT_ID" "📍 **[$TARGET_REGION] 战区哨兵矩阵**\n请锁定要执行战术动作的具体目标" "$BTNS"
fi
;;
manage:*)
# 🛡️ 强制过滤节点名,防止面板渲染时发生 XSS 或注入
TARGET_NODE=$(echo "${TEXT#*:}" | tr -cd 'a-zA-Z0-9_.-')
# 【核心升级】拆分下发按钮,精准对应 Google 与 Trust 两个模块,并排版为 3 行 2 列
BTNS="[[{\"text\":\"📍 Google 纠偏\",\"callback_data\":\"google:$TARGET_NODE\"}, {\"text\":\"🛡️ 信用净化\",\"callback_data\":\"trust:$TARGET_NODE\"}], [{\"text\":\"📜 实时日志\",\"callback_data\":\"log:$TARGET_NODE\"}, {\"text\":\"📊 统计战报\",\"callback_data\":\"report:$TARGET_NODE\"}], [{\"text\":\"🗑️ 剔除失联节点\",\"callback_data\":\"del:$TARGET_NODE\"}, {\"text\":\"⬅️ 返回大区目录\",\"callback_data\":\"list_nodes\"}]]"
send_ui "$CHAT_ID" "⚙️ **目标锁定**: \`$TARGET_NODE\`\n请选择战术动作" "$BTNS"
TARGET_ALIAS=$(db_exec "SELECT IFNULL(node_alias, node_name) FROM nodes WHERE chat_id='$CHAT_ID' AND node_name='$TARGET_NODE' LIMIT 1;")
[ -z "$TARGET_ALIAS" ] && TARGET_ALIAS="$TARGET_NODE"
# 抓取节点全景元数据
TOGGLE_INFO=$(db_exec "SELECT enable_google, enable_trust, enable_ota, agent_ip, IFNULL(last_seen, '未知') FROM nodes WHERE chat_id='$CHAT_ID' AND node_name='$TARGET_NODE' LIMIT 1;")
ST_GOOGLE=$(echo "$TOGGLE_INFO" | cut -d'|' -f1)
ST_TRUST=$(echo "$TOGGLE_INFO" | cut -d'|' -f2)
ST_OTA=$(echo "$TOGGLE_INFO" | cut -d'|' -f3)
A_IP=$(echo "$TOGGLE_INFO" | cut -d'|' -f4)
LAST_SEEN=$(echo "$TOGGLE_INFO" | cut -d'|' -f5)
# 动态渲染状态文字
[ "$ST_GOOGLE" == "true" ] && BTN_G="🟢 Google巡逻: 已开" && ACT_G="false" || { BTN_G="🔴 Google巡逻: 已停"; ACT_G="true"; }
[ "$ST_TRUST" == "true" ] && BTN_T="🟢 信用净化: 已开" && ACT_T="false" || { BTN_T="🔴 信用净化: 已停"; ACT_T="true"; }
# 模块一:即时战术动作
BTN_ACTION="[{\"text\":\"📍 触发 Google 纠偏\",\"callback_data\":\"google:$TARGET_NODE\"}, {\"text\":\"🛡️ 触发信用净化\",\"callback_data\":\"trust:$TARGET_NODE\"}], [{\"text\":\"📜 提取终端实时日志\",\"callback_data\":\"log:$TARGET_NODE\"}, {\"text\":\"📊 生成单机战报\",\"callback_data\":\"report:$TARGET_NODE\"}]"
# 模块二:养护状态启停
BTN_TOGGLE="[{\"text\":\"$BTN_G\",\"callback_data\":\"toggle:google:$TARGET_NODE:$ACT_G\"}, {\"text\":\"$BTN_T\",\"callback_data\":\"toggle:trust:$TARGET_NODE:$ACT_T\"}]"
# 模块三:深度配置管理 (结合 UI 熔断)
if [ "$IS_OFFICIAL_GATEWAY" != "true" ] && [ "$ST_OTA" == "true" ]; then
BTN_CONFIG="[{\"text\":\"✏️ 更改终端展示代号\",\"callback_data\":\"rename:$TARGET_NODE\"}, {\"text\":\"🆙 OTA 静默升级\",\"callback_data\":\"ota_confirm:$TARGET_NODE\"}]"
else
BTN_CONFIG="[{\"text\":\"✏️ 更改终端展示代号\",\"callback_data\":\"rename:$TARGET_NODE\"}]"
fi
# 模块四:危险区与逃生舱
BTN_DANGER="[{\"text\":\"🗑️ 从中枢销毁该档案\",\"callback_data\":\"del:$TARGET_NODE\"}, {\"text\":\"⬅️ 返回战区列表\",\"callback_data\":\"list_nodes\"}]"
# 组合终极矩阵
BTNS="[$BTN_ACTION, $BTN_TOGGLE, $BTN_CONFIG, $BTN_DANGER]"
TEXT_MSG="⚙️ **目标锁定**: \`$TARGET_ALIAS\`\n(底层标识: \`$TARGET_NODE\`)\n🌐 IP 坐标: \`$A_IP\`\n🕒 最后通讯: \`$LAST_SEEN\`\n\n请下达精确控制指令"
if [ -n "$MSG_ID" ]; then
edit_ui "$CHAT_ID" "$MSG_ID" "$TEXT_MSG" "$BTNS"
else
send_ui "$CHAT_ID" "$TEXT_MSG" "$BTNS"
fi
;;
toggle:*)
# [动态启停通信闭环]
IFS=':' read -r CMD MOD_NAME TARGET_NODE TARGET_STATE <<< "$TEXT"
CHAT_ID=$(echo "$CHAT_ID" | tr -cd '0-9-')
AGENT_INFO=$(db_exec "SELECT agent_ip, agent_port FROM nodes WHERE chat_id='$CHAT_ID' AND node_name='$TARGET_NODE' LIMIT 1;")
AGENT_IP=$(echo "$AGENT_INFO" | cut -d'|' -f1)
AGENT_PORT=$(echo "$AGENT_INFO" | cut -d'|' -f2)
if [ -n "$AGENT_IP" ] && [ -n "$AGENT_PORT" ]; then
TARGET_URL=$(generate_signed_url "$AGENT_IP" "$AGENT_PORT" "/trigger_toggle")
TARGET_URL="${TARGET_URL}&mod=${MOD_NAME}&state=${TARGET_STATE}"
RESPONSE=$(curl -k -s -m 5 "$TARGET_URL" || echo "FAILED")
# [向下兼容补丁] 若 HTTPS 拒绝或超时,回退 HTTP 试探老节点
if [ "$RESPONSE" == "FAILED" ] || [ -z "$RESPONSE" ]; then
TARGET_URL_HTTP="${TARGET_URL/https:\/\//http:\/\/}"
RESPONSE=$(curl -s -m 5 "$TARGET_URL_HTTP" || echo "FAILED")
fi
if [[ "$RESPONSE" == *"Action Accepted"* ]]; then
# 下发成功,更新 DB原位重绘
db_exec "UPDATE nodes SET enable_${MOD_NAME}='$TARGET_STATE' WHERE chat_id='$CHAT_ID' AND node_name='$TARGET_NODE';"
TOGGLE_INFO=$(db_exec "SELECT enable_google, enable_trust FROM nodes WHERE chat_id='$CHAT_ID' AND node_name='$TARGET_NODE' LIMIT 1;")
ST_GOOGLE=$(echo "$TOGGLE_INFO" | cut -d'|' -f1)
ST_TRUST=$(echo "$TOGGLE_INFO" | cut -d'|' -f2)
[ "$ST_GOOGLE" == "true" ] && BTN_G="🔴 停用 Google 纠偏" && ACT_G="false" || { BTN_G="🟢 启用 Google 纠偏"; ACT_G="true"; }
[ "$ST_TRUST" == "true" ] && BTN_T="🔴 停用信用净化" && ACT_T="false" || { BTN_T="🟢 启用信用净化"; ACT_T="true"; }
# 切换后直接复用扁平化 L3 面板的重绘逻辑
TOGGLE_INFO=$(db_exec "SELECT enable_google, enable_trust, enable_ota, agent_ip, IFNULL(last_seen, '未知') FROM nodes WHERE chat_id='$CHAT_ID' AND node_name='$TARGET_NODE' LIMIT 1;")
ST_GOOGLE=$(echo "$TOGGLE_INFO" | cut -d'|' -f1)
ST_TRUST=$(echo "$TOGGLE_INFO" | cut -d'|' -f2)
ST_OTA=$(echo "$TOGGLE_INFO" | cut -d'|' -f3)
A_IP=$(echo "$TOGGLE_INFO" | cut -d'|' -f4)
LAST_SEEN=$(echo "$TOGGLE_INFO" | cut -d'|' -f5)
[ "$ST_GOOGLE" == "true" ] && BTN_G="🟢 Google巡逻: 已开" && ACT_G="false" || { BTN_G="🔴 Google巡逻: 已停"; ACT_G="true"; }
[ "$ST_TRUST" == "true" ] && BTN_T="🟢 信用净化: 已开" && ACT_T="false" || { BTN_T="🔴 信用净化: 已停"; ACT_T="true"; }
BTN_ACTION="[{\"text\":\"📍 触发 Google 纠偏\",\"callback_data\":\"google:$TARGET_NODE\"}, {\"text\":\"🛡️ 触发信用净化\",\"callback_data\":\"trust:$TARGET_NODE\"}], [{\"text\":\"📜 提取终端实时日志\",\"callback_data\":\"log:$TARGET_NODE\"}, {\"text\":\"📊 生成单机战报\",\"callback_data\":\"report:$TARGET_NODE\"}]"
BTN_TOGGLE="[{\"text\":\"$BTN_G\",\"callback_data\":\"toggle:google:$TARGET_NODE:$ACT_G\"}, {\"text\":\"$BTN_T\",\"callback_data\":\"toggle:trust:$TARGET_NODE:$ACT_T\"}]"
if [ "$IS_OFFICIAL_GATEWAY" != "true" ] && [ "$ST_OTA" == "true" ]; then
BTN_CONFIG="[{\"text\":\"✏️ 更改终端展示代号\",\"callback_data\":\"rename:$TARGET_NODE\"}, {\"text\":\"🆙 OTA 静默升级\",\"callback_data\":\"ota_confirm:$TARGET_NODE\"}]"
else
BTN_CONFIG="[{\"text\":\"✏️ 更改终端展示代号\",\"callback_data\":\"rename:$TARGET_NODE\"}]"
fi
BTN_DANGER="[{\"text\":\"🗑️ 从中枢销毁该档案\",\"callback_data\":\"del:$TARGET_NODE\"}, {\"text\":\"⬅️ 返回战区列表\",\"callback_data\":\"list_nodes\"}]"
BTNS="[$BTN_ACTION, $BTN_TOGGLE, $BTN_CONFIG, $BTN_DANGER]"
TARGET_ALIAS=$(db_exec "SELECT IFNULL(node_alias, node_name) FROM nodes WHERE chat_id='$CHAT_ID' AND node_name='$TARGET_NODE' LIMIT 1;")
TEXT_MSG="⚙️ **目标锁定**: \`$TARGET_ALIAS\`\n(底层标识: \`$TARGET_NODE\`)\n🌐 IP 坐标: \`$A_IP\`\n🕒 最后通讯: \`$LAST_SEEN\`\n\n✅ **执行成功**: 模块 [$MOD_NAME] 状态已切换为 $TARGET_STATE"
edit_ui "$CHAT_ID" "$MSG_ID" "$TEXT_MSG" "$BTNS"
else
send_msg "$CHAT_ID" "❌ 指令下发失败,节点可能离线或未更新至 v3.5.3。"
fi
fi
;;
del:*)
@@ -261,6 +512,8 @@ while true; do
case "$REGION_NAME" in
"US") FLAG="🇺🇸" ;; "JP") FLAG="🇯🇵" ;; "HK") FLAG="🇭🇰" ;;
"SG") FLAG="🇸🇬" ;; "UK"|"GB") FLAG="🇬🇧" ;; "DE") FLAG="🇩🇪" ;; "FR") FLAG="🇫🇷" ;;
"CA") FLAG="🇨🇦" ;; "AU") FLAG="🇦🇺" ;; "KR") FLAG="🇰🇷" ;; "NL") FLAG="🇳🇱" ;;
"BR") FLAG="🇧🇷" ;; "IN") FLAG="🇮🇳" ;; "TW") FLAG="🇹🇼" ;;
esac
BTNS="$BTNS[{\"text\":\"$FLAG $REGION_NAME ($NODE_COUNT 台)\",\"callback_data\":\"region:$REGION_NAME\"}],"
done <<< "$REGION_DATA"
@@ -269,6 +522,103 @@ while true; do
fi
;;
rename:*)
TARGET_NODE=$(echo "${TEXT#*:}" | tr -cd 'a-zA-Z0-9_.-')
CHAT_ID=$(echo "$CHAT_ID" | tr -cd '0-9-')
# [v3.5.2] 发送 ForceReply 引导用户回复
curl -s -X POST "https://api.telegram.org/bot${TG_TOKEN}/sendMessage" \
-H "Content-Type: application/json" \
-d "{\"chat_id\":\"$CHAT_ID\",\"text\":\"✏️ 请回复本消息以重命名节点:\n\`$TARGET_NODE\`\n(仅限中英文、数字最长20字符)\",\"parse_mode\":\"Markdown\",\"reply_markup\":{\"force_reply\":true}}" > /dev/null
;;
do_rename:*)
# [v3.5.2] 内部重命名路由 (已被第2处的代码拦截并格式化)
IFS=':' read -r CMD TARGET_NODE NEW_ALIAS <<< "$TEXT"
CHAT_ID=$(echo "$CHAT_ID" | tr -cd '0-9-')
AGENT_INFO=$(db_exec "SELECT agent_ip, agent_port FROM nodes WHERE chat_id='$CHAT_ID' AND node_name='$TARGET_NODE' LIMIT 1;")
AGENT_IP=$(echo "$AGENT_INFO" | cut -d'|' -f1)
AGENT_PORT=$(echo "$AGENT_INFO" | cut -d'|' -f2)
if [ -n "$AGENT_IP" ] && [ -n "$AGENT_PORT" ]; then
send_msg "$CHAT_ID" "⏳ 正在向 \`$TARGET_NODE\` 下发重命名指令,正在建立加密隧道..."
TARGET_URL=$(generate_signed_url "$AGENT_IP" "$AGENT_PORT" "/trigger_rename")
# [绝密防线: Base64 编码绕过一切传输限制与 WAF 拦截]
ALIAS_B64=$(echo -n "$NEW_ALIAS" | base64 | tr -d '\n' | tr '+/' '-_')
TARGET_URL="${TARGET_URL}&b64=${ALIAS_B64}"
RESPONSE=$(curl -k -s -m 5 "$TARGET_URL" || echo "FAILED")
# [向下兼容补丁] 若 HTTPS 拒绝或超时,回退 HTTP 试探老节点
if [ "$RESPONSE" == "FAILED" ] || [ -z "$RESPONSE" ]; then
TARGET_URL_HTTP="${TARGET_URL/https:\/\//http:\/\/}"
RESPONSE=$(curl -s -m 5 "$TARGET_URL_HTTP" || echo "FAILED")
fi
if [ "$RESPONSE" == "FAILED" ]; then
send_msg "$CHAT_ID" "❌ 指令下发超时!请检查节点连通性。"
elif [[ "$RESPONSE" == *"Action Accepted"* ]]; then
# [v3.5.2 极致丝滑] 确认 Agent 修改成功后Master 立即自动同步本地 SQLite 数据库!
db_exec "UPDATE nodes SET node_alias='$NEW_ALIAS' WHERE chat_id='$CHAT_ID' AND node_name='$TARGET_NODE';"
send_msg "$CHAT_ID" "✅ 通讯成功!节点别名已下发: \`$NEW_ALIAS\`%0A*(司令部档案已自动刷新,雷达面板已同步)*"
else
# 增加输出 RESPONSE 调试信息,排查任何拦截死因
send_msg "$CHAT_ID" "⚠️ 节点拒绝了请求,请确保 Agent 已更新至 v3.5.2%0A(回传信息: \`${RESPONSE}\`)"
fi
else
send_msg "$CHAT_ID" "❌ 数据库中未找到该节点的通讯地址。"
fi
;;
ota_confirm:*)
TARGET_NODE=$(echo "${TEXT#*:}" | tr -cd 'a-zA-Z0-9_.-')
# 将取消动作引导回 manage因为 adv 已经被删除了
CONFIRM_BTNS="[[{\"text\":\"🚨 确认执行远程升级\",\"callback_data\":\"ota_execute:$TARGET_NODE\"}], [{\"text\":\"取消\",\"callback_data\":\"manage:$TARGET_NODE\"}]]"
send_ui "$CHAT_ID" "☢️ **操作确认**:即将向 \`$TARGET_NODE\` 下发 OTA 热更新指令。\n节点更新完成后会自动发送包含新版本号的注册回执确定执行" "$CONFIRM_BTNS"
;;
ota_execute:*)
TARGET_NODE=$(echo "${TEXT#*:}" | tr -cd 'a-zA-Z0-9_.-')
CHAT_ID=$(echo "$CHAT_ID" | tr -cd '0-9-')
AGENT_INFO=$(db_exec "SELECT agent_ip, agent_port FROM nodes WHERE chat_id='$CHAT_ID' AND node_name='$TARGET_NODE' LIMIT 1;")
AGENT_IP=$(echo "$AGENT_INFO" | cut -d'|' -f1)
AGENT_PORT=$(echo "$AGENT_INFO" | cut -d'|' -f2)
if [ -n "$AGENT_IP" ] && [ -n "$AGENT_PORT" ]; then
if [ -n "$MSG_ID" ]; then
edit_msg "$CHAT_ID" "$MSG_ID" "⏳ 正在向 \`$TARGET_NODE\` 发送 OTA 触发报文..."
else
send_msg "$CHAT_ID" "⏳ 正在向 \`$TARGET_NODE\` 发送 OTA 触发报文..."
fi
TARGET_URL=$(generate_signed_url "$AGENT_IP" "$AGENT_PORT" "/trigger_ota")
RESPONSE=$(curl -k -s -m 5 "$TARGET_URL" || echo "FAILED")
# [向下兼容补丁] 若 HTTPS 拒绝或超时,回退 HTTP 试探老节点
if [ "$RESPONSE" == "FAILED" ] || [ -z "$RESPONSE" ]; then
TARGET_URL_HTTP="${TARGET_URL/https:\/\//http:\/\/}"
RESPONSE=$(curl -s -m 5 "$TARGET_URL_HTTP" || echo "FAILED")
fi
if [ "$RESPONSE" == "FAILED" ]; then
TEXT_RES="❌ OTA 指令下发超时!请检查节点公网连通性。"
elif [[ "$RESPONSE" == *"403"* ]]; then
TEXT_RES="⚠️ **节点拒绝执行**:该节点本地未开启 OTA 权限或运行在官方网关下!"
else
TEXT_RES="✅ OTA 触发成功!节点正在后台执行拉取重构,请等待其发送更新完成的回执消息。"
fi
if [ -n "$MSG_ID" ]; then
edit_msg "$CHAT_ID" "$MSG_ID" "$TEXT_RES"
else
send_msg "$CHAT_ID" "$TEXT_RES"
fi
else
send_msg "$CHAT_ID" "❌ 数据库中未找到该节点的通讯地址。"
fi
;;
# 【核心升级】增加拦截规则,支持 google 和 trust 前缀
google:*|trust:*|run:*|report:*|log:*)
# 🛡️ 提取并强制过滤动作参数、节点名与 CHAT_ID
@@ -290,7 +640,12 @@ while true; do
# 🛡️ [v3.0.4] 动态签名生成与触发 (防重放与防篡改)
TARGET_URL=$(generate_signed_url "$AGENT_IP" "$AGENT_PORT" "/trigger_${ACTION_TYPE}")
RESPONSE=$(curl -s -m 5 "$TARGET_URL" || echo "FAILED")
RESPONSE=$(curl -k -s -m 5 "$TARGET_URL" || echo "FAILED")
# [向下兼容补丁] 若 HTTPS 拒绝或超时,回退 HTTP 试探老节点
if [ "$RESPONSE" == "FAILED" ] || [ -z "$RESPONSE" ]; then
TARGET_URL_HTTP="${TARGET_URL/https:\/\//http:\/\/}"
RESPONSE=$(curl -s -m 5 "$TARGET_URL_HTTP" || echo "FAILED")
fi
# 结果判定
if [ "$RESPONSE" == "FAILED" ]; then

View File

@@ -1,14 +1,30 @@
#!/bin/bash
# ==========================================================
# 脚本名称: uninstall_master.sh (IP-Sentinel Master 一键卸载脚本)
# 脚本名称: uninstall_master.sh (IP-Sentinel Master 一键卸载脚本 - 动态锚点版)
# 核心功能: 终止调度进程、清理看门狗定时任务、抹除数据库与配置
# ==========================================================
# ==========================================================
# 🛑 核心权限防线: 检查是否以 root 权限运行
# ==========================================================
if [ "$EUID" -ne 0 ]; then
echo -e "\033[31m❌ 权限被拒绝: 卸载 IP-Sentinel 需要最高系统权限。\033[0m"
echo -e "💡 请切换到 root 用户 (执行 su root 或 sudo -i) 后重新运行指令。"
exit 1
fi
MASTER_DIR="/opt/ip_sentinel_master"
CONF_FILE="${MASTER_DIR}/master.conf"
echo "========================================================"
echo " 🗑️ 准备卸载 IP-Sentinel Master (控制中枢)"
# [v3.4.0 优化] 卸载前读取并播报中枢版本号
if [ -f "$CONF_FILE" ]; then
MASTER_VER=$(grep "^MASTER_VERSION=" "$CONF_FILE" | cut -d'"' -f2)
[ -n "$MASTER_VER" ] && echo " 📍 目标版本: v${MASTER_VER}"
fi
echo "========================================================"
echo -e "\n⚠ 警告: 此操作将永久删除包含所有节点档案的 SQLite 数据库!"
@@ -18,18 +34,30 @@ if [[ ! "$CONFIRM_DEL" =~ ^[Yy]$ ]]; then
exit 0
fi
# 1. 停止运行中的 Master 守护进程
echo "[1/3] 正在终止后台中枢调度进程..."
pgrep -f tg_master.sh | xargs -r kill -9 >/dev/null 2>&1
# 1. 停止并删除 Systemd 服务 (适配新架构)
echo "[1/4] 正在停止并删除 Systemd 服务..."
if command -v systemctl >/dev/null 2>&1; then
echo "💡 检测到 Systemd 环境,正在抹除 Systemd 服务单元..."
systemctl disable --now ip-sentinel-master.service >/dev/null 2>&1
rm -f /etc/systemd/system/ip-sentinel-master.service
systemctl daemon-reload
systemctl reset-failed
else
echo "💡 未检测到 Systemd跳过此步骤..."
fi
# 2. 清除看门狗定时任务 (Cron)
echo "[2/3] 正在清理系统定时任务 (Cron)..."
# 2. 停止运行中的 Master 守护进程 (兜底清理老版进程)
echo "[2/4] 正在终止后台中枢调度进程..."
pkill -9 -f "tg_master.sh" >/dev/null 2>&1 || true
# 3. 清除看门狗定时任务 (Cron)
echo "[3/4] 正在清理系统定时任务 (Cron)..."
crontab -l 2>/dev/null | grep -v "tg_master.sh" > /tmp/cron_backup
crontab /tmp/cron_backup
rm -f /tmp/cron_backup
# 3. 删除所有文件、配置与数据库
echo "[3/3] 正在抹除核心程序、配置文件与 SQLite 数据库..."
# 4. 删除所有文件、配置与数据库
echo "[4/4] 正在抹除核心程序、配置文件与 SQLite 数据库..."
if [ -d "$MASTER_DIR" ]; then
rm -rf "$MASTER_DIR"
fi

83
scripts/fetch_trends.py Normal file
View File

@@ -0,0 +1,83 @@
import urllib.request
import xml.etree.ElementTree as ET
import os
import json
import re
# ================== [路径防弹装甲] ==================
# 无论在哪里执行该脚本,都能精准反推项目根目录
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.dirname(SCRIPT_DIR)
MAP_JSON_PATH = os.path.join(PROJECT_ROOT, "data", "map.json")
DATA_DIR = os.path.join(PROJECT_ROOT, "data", "keywords")
# ====================================================
# 特殊战区代码映射 (Google Trends RSS 要求)
GEO_FIX = {'UK': 'GB'}
HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
}
def get_active_regions():
"""动态提取 map.json 中的战区 (适配 v3.5.0 大洲战区降维架构)"""
try:
with open(MAP_JSON_PATH, 'r', encoding='utf-8') as f:
data = json.load(f)
regions = []
# 第一层穿透:遍历所有大洲战区 (continents)
for continent in data.get('continents', []):
# 第二层穿透:遍历大洲下的所有国家 (countries)
for country in continent.get('countries', []):
if 'id' in country:
regions.append(country['id'])
return regions
except Exception as e:
print(f"❌ [读取地图失败]: {e}")
return []
def fetch_trends(region_code):
"""从 Google Trends 抓取当日热搜"""
geo = GEO_FIX.get(region_code, region_code)
url = f"https://trends.google.com/trending/rss?geo={geo}"
try:
req = urllib.request.Request(url, headers=HEADERS)
with urllib.request.urlopen(req, timeout=10) as response:
xml_data = response.read()
root = ET.fromstring(xml_data)
return [re.sub(r'[\n\r\t]', ' ', item.find('title').text).strip()
for item in root.findall('./channel/item')
if item.find('title') is not None]
except Exception as e:
print(f"⚠️ {region_code} 抓取异常: {e}")
return []
def update_file(region, new_words):
"""滑动窗口更新,保留 200 条最热记录"""
os.makedirs(DATA_DIR, exist_ok=True)
file_path = os.path.join(DATA_DIR, f"kw_{region}.txt")
old_words = []
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
old_words = [l.strip() for l in f if l.strip()]
# 新词排在最前面,去重
combined = new_words + [w for w in old_words if w not in new_words]
final_list = combined[:200]
with open(file_path, 'w', encoding='utf-8') as f:
f.write('\n'.join(final_list) + '\n')
print(f"✅ [同步完成] {region}: 注入 {len(new_words)} 条新热点")
if __name__ == '__main__':
regions = get_active_regions()
if not regions:
print("🛑 未发现活跃战区,请检查 map.json")
exit(1)
for r in regions:
print(f"📡 正在拉取 {r} 战区情报...")
words = fetch_trends(r)
if words:
update_file(r, words)

102
scripts/fetch_trust_urls.py Normal file
View File

@@ -0,0 +1,102 @@
import urllib.request
import xml.etree.ElementTree as ET
import os
import json
import random
# ================== [路径防弹装甲] ==================
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.dirname(SCRIPT_DIR)
REGIONS_DIR = os.path.join(PROJECT_ROOT, "data", "regions")
# ====================================================
HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
}
# 全球骨干新闻 RSS 监听矩阵
RSS_FEEDS = {
"US": ["http://rss.cnn.com/rss/cnn_topstories.rss", "https://feeds.npr.org/1001/rss.xml"],
"UK": ["http://feeds.bbci.co.uk/news/rss.xml"],
"AU": ["https://www.abc.net.au/news/feed/51120/rss.xml"],
"CA": ["https://www.cbc.ca/cmlink/rss-topstories"],
"DE": ["https://www.tagesschau.de/xml/rss2"],
"FR": ["https://www.france24.com/fr/rss"],
"ES": ["https://feeds.elpais.com/mrss-s/pages/ep/site/elpais.com/portada"],
"JP": ["https://news.yahoo.co.jp/rss/topics/top-picks.xml"],
"HK": ["https://hk.news.yahoo.com/rss/hong-kong"],
"TW": ["https://news.google.com/rss?hl=zh-TW&gl=TW&ceid=TW:zh-Hant"],
"KR": ["https://www.yonhapnewstv.co.kr/category/news/headline/feed/"],
"SG": ["https://www.channelnewsasia.com/api/v1/rss-outbound-feed?_format=xml"],
"NL": ["https://feeds.nos.nl/nosnieuwsalgemeen"],
"VN": ["https://vnexpress.net/rss/tin-moi-nhat.rss"]
}
def fetch_rss_links(region_code, max_items=15):
"""抓取该战区最新的 RSS 新闻链接"""
feeds = RSS_FEEDS.get(region_code, [])
if not feeds:
return []
links = []
for url in feeds:
try:
req = urllib.request.Request(url, headers=HEADERS)
with urllib.request.urlopen(req, timeout=10) as response:
xml_data = response.read()
root = ET.fromstring(xml_data)
for item in root.findall('.//item'):
link = item.find('link')
if link is not None and link.text:
clean_link = link.text.strip()
if clean_link.startswith('http'):
links.append(clean_link)
except Exception as e:
print(f"⚠️ [{region_code}] RSS 抓取异常 ({url}): {e}")
# 去重并截取最新
return list(set(links))[:max_items]
def process_json_file(file_path, region_code):
"""融合静态基石与动态新闻"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
trust_mod = data.get("trust_module", {})
if not trust_mod or "static_urls" not in trust_mod:
return
static_urls = trust_mod.get("static_urls", [])
# 抓取今日该战区的活体新闻流
daily_news_urls = fetch_rss_links(region_code)
# 战术混合:基石(保证高权重) + 新闻(保证活体动态)
combined_urls = static_urls + daily_news_urls
# 深度洗牌,打破机械顺序特征
combined_urls = list(set(combined_urls))
random.shuffle(combined_urls)
# 覆写回供 Agent 拉取的 white_urls
trust_mod["white_urls"] = combined_urls
data["trust_module"] = trust_mod
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print(f"✅ [信用融合] {os.path.basename(file_path)}: 骨干 {len(static_urls)} 条 + 活体 {len(daily_news_urls)}")
except Exception as e:
print(f"❌ [处理失败] {file_path}: {e}")
if __name__ == '__main__':
print("========== 启动 IP-Sentinel 活体新闻流融合引擎 ==========")
for root_dir, _, files in os.walk(REGIONS_DIR):
for file in files:
if file.endswith(".json"):
file_path = os.path.join(root_dir, file)
region_code = os.path.relpath(file_path, REGIONS_DIR).split(os.sep)[0]
process_json_file(file_path, region_code)
print("========== 融合引擎执行完毕 ==========")

2
version.txt Normal file
View File

@@ -0,0 +1,2 @@
MASTER_VERSION=3.6.3
AGENT_VERSION=3.6.4