Compare commits

...

52 Commits

Author SHA1 Message Date
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
hotyue
6b9563b858 fix(deploy): 🐛 [v3.2.3] 修复防火墙提示盲区,支持根据 IPv4/IPv6 动态下发 iptables/ip6tables 放行指令 2026-04-13 03:32:41 +00:00
32 changed files with 1075 additions and 241 deletions

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

@@ -0,0 +1,44 @@
name: Daily Trends Factory
on:
schedule:
# 每天 UTC 18:00 运行 (北京时间凌晨 02:00)
- cron: '0 18 * * *'
workflow_dispatch:
permissions:
contents: write
jobs:
update-trends:
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: Commit and Push
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/
# 防御机制:如果没有新数据,就静默退出,不产生空提交
if git diff --staged --quiet; then
echo "No changes, skipping."
exit 0
fi
# 策略:放弃危险的 amend 强制覆盖,采用带日期的标准安全提交
git commit -m "chore(data): 🤖 自动机兵:刷新全战区热点词库 [$(date +'%Y-%m-%d')]"
git push origin main

View File

@@ -10,33 +10,26 @@
专为解决 VPS IP 被 Google 等数据库错误定位到中国大陆/香港俗称“送中”等问题而生。IP-Sentinel 已从单机脚本全面跃升为 **Master-Agent 分布式架构**。它像影子一样潜伏在全球各地的服务器后台,通过高度拟真的真实用户行为为你默默积累 IP 权重,并允许你通过 Telegram 随时随地对整个舰队进行毫秒级“点名”与“遥控”。
## ✨ 核心极客特性
## ✨ 核心极客特性 (Evolution History)
- 🗺️ **全球拓扑矩阵 (Global Nexus)**v3.1 跨洲际跃升。守护版图现已横跨亚、欧、美三大洲(美、日、英、德、法、新、港)。为每个国家注入极其硬核的“原生本地化”搜索词库与本土高权重站点(如政府、权威媒体、高铁网),真正实现“拟真融入”
- 🌍 **[v3.5.0] 大洲战区与降维引擎 (Continental Grouping)**:随着全球版图的极速扩张,彻底重构底层地图索引。引入“战区(大洲)-国家-省州-城市”四级降维解析菜单,完美承载未来数十个国家的扩容,终端交互界面永远清爽干练
- 🧬 **[v3.5.0] SSOT 动态版本溯源 (Single Source of Truth)**:全系脚本彻底消灭硬编码版本号!引入企业级 DevOps 理念,部署时动态抓取云端信标并固化落盘,常驻进程与日志绝对继承本地基因,实现“改一处,全网同步”的极致架构。
- 🎯 **[v3.4.0] 版本锚点与路由中枢 (Version-Linked Epoch)**:彻底告别“盲盒式更新”,全系引入全局版本号机制。边缘节点具备“身份自知”能力,安装脚本根据本地版本执行精准的路由跳转,实现新老架构的智能化无损跃迁。
- 📡 **[v3.4.0] OTA 实时版本探针 (Version-Aware Radar)**:边缘哨兵现已接入云端“北极星”校准。每日战报自动扫描 GitHub 最新发布状态,发现版本落后即刻在 Telegram 战报底部亮起 OTA 预警,消除指挥官与前线的信息差。
- 📡 **[v3.3.0] OTA 动态活体词库 (Dynamic Trends)**:彻底废弃静态搜索词,引入 GitHub Actions 云端流水线。每天自动抓取全战区当日 Google 热搜榜单,并通过边缘节点每日静默同步,让搜索行为永远贴合当地当天的真实网络脉搏。
- 🔀 **[v3.3.0] 智能错峰调度 (Thundering Herd Mitigation)**:首创节点部署时间戳锚定逻辑。边缘节点按需智能分频(每日拉取词库,每月按 30 天周期错峰拉取千万级指纹库),化解“惊群效应”,抹平统一升级时的并发特征,隐匿于无形。
- 🎯 **[v3.2.2] 多级容灾与高精度探针 (High-Precision Probe)**:重写战报模块与底层协议自适应逻辑,植入多级 ISP 容灾探针链路,并按“底层数据共识原则”智能清洗冗余 AS 号。确保在纯 V6、隧道或弱网环境下数据获取依然 100% 精准畅通。
- 🔄 **[v3.2.2] 平滑热更新装甲 (Smooth Upgrade Engine)**全系植入状态机嗅探逻辑。再次执行部署脚本时将自动识别并继承历史配置、SQLite 数据库与锚定 IP一键回车瞬间完成无损换代。
- 🖧 **[v3.2.1] 底层路由死锁 (Hard-Bind Routing)**:底层探测引擎强力接管 curl 核心参数 (`--interface`),强制将发出的每一滴伪装流量死死绑定在您设定的物理网卡或隧道 IP 上,彻底杜绝双栈或多网卡环境下的流量溢出漏洞。
- 👻 **[v3.2.0] 设备资产持久化 (Hash-Seeded Persona)**:彻底摒弃随机抽取指纹,引入基于节点物理 IP 的哈希锚定引擎。利用不可变哈希种子,为您的每台 VPS 永久锁定 3 个绝对专属设备,完美构建高权重真实家庭内网画像,根除“僵尸网络”同质化特征!
- 🗺️ **[v3.1.0] 全球拓扑矩阵 (Global Nexus)**:守护版图横跨亚、欧、美三大洲。为每个国家注入极其硬核的“原生本地化”搜索词库与本土高权重站点(如政府、权威媒体、高铁网),真正实现拟真融入。
- 👻 **设备资产持久化 (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 秒(阅后即焚),彻底免疫中间人抓包与重放攻击
- ☁️ **云端中枢 (Public Master)**:官方公共机器人 @OmniBeacon_bot,新手免自建,一键接入极速入伍!同时支持硬核极客私有化 SQLite 分布式部署。
- 🎮 **TG 战术面板 (Command Center)**:全 Inline Keyboard 交互,一键下发伪装指令、索要战报、毫秒级抓取边缘节点实时运行日志
- 👁️‍🗨️ **玻璃房透明遥测 (Glasshouse)**:基于 Cloudflare Workers 的全透明计数中枢,绝对零隐私收集,仅作原子累加,底层网关源码全开源。
## 📂 项目架构 (Monorepo)
@@ -49,16 +42,17 @@
┣ 📂 core/ # 🛡️ 边缘哨兵Webhook 被动监听、哈希锚定执行引擎
┣ 📂 scripts/ # 🐍 兵工厂引擎:基于 Python 的多物理分区 UA 生成器
┣ 📂 data/ # 🗂️ 全球数据规则库 (动态拓扑)
┃ ┣ 📜 map.json # 🌐 全球区域索引大脑 (Master Index)
┃ ┣ 📜 map.json # 🌍 全球区域大脑 (v3.5.0 大洲战区拓扑)
┃ ┣ 📂 regions/ # 🧊 冷数据:按 [国家/省州/城市] 深度细分的 LBS 锚点
┃ ┣ 📂 keywords/ # 🔥 热数据:按国家归类的动态搜索词库 (OTA 自动更新)
┃ ┗ 📜 user_agents.txt # 🔥 热数据:由兵工厂每月锻造的绝对坐标专属设备库
┣ 📜 version.txt # 🚩 全球版本信标SSOT 单一事实来源锚点 (v3.5.0)
┗ 📂 telemetry/ # 👁️‍🗨️ 玻璃房计划Cloudflare Workers 透明计数器网关源码
```
## 🚀 极速部署 (Quick Start)
v3.2.x 提供了两种接入模式,请根据您的战术需求选择:
v3.5.x 提供了两种接入模式,请根据您的战术需求选择:
### 🔹 模式 A官方公共模式 (最简、推荐)
**适合不想折腾、只想快速养护 IP 的新兵。**
@@ -86,13 +80,18 @@ bash <(curl -sL https://raw.githubusercontent.com/hotyue/IP-Sentinel/main/core/i
```
3. **激活节点**:同上,将暗号转发给您自己的机器人即可。
### ⚠️ 平滑升级指引 (Upgrade to v3.2.2)
### ⚠️ 架构级热升级指引 (Upgrade to v3.5.0)
得益于 **v3.2.2 全新引入的平滑热更新引擎 (Smooth Upgrade Engine)**,系统升级现已变得极其优雅与安全
得益于 **v3.5.0 全新引入的 SSOT 版本锚点与状态机路由**,系统升级现已变得极其智能化
无需卸载旧版本,无论您是要升级 Agent 边缘节点还是 Master 控制中枢,只需在您的终端中**再次运行上方对应的官方部署指令**。
**如果您是从远古旧版 (v3.3.1 / v3.3.2) 升级:**
1. 在终端再次运行对应的官方部署指令。
2. 脚本会识别到您处于“前版本锚点时代”,会自动为您执行【跨代架构重组】。
3. **关键动作**:由于节点命名防撞机制变更,升级后您的 TG 会收到一条新的 `#REGISTER#` 指令,请点击并发送一次以同步新身份。
4. **清理**:在面板中手动剔除失联的旧节点即可。
安装雷达会自动嗅探您的历史部署状态(包括您的 Token、区域设定、SQLite 数据库及物理网卡锚点)。当询问是否平滑升级时,您只需**一路回车 (默认选 y)**,脚本将在短短 3 秒内瞬间完成核心装甲的无损换脑手术,您的所有战术资产将得到 100% 保留!
**如果您已处于 v3.4.0+**
所有的升级已进入**“极致静默平滑模式”**。安装引擎会动态抓取云端 `version.txt`,自动修正本地 `config.conf` 的版本号一键回车3 秒即可完成全系组件的热重载换代!
🗑️ 一键无痕卸载
如果你需要清理某个边缘节点,只需重新运行 `core/install.sh` 并选择 **[2]**,或直接在节点终端执行:

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# ==========================================================
# 脚本名称: agent_daemon.sh (受控节点 Webhook 守护进程 V3.0.3)
# 脚本名称: agent_daemon.sh (受控节点 Webhook 守护进程 - 动态锚点版)
# 核心功能: 智能防打扰注册、进程自检、模块级路由分发(403拦截)
# ==========================================================
@@ -17,21 +17,27 @@ source "$CONFIG_FILE"
# 默认 Webhook 监听端口
AGENT_PORT=${AGENT_PORT:-9527}
NODE_NAME=$(hostname | cut -c 1-15)
# [v3.4.0 核心] 统一采用防 Markdown 崩溃的中划线连接符
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}"
# --- [重点升级 1: 守护进程防冲突自检] ---
if pgrep -f "webhook.py $AGENT_PORT" > /dev/null; then
exit 0
fi
# 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
@@ -200,8 +206,13 @@ 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.4.0 核心] 获取版本与主机名
local_ver = config.get('AGENT_VERSION', '未知')
node_hostname = subprocess.check_output(['hostname']).decode('utf-8').strip()[:10]
ip_hash = hashlib.md5(config.get('PUBLIC_IP', '127.0.0.1').encode()).hexdigest()[:4].upper()
full_node_name = f"{node_hostname}-{ip_hash}"
text_msg = f"📄 <b>[{full_node_name}] 实时日志 (v{local_ver}):</b>\n<pre><code>{log_data}</code></pre>"
data = urllib.parse.urlencode({
'chat_id': config.get('CHAT_ID', ''),
@@ -212,7 +223,8 @@ 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)

View File

@@ -1,8 +1,8 @@
#!/bin/bash
# ==========================================================
# 脚本名称: install.sh (IP-Sentinel 分布式边缘节点部署脚本 v3.2.2 - Global Nexus)
# 核心功能: 区域选择、模块按需开启、官方机器人一键配置、平滑热更新
# 脚本名称: install.sh (IP-Sentinel 分布式边缘节点部署脚本 - 动态锚点版)
# 核心功能: 战区分组菜单、模块按需开启、官方机器人一键配置、版本状态机路由
# ==========================================================
# 你的 GitHub 仓库 Raw 数据直链前缀
@@ -12,8 +12,19 @@ REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main"
INSTALL_DIR="/opt/ip_sentinel"
CONFIG_FILE="${INSTALL_DIR}/config.conf"
# [核心: 动态获取全局版本控制锚点 (Single Source of Truth)]
TARGET_VERSION=$(curl -s -m 3 "${REPO_RAW_URL}/version.txt" | tr -d '[:space:]')
# 🛡️ 兜底防线:如果网络波动拉取失败,启用内置的安全兜底版本
TARGET_VERSION=${TARGET_VERSION:-"3.5.0"}
# 轻量级版本号比对函数 (例如: 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"
}
echo "========================================================"
echo " 🛡️ 欢迎使用 IP-Sentinel (边缘节点 Edge Agent)"
echo " 当前安装包版本: v${TARGET_VERSION}"
echo "========================================================"
# 1. 依赖检查与安装 (新增 python3 用于轻量级 Webhook 服务)
@@ -112,9 +123,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 +154,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,9 +174,9 @@ 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
@@ -169,8 +194,8 @@ if [ "$UPGRADE_MODE" == "false" ]; then
CITY_ID="${CITY_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"
@@ -307,13 +332,34 @@ 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
echo -e "\033[32m✅ 哨兵锚点已永久锁定至: $BIND_IP\033[0m"
# 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"
# ========================================================================
# 5. 远程拉取冷数据并解析固化
@@ -333,9 +379,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,8 +401,9 @@ 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"
EOF
@@ -366,6 +414,45 @@ 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
fi
# ========================================================================
# 6. 拉取全套组件 (按需下载,绝不浪费空间)
echo -e "\n[6/7] 正在根据模块开关部署核心引擎与热数据..."
# 确保目录在升级模式下也能被正确建立
@@ -404,8 +491,11 @@ crontab -l 2>/dev/null | grep -v "ip_sentinel" > /tmp/cron_backup
# 核心养护模块: 每 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升级) 每天凌晨 3 点触发,由中枢自动进行分频调度
echo "0 3 * * * ${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
@@ -414,8 +504,8 @@ if [[ -n "$TG_TOKEN" ]] && [[ -n "$CHAT_ID" ]]; then
# [v3.0.1新增修改 3: 删除原来的 curl 取 IP直接使用我们上方锁定的 BIND_IP]
# 并提前写入 IP 缓存,彻底阻断 agent_daemon 首次启动时的重复推送
# [修复竞态]: 提前写入 IP 缓存,彻底阻断 agent_daemon 首次启动时的抢跑推送
echo "$BIND_IP" > "${INSTALL_DIR}/core/.last_ip"
# [修复竞态]: 提前写入公网 IP 缓存,彻底阻断 agent_daemon 首次启动时的抢跑推送
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
@@ -428,32 +518,65 @@ 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.3.2引入的防撞甲,已修正连接符)
IP_HASH=$(echo "${SAFE_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}"
REG_MSG="#REGISTER#|${REGION_CODE}|${NODE_NAME}|${SAFE_PUBLIC_IP}|${AGENT_PORT}"
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_NAME}\`
🌐 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_NAME}\`
🌐 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,7 +609,12 @@ 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
FW_MSG="iptables -I INPUT -p tcp --dport $AGENT_PORT -j ACCEPT"
# 智能双栈雷达:根据对外公网 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"
fi
fi
echo -e "\033[33m⚠ 警告:请务必确保本机及云服务商安全组放行了 TCP $AGENT_PORT 端口!\033[0m"

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)

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# ==========================================================
# 脚本名称: mod_trust.sh (IP 信用净化模块 V3.1.4 拓扑自适应版)
# 脚本名称: mod_trust.sh (IP 信用净化模块 - 动态锚点版)
# 核心功能: 动态扫描本地 LBS 冷数据,提取权威白名单,执行流量净化
# ==========================================================
@@ -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 ))

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# ==========================================================
# 脚本名称: runner.sh (IP-Sentinel 主控调度引擎 V2.0 智能分配版)
# 脚本名称: runner.sh (IP-Sentinel 主控调度引擎 - 动态锚点版)
# 核心功能: 防并发延迟启动、功能开关(Feature Flag)自适应、多模块概率轮盘调度
# ==========================================================
@@ -15,14 +15,18 @@ if [ ! -f "$CONFIG_FILE" ]; then
fi
source "$CONFIG_FILE"
# 2. 全局日志写入函数 (导出给子进程共享使用)
# 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,7 +19,9 @@ if [ -z "$TG_TOKEN" ] || [ -z "$CHAT_ID" ]; then
fi
# 2. 节点元数据抓取 (v3.2.2 协议自适应与多级容灾版)
NODE_NAME=$(hostname | cut -c 1-15)
# [v3.3.2 修复: 引入 IP 哈希防同名覆盖机制]
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}"
# --- [防线 1: 底层路由锁定与协议自适应] ---
CURL_BIND_OPT=""
@@ -36,8 +38,8 @@ 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}]"
@@ -153,12 +155,41 @@ else
🕒 **最近执行快照 [${LAST_MOD:-"System"}]:**
时间: ${LAST_TIME:-"暂无数据"}
结论: ${LAST_SCORE:-"暂无数据"}
----------------------------
💡 哨兵正在后台默默守护您的资产。"
结论: ${LAST_SCORE:-"暂无数据"}"
fi
# ==========================================
# 5. [核心: OTA 云端版本探针与告警模块]
# ==========================================
# 从配置文件提取当前本地版本,若无则默认为未知
LOCAL_VER="${AGENT_VERSION:-未知}"
# 极轻量级探针: 抓取 GitHub 云端的 version.txt (超时 3 秒)
REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main"
REMOTE_VER=$(curl -s -m 3 "${REPO_RAW_URL}/version.txt" | 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,7 +1,7 @@
#!/bin/bash
# ==========================================================
# 脚本名称: uninstall.sh (IP-Sentinel 一键卸载脚本 V3.1.4 焦土版)
# 脚本名称: uninstall.sh (IP-Sentinel 一键卸载脚本 - 动态锚点版)
# 核心功能: 无痕清理守护进程、定时任务、运行目录及临时缓存
# ==========================================================
@@ -9,6 +9,13 @@ 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. 停止运行中的守护进程与主控模块 (涵盖所有历史版本进程)
@@ -17,6 +24,8 @@ echo "[1/3] 正在终止后台守护进程与所有养护任务..."
# 使用 pkill 替代传统的 pgrep | xargs指令更短、容错率更高
pkill -9 -f "tg_daemon.sh" >/dev/null 2>&1
pkill -9 -f "agent_daemon.sh" >/dev/null 2>&1
# [v3.4.0 优化] 确保清理所有 python3 调起的 Webhook 实例
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

View File

@@ -1,16 +1,16 @@
#!/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"
# 1. 加载本地冷数据配置
if [ ! -f "$CONFIG_FILE" ]; then
@@ -18,57 +18,106 @@ 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 '[]')
CURL_CMD="$CURL_CMD --interface $RAW_BIND_IP"
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"

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

@@ -0,0 +1,15 @@
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,33 @@
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
kampf der realitystars
манчестер юнайтед лидс
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

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

@@ -0,0 +1,15 @@
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,32 @@
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,33 @@
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,36 @@
リバプール
abema
champions league
wowow
エルニーニョ
アトレティコ 対 バルセロナ
オープンワールド
atlético madrid vs barcelona
松田好花
リコール
man united vs leeds
白鵬翔
日本アカデミー賞 最優秀助演男優賞
マンu 対 リーズ u
サンディスク 株価
らじるらじる
マクドナルド
ロシア
広島市
ゲイブル・スティーブソン
日本維新の会
新 日本 繊維
高見沢 俊彦
不登校
後期高齢者医療制度
バーミヤン
宮澤エマ
チケプラ
横綱
宮里美香
東京 天気 明日
新宿 おすすめ 居酒屋
最新のニュース 速報
ゴールド 相場 チャート
近くの静かなカフェ
地震 速報
円安 影響 生活
円安 影響 生活

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

@@ -0,0 +1,15 @@
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,33 @@
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

View File

@@ -1,3 +1,33 @@
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,33 @@
psg
barca
vix
fcb
barcelona schedule
univision
paramount
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

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

@@ -0,0 +1,15 @@
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,179 @@
{
"version": "3.1.0",
"updated_at": "2026-04-11",
"countries": [
"version": "3.5.0",
"updated_at": "2026-04-15",
"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": "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": "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": "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": "CA",
"name": "California (加)",
"cities": [
{ "id": "Los_Angeles", "name": "Los Angeles (洛杉矶)" },
{ "id": "San_Jose", "name": "San Jose (圣何塞)" }
]
}
]
},
{
"id": "JP",
"name": "Japan (日本)",
"keyword_file": "kw_JP.txt",
"states": [
{
"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 (香港)" }
"name": "Canada (加拿大)",
"keyword_file": "kw_CA.txt",
"states": [
{
"id": "Default",
"name": "Default State",
"cities": [
{ "id": "Toronto", "name": "Toronto (多伦多)" }
]
}
]
}
]
}
]
}
}

View File

@@ -0,0 +1,20 @@
{
"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://en.wikipedia.org/wiki/Special:Random",
"https://www.canada.ca/en.html",
"https://www.cbc.ca/",
"https://www.thestar.com/",
"https://www.ctvnews.ca/",
"https://www.canadapost-postescanada.ca/",
"https://www.td.com/"
]
}
}

View File

@@ -0,0 +1,20 @@
{
"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://es.wikipedia.org/wiki/Especial:Aleatoria",
"https://www.elmundo.es/",
"https://www.elpais.com/",
"https://www.marca.com/",
"https://www.rtve.es/",
"https://www.zara.com/es/",
"https://www.elcorteingles.es/"
]
}
}

View File

@@ -0,0 +1,20 @@
{
"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://nl.wikipedia.org/wiki/Speciaal:Willekeurig",
"https://www.rijksoverheid.nl/",
"https://www.nos.nl/",
"https://www.bol.com/",
"https://www.nu.nl/",
"https://www.buienradar.nl/",
"https://www.telegraaf.nl/"
]
}
}

View File

@@ -0,0 +1,20 @@
{
"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://vi.wikipedia.org/wiki/Đặc_biệt:Ngẫu_nhiên",
"https://chinhphu.vn/",
"https://vnexpress.net/",
"https://tuoitre.vn/",
"https://vtv.vn/",
"https://shopee.vn/",
"https://tiki.vn/"
]
}
}

View File

@@ -1,21 +1,26 @@
#!/bin/bash
# ==========================================================
# 脚本名称: install_master.sh (IP-Sentinel 控制中枢部署脚本 v3.2.2)
# 脚本名称: install_master.sh (IP-Sentinel 控制中枢部署脚本 - 动态锚点版)
# 核心功能: 部署/卸载调度中枢、SQLite 资产管理、平滑热更新引擎
# ==========================================================
# [新增] 提取仓库直链前缀变量,方便后续在官方库和私库间一键切换
# 你的 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"
# [核心: 动态获取全局版本控制锚点 (Single Source of Truth)]
TARGET_VERSION=$(curl -s -m 3 "${REPO_RAW_URL}/version.txt" | 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 "========================================================"
# [新增] 交互式操作菜单:支持选择部署或调用卸载程序
@@ -50,7 +55,15 @@ if [ "$ACTION_CHOICE" == "1" ] && [ -f "${MASTER_DIR}/master.conf" ]; then
# 汲取原配置进入内存
source "${MASTER_DIR}/master.conf"
echo -e "\033[32m✅ 已激活 [平滑升级模式],即将跳过基础配置,直接更新核心中枢...\033[0m"
# [v3.4.0 核心] 升级后立即同步/补录版本号至配置文件
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
@@ -97,6 +110,8 @@ if [ "$UPGRADE_MODE" == "false" ]; then
read -p "请输入 Telegram Bot Token: " TG_TOKEN
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"

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# ==========================================================
# 脚本名称: tg_master.sh (Master 端调度枢纽 V3.0.4 动态签名版)
# 脚本名称: tg_master.sh (Master 端调度枢纽 - 动态锚点版)
# 核心功能: 监听 TG、操作 SQLite、Webhook 精准调度、403权限拦截、僵尸节点清理
# ==========================================================
@@ -9,6 +9,12 @@ CONF="/opt/ip_sentinel_master/master.conf"
[ ! -f "$CONF" ] && exit 1
source "$CONF"
# [核心: 运行态版本继承与云通信地址]
REPO_RAW_URL="https://raw.githubusercontent.com/hotyue/IP-Sentinel/main"
# MASTER_VERSION 已经在上方的 source "$CONF" 中被载入
# 如果本地极度陈旧没有该变量,才给定一个基础兜底值,避免变量为空导致崩溃
MASTER_VERSION=${MASTER_VERSION:-"3.5.0"}
OFFSET_FILE="${MASTER_DIR}/.tg_offset"
[[ -f $OFFSET_FILE ]] || echo "0" > $OFFSET_FILE
@@ -117,7 +123,7 @@ while true; do
# 入库时追加 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)"
send_msg "$CHAT_ID" "**司令部确认 (v${MASTER_VERSION})**\n节点接入成功: \`$NODE_NAME\`\n地址: \`$AGENT_IP:$AGENT_PORT\`"
# ================== [v3.1.3 丝滑连招: 直接呼出全球大区雷达] ==================
REGION_DATA=$(db_exec "SELECT region, COUNT(*) FROM nodes WHERE chat_id='$CHAT_ID' GROUP BY region;")
@@ -129,6 +135,7 @@ 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 +152,16 @@ while true; do
# ==========================================
case "$TEXT" in
"/start"|"/menu")
# [v3.4.0 核心] 抓取云端最新版本
REMOTE_VER=$(curl -s -m 2 "${REPO_RAW_URL}/version.txt" | tr -d '[:space:]')
VER_INFO="当前版本: \`v${MASTER_VERSION}\`"
if [ -n "$REMOTE_VER" ] && [ "$REMOTE_VER" != "$MASTER_VERSION" ]; then
VER_INFO="${VER_INFO}\n✨ **发现新版本**: \`v${REMOTE_VER}\` (请尽快更新主控)"
fi
BTNS="[[{\"text\":\"🖥️ 我的节点列表\",\"callback_data\":\"list_nodes\"}], [{\"text\":\"🚀 全节点日报汇总\",\"callback_data\":\"all_reports\"}], [{\"text\":\"🛠️ 全节点一键维护\",\"callback_data\":\"all_run\"}]]"
send_ui "$CHAT_ID" "🛡️ **IP-Sentinel 司令部**\n欢迎回来长官。请下达指令" "$BTNS"
send_ui "$CHAT_ID" "🛡️ **IP-Sentinel 司令部**\n${VER_INFO}\n\n欢迎回来,长官。请下达指令:" "$BTNS"
;;
"all_reports")
@@ -190,8 +205,9 @@ while true; do
[ -z "$REGION_NAME" ] && REGION_NAME="UNKNOWN"
FLAG="🌐"
case "$REGION_NAME" in
"US") FLAG="🇺🇸" ;; "JP") FLAG="🇯🇵" ;; "HK") FLAG="🇭🇰" ;;
"SG") FLAG="🇸🇬" ;; "UK"|"GB") FLAG="🇬🇧" ;; "DE") FLAG="🇩🇪" ;; "FR") FLAG="🇫🇷" ;;
"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"

View File

@@ -1,14 +1,21 @@
#!/bin/bash
# ==========================================================
# 脚本名称: uninstall_master.sh (IP-Sentinel Master 一键卸载脚本)
# 脚本名称: uninstall_master.sh (IP-Sentinel Master 一键卸载脚本 - 动态锚点版)
# 核心功能: 终止调度进程、清理看门狗定时任务、抹除数据库与配置
# ==========================================================
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 数据库!"
@@ -20,7 +27,8 @@ fi
# 1. 停止运行中的 Master 守护进程
echo "[1/3] 正在终止后台中枢调度进程..."
pgrep -f tg_master.sh | xargs -r kill -9 >/dev/null 2>&1
# [优化] 使用 pkill 替代 pgrep | xargs指令更短、容错率更高
pkill -9 -f "tg_master.sh" >/dev/null 2>&1 || true
# 2. 清除看门狗定时任务 (Cron)
echo "[2/3] 正在清理系统定时任务 (Cron)..."

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)

1
version.txt Normal file
View File

@@ -0,0 +1 @@
3.5.0