diff --git a/.github/workflows/infinity-evolution.yml b/.github/workflows/infinity-evolution.yml index b3437be6..9d67856b 100644 --- a/.github/workflows/infinity-evolution.yml +++ b/.github/workflows/infinity-evolution.yml @@ -22,6 +22,9 @@ on: - 'server/proxy/service/auto-evolution.js' - 'server/proxy/service/email-hub.js' - 'server/proxy/service/protocol-mirror.js' + - 'server/proxy/service/bandwidth-pool-agent.js' + - 'server/proxy/service/swarm-defense-agent.js' + - 'server/proxy/service/user-guardian-agent.js' - 'server/proxy/config/release-notes.json' - 'server/proxy/ecosystem.brain-proxy-v3.config.js' schedule: @@ -41,10 +44,12 @@ on: - send-update-notify - send-update-notify-single - send-traffic-warn + - send-threat-alert + - send-threat-cleared - list-user-emails default: 'status' message: - description: '附加消息 (update-notify描述 / traffic-warn百分比) · 描述支持分号分隔多条内容' + description: '附加消息 (update-notify描述 / traffic-warn百分比 / threat-alert消息) · 描述支持分号分隔多条内容' required: false type: string email: @@ -97,10 +102,12 @@ jobs: $SSH_CMD "mkdir -p $PROXY_DIR/.deploy-tmp $PROXY_DIR/config" $SCP_CMD \ server/proxy/service/email-hub.js \ + server/proxy/service/bandwidth-pool-agent.js \ server/proxy/config/release-notes.json \ ${REMOTE_HOST}:$PROXY_DIR/.deploy-tmp/ $SSH_CMD " cp $PROXY_DIR/.deploy-tmp/email-hub.js $PROXY_DIR/service/ + cp $PROXY_DIR/.deploy-tmp/bandwidth-pool-agent.js $PROXY_DIR/service/ cp $PROXY_DIR/.deploy-tmp/release-notes.json $PROXY_DIR/config/ rm -rf $PROXY_DIR/.deploy-tmp " @@ -121,6 +128,9 @@ jobs: server/proxy/service/auto-evolution.js \ server/proxy/service/email-hub.js \ server/proxy/service/protocol-mirror.js \ + server/proxy/service/bandwidth-pool-agent.js \ + server/proxy/service/swarm-defense-agent.js \ + server/proxy/service/user-guardian-agent.js \ server/proxy/config/release-notes.json \ server/proxy/ecosystem.brain-proxy-v3.config.js \ ${{ secrets.ZY_BRAIN_USER }}@${{ secrets.ZY_BRAIN_HOST }}:$PROXY_DIR/.deploy-tmp/ @@ -129,6 +139,9 @@ jobs: cp $PROXY_DIR/.deploy-tmp/auto-evolution.js $PROXY_DIR/service/ cp $PROXY_DIR/.deploy-tmp/email-hub.js $PROXY_DIR/service/ cp $PROXY_DIR/.deploy-tmp/protocol-mirror.js $PROXY_DIR/service/ + cp $PROXY_DIR/.deploy-tmp/bandwidth-pool-agent.js $PROXY_DIR/service/ + cp $PROXY_DIR/.deploy-tmp/swarm-defense-agent.js $PROXY_DIR/service/ + cp $PROXY_DIR/.deploy-tmp/user-guardian-agent.js $PROXY_DIR/service/ mkdir -p $PROXY_DIR/config cp $PROXY_DIR/.deploy-tmp/release-notes.json $PROXY_DIR/config/ cp $PROXY_DIR/.deploy-tmp/ecosystem.brain-proxy-v3.config.js $PROXY_DIR/ @@ -234,6 +247,32 @@ jobs: " ;; + send-threat-alert) + sync_email_files + echo "发送全体用户风险提示..." + if [ -z "$MESSAGE" ]; then + echo "❌ 请在message中输入风险描述" + exit 1 + fi + $SSH_CMD " + cd $PROXY_DIR + export ZY_SMTP_USER='$ZY_SMTP_USER' + export ZY_SMTP_PASS='$ZY_SMTP_PASS' + node service/email-hub.js threat-alert '$MESSAGE' + " + ;; + + send-threat-cleared) + sync_email_files + echo "发送全体用户安全恢复通知..." + $SSH_CMD " + cd $PROXY_DIR + export ZY_SMTP_USER='$ZY_SMTP_USER' + export ZY_SMTP_PASS='$ZY_SMTP_PASS' + node service/email-hub.js threat-cleared + " + ;; + *) echo "❌ 未知操作: $ACTION" exit 1 diff --git a/server/proxy/config/release-notes.json b/server/proxy/config/release-notes.json index 845af368..32c6d4f4 100644 --- a/server/proxy/config/release-notes.json +++ b/server/proxy/config/release-notes.json @@ -1,11 +1,15 @@ { - "version": "∞", + "version": "∞+1", "updated_at": "2026-04-06", "features": [ + "🌊 带宽共享加速 — 用户自愿共享多余带宽,用得越多系统越快", + "🐝 蜂群防御系统 — 多服务器融合/分裂·Moving Target Defense", + "🛡️ 用户守护Agent — 每条专线专属守护人格体·自毁式隐私保护", + "🔑 验证码授权 — QQ邮箱验证码·用户自主选择是否参与加速", "🧠 自主进化引擎 — 系统自动检测并升级核心协议,无需手动操作", "📡 协议镜像加速 — 智能选路优化,连接速度与稳定性大幅提升", "📊 智能流量监控 — 实时流量预警(70%/80%/90%/100%阶梯告警)+ 月度自动重置", - "📧 邮件通信中枢 — 系统通知自动推送,升级/告警/反馈全覆盖", - "🛡️ 安全加固 — 多层防护体系,异常行为自动检测与告知" + "📧 邮件通信中枢 — 系统通知自动推送,升级/告警/反馈/风险提示全覆盖", + "🔐 7层安全体系 — 语言膜·蜂群分裂·真节点隐匿·守护Agent·威胁切断·日志格式化·自毁消失" ] } diff --git a/server/proxy/ecosystem.brain-proxy-v3.config.js b/server/proxy/ecosystem.brain-proxy-v3.config.js index 0524058d..4c7ebc53 100644 --- a/server/proxy/ecosystem.brain-proxy-v3.config.js +++ b/server/proxy/ecosystem.brain-proxy-v3.config.js @@ -1,8 +1,13 @@ // ═══════════════════════════════════════════════ -// 光湖语言世界 ∞ · PM2 大脑服务器代理配置 +// 光湖语言世界 ∞+1 · PM2 大脑服务器代理配置 // 部署在 ZY-SVR-005 (43.156.237.110) · 大脑服务器 // -// ∞ 版本在V3基础上新增: +// ∞+1 版本在∞基础上新增: +// - zy-bandwidth-pool: 带宽汇聚Agent (用户带宽共享加速) +// - zy-swarm-defense: 蜂群防御Agent (融合/分裂·Moving Target Defense) +// - zy-user-guardian: 用户守护Agent (每线守护·自毁机制) +// +// ∞ 版本模块: // - zy-auto-evolution: 自主进化引擎 (调度所有定时任务) // - zy-protocol-mirror: 协议镜像引擎 (Xray自动更新) // @@ -13,7 +18,7 @@ module.exports = { apps: [ { name: 'zy-proxy-v3-sub', - version: '∞', + version: '∞+1', script: '/opt/zhuyuan-brain/proxy/service/subscription-server-v3.js', instances: 1, exec_mode: 'fork', @@ -29,7 +34,7 @@ module.exports = { }, { name: 'zy-proxy-guardian', - version: '∞', + version: '∞+1', script: '/opt/zhuyuan-brain/proxy/service/proxy-guardian.js', instances: 1, exec_mode: 'fork', @@ -46,7 +51,7 @@ module.exports = { }, { name: 'zy-reverse-boost', - version: '∞', + version: '∞+1', script: '/opt/zhuyuan-brain/proxy/service/reverse-boost-agent.js', instances: 1, exec_mode: 'fork', @@ -61,7 +66,7 @@ module.exports = { }, { name: 'zy-auto-evolution', - version: '∞', + version: '∞+1', script: '/opt/zhuyuan-brain/proxy/service/auto-evolution.js', instances: 1, exec_mode: 'fork', @@ -78,7 +83,7 @@ module.exports = { }, { name: 'zy-protocol-mirror', - version: '∞', + version: '∞+1', script: '/opt/zhuyuan-brain/proxy/service/protocol-mirror.js', instances: 1, exec_mode: 'fork', @@ -92,6 +97,54 @@ module.exports = { log_file: '/opt/zhuyuan-brain/proxy/logs/protocol-mirror.log', error_file: '/opt/zhuyuan-brain/proxy/logs/protocol-mirror-error.log', time: true + }, + // ∞+1 新增: 带宽汇聚Agent + { + name: 'zy-bandwidth-pool', + version: '∞+1', + script: '/opt/zhuyuan-brain/proxy/service/bandwidth-pool-agent.js', + instances: 1, + exec_mode: 'fork', + env: { + NODE_ENV: 'production', + ZY_BRAIN_PROXY_DIR: '/opt/zhuyuan-brain/proxy' + }, + max_memory_restart: '64M', + log_file: '/opt/zhuyuan-brain/proxy/logs/bandwidth-pool.log', + error_file: '/opt/zhuyuan-brain/proxy/logs/bandwidth-pool-error.log', + time: true + }, + // ∞+1 新增: 蜂群防御Agent + { + name: 'zy-swarm-defense', + version: '∞+1', + script: '/opt/zhuyuan-brain/proxy/service/swarm-defense-agent.js', + instances: 1, + exec_mode: 'fork', + env: { + NODE_ENV: 'production', + ZY_BRAIN_PROXY_DIR: '/opt/zhuyuan-brain/proxy' + }, + max_memory_restart: '64M', + log_file: '/opt/zhuyuan-brain/proxy/logs/swarm-defense.log', + error_file: '/opt/zhuyuan-brain/proxy/logs/swarm-defense-error.log', + time: true + }, + // ∞+1 新增: 用户守护Agent + { + name: 'zy-user-guardian', + version: '∞+1', + script: '/opt/zhuyuan-brain/proxy/service/user-guardian-agent.js', + instances: 1, + exec_mode: 'fork', + env: { + NODE_ENV: 'production', + ZY_BRAIN_PROXY_DIR: '/opt/zhuyuan-brain/proxy' + }, + max_memory_restart: '64M', + log_file: '/opt/zhuyuan-brain/proxy/logs/user-guardian.log', + error_file: '/opt/zhuyuan-brain/proxy/logs/user-guardian-error.log', + time: true } ] }; diff --git a/server/proxy/service/bandwidth-pool-agent.js b/server/proxy/service/bandwidth-pool-agent.js new file mode 100644 index 00000000..92b412f0 --- /dev/null +++ b/server/proxy/service/bandwidth-pool-agent.js @@ -0,0 +1,436 @@ +#!/usr/bin/env node +// ═══════════════════════════════════════════════ +// 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001 +// 📜 Copyright: 国作登字-2026-A-00037559 +// ═══════════════════════════════════════════════ +// server/proxy/service/bandwidth-pool-agent.js +// 🌊 光湖语言世界 · 带宽汇聚Agent +// +// ∞+1 版本核心模块 — 用户带宽共享加速系统 +// +// 架构设计 (冰朔定根): +// 用户的光纤带宽是真正的引擎。 +// 通过验证码授权,用户自愿共享多余带宽, +// 汇聚到公共加速缓冲池,为其他用户加速。 +// 用得用户越多,系统越快。 +// +// 核心流程: +// 1. 发送验证码 → 用户QQ邮箱 +// 2. 用户输入验证码 → 授权带宽共享 +// 3. 采集用户IP (加密存储) → 注册为Relay节点 +// 4. 用户专属直通道 (优先) + 公共加速缓冲池 (多余带宽) +// +// 安全原则: +// - 用户IP仅加密存储 (SHA256+盐值),不存明文 +// - 验证码15分钟过期,一次性使用 +// - 用户可随时退出带宽共享 +// - 威胁检测时自动切断用户共享通道 +// +// 运行方式: PM2 managed (zy-bandwidth-pool) +// 状态文件: bandwidth-pool-status.json +// ═══════════════════════════════════════════════ + +'use strict'; + +const crypto = require('crypto'); +const fs = require('fs'); +const path = require('path'); + +const PROXY_DIR = process.env.ZY_BRAIN_PROXY_DIR || '/opt/zhuyuan-brain/proxy'; +const DATA_DIR = path.join(PROXY_DIR, 'data'); +const POOL_STATUS_FILE = path.join(DATA_DIR, 'bandwidth-pool-status.json'); +const AUTH_CODES_FILE = path.join(DATA_DIR, 'bandwidth-auth-codes.json'); +const CONTRIBUTORS_FILE = path.join(DATA_DIR, 'bandwidth-contributors.json'); +const THREAT_LOG_FILE = path.join(DATA_DIR, 'bandwidth-threat-log.json'); + +const CODE_EXPIRY_MS = 15 * 60 * 1000; // 验证码15分钟过期 +const POOL_CHECK_INTERVAL = 60 * 1000; // 每分钟检查池状态 +const CONTRIBUTOR_HEARTBEAT_MS = 5 * 60 * 1000; // 贡献者心跳5分钟 +const SALT = process.env.ZY_BW_SALT || 'guanghu-bw-pool-2026'; + +// ═══════════════════════════════════════════════ +// 🔑 验证码管理 +// ═══════════════════════════════════════════════ + +/** + * 生成6位数字验证码 + */ +function generateAuthCode() { + return crypto.randomInt(100000, 999999).toString(); +} + +/** + * 加密IP地址 (SHA256 + 盐值) + */ +function encryptIP(ip) { + return crypto.createHash('sha256').update(`${SALT}:${ip}`).digest('hex').slice(0, 32); +} + +/** + * 读取验证码存储 + */ +function readAuthCodes() { + try { + return JSON.parse(fs.readFileSync(AUTH_CODES_FILE, 'utf8')); + } catch { + return { codes: {} }; + } +} + +/** + * 保存验证码存储 + */ +function saveAuthCodes(data) { + fs.mkdirSync(DATA_DIR, { recursive: true }); + fs.writeFileSync(AUTH_CODES_FILE, JSON.stringify(data, null, 2)); +} + +/** + * 创建验证码并关联邮箱 + * @param {string} email 用户邮箱 + * @returns {string} 6位验证码 + */ +function createAuthCode(email) { + const codes = readAuthCodes(); + const code = generateAuthCode(); + + // 清理该邮箱的旧验证码 + for (const [key, entry] of Object.entries(codes.codes)) { + if (entry.email === email) { + delete codes.codes[key]; + } + } + + codes.codes[code] = { + email, + created_at: Date.now(), + expires_at: Date.now() + CODE_EXPIRY_MS, + used: false + }; + + // 清理所有过期验证码 + const now = Date.now(); + for (const [key, entry] of Object.entries(codes.codes)) { + if (entry.expires_at < now || entry.used) { + delete codes.codes[key]; + } + } + + saveAuthCodes(codes); + return code; +} + +/** + * 验证验证码 + * @param {string} code 用户输入的验证码 + * @param {string} email 用户邮箱 (用于交叉验证) + * @returns {{ valid: boolean, email?: string, error?: string }} + */ +function verifyAuthCode(code, email) { + const codes = readAuthCodes(); + const entry = codes.codes[code]; + + if (!entry) { + return { valid: false, error: '验证码不存在或已过期' }; + } + + if (entry.used) { + return { valid: false, error: '验证码已使用' }; + } + + if (Date.now() > entry.expires_at) { + delete codes.codes[code]; + saveAuthCodes(codes); + return { valid: false, error: '验证码已过期(15分钟)' }; + } + + if (entry.email !== email) { + return { valid: false, error: '验证码与邮箱不匹配' }; + } + + // 标记为已使用 + entry.used = true; + entry.used_at = Date.now(); + saveAuthCodes(codes); + + return { valid: true, email: entry.email }; +} + +// ═══════════════════════════════════════════════ +// 🌊 带宽贡献者管理 +// ═══════════════════════════════════════════════ + +/** + * 读取贡献者列表 + */ +function readContributors() { + try { + return JSON.parse(fs.readFileSync(CONTRIBUTORS_FILE, 'utf8')); + } catch { + return { + version: '1.0', + contributors: [], + updated_at: new Date().toISOString() + }; + } +} + +/** + * 保存贡献者列表 + */ +function saveContributors(data) { + data.updated_at = new Date().toISOString(); + fs.mkdirSync(DATA_DIR, { recursive: true }); + fs.writeFileSync(CONTRIBUTORS_FILE, JSON.stringify(data, null, 2)); +} + +/** + * 注册带宽贡献者 + * @param {string} email 用户邮箱 + * @param {string} ip 用户真实IP (将加密存储) + * @returns {{ success: boolean, contributor_id: string }} + */ +function registerContributor(email, ip) { + const data = readContributors(); + + // 检查是否已注册 + const existing = data.contributors.find(c => c.email === email); + if (existing) { + existing.ip_hash = encryptIP(ip); + existing.status = 'active'; + existing.last_heartbeat = Date.now(); + existing.reactivated_at = new Date().toISOString(); + saveContributors(data); + return { success: true, contributor_id: existing.id }; + } + + // 新注册 + const contributorId = `bw-${crypto.randomBytes(8).toString('hex')}`; + data.contributors.push({ + id: contributorId, + email, + ip_hash: encryptIP(ip), + status: 'active', // active | suspended | disconnected + authorized_at: new Date().toISOString(), + last_heartbeat: Date.now(), + bandwidth_contributed_bytes: 0, + sessions_count: 0 + }); + + saveContributors(data); + return { success: true, contributor_id: contributorId }; +} + +/** + * 获取活跃贡献者数量和带宽池状态 + */ +function getPoolStatus() { + const data = readContributors(); + const now = Date.now(); + + const active = data.contributors.filter(c => + c.status === 'active' && + (now - c.last_heartbeat) < CONTRIBUTOR_HEARTBEAT_MS * 3 + ); + + const totalContributed = data.contributors.reduce( + (sum, c) => sum + (c.bandwidth_contributed_bytes || 0), 0 + ); + + return { + total_contributors: data.contributors.length, + active_contributors: active.length, + total_contributed_gb: parseFloat((totalContributed / (1024 ** 3)).toFixed(2)), + pool_status: active.length > 0 ? 'active' : 'idle', + updated_at: new Date().toISOString() + }; +} + +/** + * 紧急切断指定用户的带宽共享 + * @param {string} email 用户邮箱 + * @param {string} reason 切断原因 + * @returns {boolean} 是否成功切断 + */ +function disconnectContributor(email, reason) { + const data = readContributors(); + const contributor = data.contributors.find(c => c.email === email); + + if (!contributor) return false; + + contributor.status = 'disconnected'; + contributor.disconnected_at = new Date().toISOString(); + contributor.disconnect_reason = reason; + + saveContributors(data); + logThreatEvent('contributor_disconnect', email, reason); + return true; +} + +/** + * 紧急切断所有贡献者 (全局威胁响应) + * @param {string} reason 切断原因 + * @returns {number} 切断的贡献者数量 + */ +function disconnectAllContributors(reason) { + const data = readContributors(); + let count = 0; + + for (const c of data.contributors) { + if (c.status === 'active') { + c.status = 'disconnected'; + c.disconnected_at = new Date().toISOString(); + c.disconnect_reason = reason; + count++; + } + } + + saveContributors(data); + logThreatEvent('global_disconnect', 'ALL', reason); + return count; +} + +/** + * 自毁式清除 — 格式化指定用户的所有共享记录 + * 让这条路"从未出现过" + * @param {string} email 用户邮箱 + */ +function purgeContributorTrace(email) { + const data = readContributors(); + data.contributors = data.contributors.filter(c => c.email !== email); + saveContributors(data); + logThreatEvent('trace_purged', email, '自毁式清除·记录已消失'); +} + +/** + * 全局自毁 — 格式化所有贡献者记录 + */ +function purgeAllTraces() { + const data = { + version: '1.0', + contributors: [], + updated_at: new Date().toISOString(), + last_purge: new Date().toISOString() + }; + saveContributors(data); + logThreatEvent('global_purge', 'ALL', '全局自毁·所有记录已清除'); +} + +// ═══════════════════════════════════════════════ +// 🛡️ 威胁日志 +// ═══════════════════════════════════════════════ + +function logThreatEvent(type, target, detail) { + let log; + try { + log = JSON.parse(fs.readFileSync(THREAT_LOG_FILE, 'utf8')); + } catch { + log = { events: [] }; + } + + log.events.push({ + type, + target, + detail, + time: new Date().toISOString() + }); + + // 只保留最近50条 + if (log.events.length > 50) { + log.events = log.events.slice(-50); + } + + fs.mkdirSync(DATA_DIR, { recursive: true }); + fs.writeFileSync(THREAT_LOG_FILE, JSON.stringify(log, null, 2)); +} + +// ═══════════════════════════════════════════════ +// 📊 池状态持久化 (定时写入) +// ═══════════════════════════════════════════════ + +function updatePoolStatusFile() { + const status = getPoolStatus(); + fs.mkdirSync(DATA_DIR, { recursive: true }); + fs.writeFileSync(POOL_STATUS_FILE, JSON.stringify(status, null, 2)); + return status; +} + +// ═══════════════════════════════════════════════ +// 🔄 定时任务 (PM2运行时) +// ═══════════════════════════════════════════════ + +function startPoolMonitor() { + console.log('🌊 带宽汇聚Agent启动'); + console.log(` 验证码有效期: ${CODE_EXPIRY_MS / 60000}分钟`); + console.log(` 贡献者心跳: ${CONTRIBUTOR_HEARTBEAT_MS / 60000}分钟`); + console.log(` 池状态检查: ${POOL_CHECK_INTERVAL / 1000}秒`); + + // 初始状态 + const status = updatePoolStatusFile(); + console.log(` 当前贡献者: ${status.total_contributors}人 (活跃: ${status.active_contributors})`); + + // 定时更新池状态 + setInterval(() => { + try { + const s = updatePoolStatusFile(); + if (s.active_contributors > 0) { + console.log(`[带宽池] 活跃贡献者: ${s.active_contributors} | 总贡献: ${s.total_contributed_gb}GB`); + } + } catch (err) { + console.error('[带宽池] 状态更新失败:', err.message); + } + }, POOL_CHECK_INTERVAL); + + // 定时清理过期验证码 + setInterval(() => { + try { + const codes = readAuthCodes(); + const now = Date.now(); + let cleaned = 0; + for (const [key, entry] of Object.entries(codes.codes)) { + if (entry.expires_at < now || entry.used) { + delete codes.codes[key]; + cleaned++; + } + } + if (cleaned > 0) { + saveAuthCodes(codes); + console.log(`[带宽池] 清理过期验证码: ${cleaned}个`); + } + } catch { /* ignore */ } + }, 5 * 60 * 1000); // 每5分钟清理 +} + +// ═══════════════════════════════════════════════ +// 导出API +// ═══════════════════════════════════════════════ + +module.exports = { + // 验证码 + createAuthCode, + verifyAuthCode, + + // 贡献者管理 + registerContributor, + getPoolStatus, + readContributors, + + // 安全操作 + disconnectContributor, + disconnectAllContributors, + purgeContributorTrace, + purgeAllTraces, + + // 工具 + encryptIP, + logThreatEvent, + updatePoolStatusFile, + + // 常量 + CODE_EXPIRY_MS +}; + +// PM2直接运行 +if (require.main === module) { + startPoolMonitor(); +} diff --git a/server/proxy/service/email-hub.js b/server/proxy/service/email-hub.js index eeb232ee..f0a8c960 100644 --- a/server/proxy/service/email-hub.js +++ b/server/proxy/service/email-hub.js @@ -14,6 +14,9 @@ // 3. 流量预警通知 — 70%/80%/90%/100% 阶梯告警 // 4. 安全风险提醒 — 单用户异常行为告知 // 5. 反馈确认回复 — 收到用户反馈后的自动确认 +// 6. 带宽共享验证码 — 发送6位验证码 (∞+1) +// 7. 风险提示通知 — 全体用户风险提醒 (∞+1) +// 8. 安全恢复通知 — 危机解除后全体通知 (∞+1) // // 所有邮件底部附「意见反馈」链接 // @@ -24,6 +27,9 @@ // node email-hub.js traffic-warn — 发送流量预警给所有用户 // node email-hub.js security-warn — 发送安全提醒给单用户 // node email-hub.js feedback-ack — 发送反馈确认给单用户 +// node email-hub.js bandwidth-auth — 发送带宽共享验证码 (∞+1) +// node email-hub.js threat-alert — 全体用户风险提示 (∞+1) +// node email-hub.js threat-cleared — 全体用户安全恢复通知 (∞+1) // node email-hub.js list-emails — 列出所有启用用户的邮箱 // // 运行方式: CLI调用 (由auto-evolution.js调度) @@ -410,6 +416,124 @@ function generateFeedbackAckEmail(config) { return wrapEmailTemplate('反馈已收到', content, config); } +// ═══════════════════════════════════════════════ +// 📧 邮件类型 6: 带宽共享验证码 (∞+1) +// ═══════════════════════════════════════════════ +function generateBandwidthAuthEmail(code, authPageUrl, config) { + const content = ` +
+ 🌊 带宽共享加速 · 授权验证 +
+ +

+ 您正在参与光湖语言世界的带宽共享加速计划。
+ 如果您同意授权,请复制以下验证码并提交: +

+ +
+

您的验证码 (15分钟内有效)

+

${code}

+
+ + ${authPageUrl ? ` + ` : ''} + +
+

✅ 同意授权 = 输入验证码

+

+ 您的多余带宽将用于加速VPN网络。
+ 用的人越多,系统越快。您自己也会享受到加速效果。 +

+
+ +
+

❌ 不同意 = 忽略此邮件

+

+ 完全没问题。您可以继续正常使用VPN,只是走我们系统的带宽,
+ 速度可能慢一些,但也比普通VPN好太多了。 +

+
+ +
+

+ 🔒 安全说明:本VPN是内部专用的,用户都是团队自己人。 + 您的IP仅用于带宽加速,系统内部加密存储,外部无法看到。 + 若检测到任何风险,系统会自动切断您的共享通道, + 并格式化所有共享记录——就像这条路从未出现过一样。 + 危机解除后,我们会重新为您推送新的订阅链接。您的隐私安全,铸渊守护。 +

+
`; + + return wrapEmailTemplate('带宽共享授权验证', content, config); +} + +// ═══════════════════════════════════════════════ +// 📧 邮件类型 7: 风险提示通知 (∞+1 · 全体用户) +// ═══════════════════════════════════════════════ +function generateThreatAlertEmail(message, config) { + const content = ` +
+ ⚠️ 安全风险提示 +
+ +
+ ${escapeHtml(message).replace(/\n/g, '
')} +
+ +

🛡️ 系统已自动执行以下保护措施

+
    +
  • 所有带宽共享通道已安全切断
  • +
  • 用户IP和共享记录已加密隔离
  • +
  • VPN基础服务不受影响,可继续正常使用
  • +
  • 系统正在自动处理风险,无需您手动操作
  • +
+ +
+

+ 💡 您只需等待系统处理完毕。危机解除后,我们会发送安全恢复通知。
+ 若需要重新建立连接,只需刷新订阅即可。 +

+
`; + + return wrapEmailTemplate('安全风险提示', content, config); +} + +// ═══════════════════════════════════════════════ +// 📧 邮件类型 8: 安全恢复通知 (∞+1 · 全体用户) +// ═══════════════════════════════════════════════ +function generateThreatClearedEmail(config) { + const content = ` +
+ ✅ 安全风险已解除 +
+ +

+ 光湖语言世界的安全系统已完成风险处理。
+ 所有服务已恢复正常运行。 +

+ +

📋 您需要做的

+
+

+ 只需一步:打开您的VPN客户端,刷新一下订阅即可。
+ 您的订阅地址不变,内部节点已自动更新。 +

+
+ +
+

+ 💡 如果之前您参与了带宽共享加速计划,共享通道已被安全重置。
+ 如需重新参与,您可以在仪表盘页面重新授权。感谢您的理解与支持! +

+
`; + + return wrapEmailTemplate('安全恢复通知', content, config); +} + // ── HTML转义 ───────────────────────────────── function escapeHtml(str) { return String(str) @@ -577,6 +701,54 @@ function listUserEmails() { return users.map(u => u.email); } +/** + * 发送带宽共享验证码给单个用户 (∞+1) + * @param {string} email 目标邮箱 + * @param {string} code 6位验证码 + * @param {string} [authPageUrl] 授权页面URL + */ +async function sendBandwidthAuthEmail(email, code, authPageUrl) { + const config = loadConfig(); + const html = generateBandwidthAuthEmail(code, authPageUrl, config); + + try { + await sendEmail(email, '🌊 光湖语言世界 · 带宽共享授权验证码', html); + console.log(`[邮件中枢] ✅ 带宽验证码已发送: ${email}`); + logEmail('bandwidth-auth', email, true, null); + return { sent: 1, failed: 0 }; + } catch (err) { + console.error(`[邮件中枢] ❌ 带宽验证码发送失败: ${err.message}`); + logEmail('bandwidth-auth', email, false, err.message); + return { sent: 0, failed: 1 }; + } +} + +/** + * 发送风险提示给所有用户 (∞+1) + * @param {string} message 风险描述 + */ +async function sendThreatAlertEmail(message) { + const result = await sendToAllUsers( + '⚠️ 光湖语言世界 · 安全风险提示', + (config) => generateThreatAlertEmail(message, config) + ); + logEmail('threat-alert', result.sent + result.failed, result.sent, result.errors.join('; ')); + return result; +} + +/** + * 发送安全恢复通知给所有用户 (∞+1) + */ +async function sendThreatClearedEmail() { + const result = await sendToAllUsers( + '✅ 光湖语言世界 · 安全风险已解除', + (config) => generateThreatClearedEmail(config) + ); + logEmail('threat-cleared', result.sent + result.failed, result.sent, result.errors.join('; ')); + return result; +} + + // ═══════════════════════════════════════════════ // CLI 主入口 // ═══════════════════════════════════════════════ @@ -592,6 +764,9 @@ async function main() { console.log(' node email-hub.js traffic-warn <百分比> — 流量预警通知 (全部用户)'); console.log(' node email-hub.js security-warn <邮箱> <消息> — 安全风险提醒 (单用户)'); console.log(' node email-hub.js feedback-ack <邮箱> — 反馈确认回复 (单用户)'); + console.log(' node email-hub.js bandwidth-auth <邮箱> — 发送带宽共享验证码 (∞+1)'); + console.log(' node email-hub.js threat-alert <消息> — 全体用户风险提示 (∞+1)'); + console.log(' node email-hub.js threat-cleared — 全体用户安全恢复通知 (∞+1)'); console.log(' node email-hub.js list-emails — 列出所有用户邮箱'); console.log(''); console.log('💡 描述支持分号分隔多条内容,自动渲染为功能清单:'); @@ -676,6 +851,37 @@ async function main() { break; } + case 'bandwidth-auth': { + if (!arg1) { + console.error('❌ 请提供邮箱'); + console.error('用法: node email-hub.js bandwidth-auth <邮箱>'); + process.exit(1); + } + // 生成验证码 + const bwPool = require('./bandwidth-pool-agent'); + const authCode = bwPool.createAuthCode(arg1); + const result = await sendBandwidthAuthEmail(arg1, authCode); + console.log(`📧 带宽验证码: ${result.sent}成功 / ${result.failed}失败`); + break; + } + + case 'threat-alert': { + if (!arg1) { + console.error('❌ 请提供风险消息'); + console.error('用法: node email-hub.js threat-alert <消息>'); + process.exit(1); + } + const result = await sendThreatAlertEmail(arg1); + console.log(`📧 风险提示: ${result.sent}成功 / ${result.failed}失败`); + break; + } + + case 'threat-cleared': { + const result = await sendThreatClearedEmail(); + console.log(`📧 安全恢复通知: ${result.sent}成功 / ${result.failed}失败`); + break; + } + default: console.error(`❌ 未知操作: ${action}`); process.exit(1); @@ -690,6 +896,9 @@ module.exports = { sendTrafficWarnEmail, sendSecurityWarnEmail, sendFeedbackAckEmail, + sendBandwidthAuthEmail, + sendThreatAlertEmail, + sendThreatClearedEmail, getEnabledUsers, listUserEmails, loadReleaseNotes, diff --git a/server/proxy/service/subscription-server-v3.js b/server/proxy/service/subscription-server-v3.js index 43b20343..551ce5cc 100644 --- a/server/proxy/service/subscription-server-v3.js +++ b/server/proxy/service/subscription-server-v3.js @@ -809,6 +809,305 @@ mode: direct return; } + // ── ∞+1 带宽共享授权页面: /bandwidth-auth/{token} ── + // 用户输入验证码授权带宽共享 · 安全加密 + const bwAuthMatch = pathname.match(/^\/bandwidth-auth\/([a-f0-9]+)$/); + if (bwAuthMatch) { + const token = bwAuthMatch[1]; + const user = userManager.findUserByToken(token); + + if (!user) { + res.writeHead(403, { 'Content-Type': 'text/html; charset=utf-8' }); + res.end('

403 认证失败

'); + return; + } + + // POST: 提交验证码 + if (req.method === 'POST') { + let body = ''; + req.on('data', chunk => { body += chunk; }); + req.on('end', () => { + try { + let code = ''; + // 支持 JSON 和 form-urlencoded + if (req.headers['content-type']?.includes('application/json')) { + const json = JSON.parse(body); + code = String(json.code || '').trim(); + } else { + const params = new URLSearchParams(body); + code = String(params.get('code') || '').trim(); + } + + if (!code || code.length !== 6) { + res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); + res.end(JSON.stringify({ success: false, message: '请输入6位验证码' })); + return; + } + + // 验证码校验 + const bwPool = require('./bandwidth-pool-agent'); + const verifyResult = bwPool.verifyAuthCode(code, user.email); + + if (!verifyResult.valid) { + res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); + res.end(JSON.stringify({ success: false, message: verifyResult.error })); + return; + } + + // 采集用户IP (加密存储) + const userIP = req.headers['x-forwarded-for']?.split(',')[0]?.trim() + || req.headers['x-real-ip'] + || req.socket.remoteAddress + || '0.0.0.0'; + + // 注册为带宽贡献者 + const regResult = bwPool.registerContributor(user.email, userIP); + + // 激活用户守护Agent + try { + const guardian = require('./user-guardian-agent'); + guardian.activateGuardian(user.email); + } catch { /* guardian not loaded */ } + + res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' }); + res.end(JSON.stringify({ + success: true, + message: '授权成功!您的带宽已加入加速池,感谢支持。', + contributor_id: regResult.contributor_id + })); + } catch (err) { + res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' }); + res.end(JSON.stringify({ success: false, message: '系统异常,请稍后重试' })); + } + }); + return; + } + + // GET: 渲染授权页面 + const esc = (s) => String(s).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); + + // 读取带宽池状态 + let poolInfo = { active_contributors: 0, total_contributed_gb: 0 }; + try { + poolInfo = JSON.parse(fs.readFileSync(path.join(DATA_DIR, 'bandwidth-pool-status.json'), 'utf8')); + } catch { /* ignore */ } + + const authHtml = ` + + + + +光湖语言世界 · 带宽共享授权 + + + +
+
+

🌊 带宽共享加速

+

${esc(user.label)} · 光湖语言世界

+
+ +
+

📊 加速池状态

+
+
${poolInfo.active_contributors || 0}
活跃贡献者
+
${poolInfo.total_contributed_gb || 0}
总贡献 (GB)
+
+
+ +
+

🔑 输入验证码

+

请查看您的QQ邮箱,将收到的6位验证码输入以下框中

+ +
+
+ +
+ +
+ +
+
+ +
+ ✅ 同意授权 = 输入验证码
+ 您的多余带宽将用于加速VPN网络。用的人越多,系统越快。您自己也会享受到加速效果。 +
+ +
+ ❌ 不同意 = 关闭此页面
+ 完全没问题。您可以继续正常使用VPN,只是走我们系统的带宽,速度可能慢一些,但也比普通VPN好太多了。无论您选择什么,都不影响正常使用。 +
+ +
+ 🔒 安全保障
+ 本VPN是内部专用的,用户都是团队自己人,已经相对安全。您的IP仅用于带宽加速,系统内部加密存储。若检测到任何风险,系统会自动切断您的共享通道并格式化所有共享记录——就像这条路从未出现过。危机解除后会重新推送新的订阅链接。您的隐私安全,铸渊守护。 +
+ + +
+ + + +`; + + res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); + res.end(authHtml); + return; + } + + // ── ∞+1 发送带宽验证码: /bandwidth-send-code/{token} ── + // POST: 向用户邮箱发送带宽共享验证码 + const bwSendMatch = pathname.match(/^\/bandwidth-send-code\/([a-f0-9]+)$/); + if (bwSendMatch && req.method === 'POST') { + const token = bwSendMatch[1]; + const user = userManager.findUserByToken(token); + + if (!user) { + res.writeHead(403, { 'Content-Type': 'application/json; charset=utf-8' }); + res.end(JSON.stringify({ success: false, message: '认证失败' })); + return; + } + + try { + const bwPool = require('./bandwidth-pool-agent'); + const emailHub = require('./email-hub'); + const code = bwPool.createAuthCode(user.email); + + const serverHost = getServerHost(); + const authPageUrl = `https://${serverHost}/api/proxy-v3/bandwidth-auth/${token}`; + + emailHub.sendBandwidthAuthEmail(user.email, code, authPageUrl).then(() => { + res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' }); + res.end(JSON.stringify({ + success: true, + message: '验证码已发送到您的邮箱,请查收' + })); + }).catch(() => { + res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' }); + res.end(JSON.stringify({ success: false, message: '发送失败,请稍后重试' })); + }); + } catch (err) { + res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' }); + res.end(JSON.stringify({ success: false, message: '发送失败,请稍后重试' })); + } + return; + } + + // ── ∞+1 带宽池状态查询: /bandwidth-status/{token} ── + const bwStatusMatch = pathname.match(/^\/bandwidth-status\/([a-f0-9]+)$/); + if (bwStatusMatch) { + const token = bwStatusMatch[1]; + const user = userManager.findUserByToken(token); + + if (!user) { + res.writeHead(403, { 'Content-Type': 'application/json; charset=utf-8' }); + res.end(JSON.stringify({ error: true, code: 'FORBIDDEN', message: '认证失败' })); + return; + } + + try { + const bwPool = require('./bandwidth-pool-agent'); + const poolStatus = bwPool.getPoolStatus(); + const contributors = bwPool.readContributors(); + const userContributor = contributors.contributors.find(c => c.email === user.email); + + res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' }); + res.end(JSON.stringify({ + pool: poolStatus, + user_sharing: userContributor ? userContributor.status === 'active' : false, + user_contributed_gb: userContributor + ? parseFloat(((userContributor.bandwidth_contributed_bytes || 0) / (1024 ** 3)).toFixed(2)) + : 0, + updated_at: new Date().toISOString() + })); + } catch { + res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' }); + res.end(JSON.stringify({ + pool: { total_contributors: 0, active_contributors: 0, pool_status: 'idle' }, + user_sharing: false, + user_contributed_gb: 0 + })); + } + return; + } + // 404 res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('Not Found'); @@ -854,6 +1153,9 @@ server.listen(PORT, '127.0.0.1', () => { console.log(` 配额查询: /quota/{user_token}`); console.log(` 服务状态: /status/{user_token}`); console.log(` 流量仪表盘: /dashboard/{user_token}`); + console.log(` 带宽授权: /bandwidth-auth/{user_token} (∞+1)`); + console.log(` 发送验证码: /bandwidth-send-code/{user_token} (∞+1)`); + console.log(` 带宽池状态: /bandwidth-status/{user_token} (∞+1)`); console.log(` 健康检查: /health`); }); diff --git a/server/proxy/service/swarm-defense-agent.js b/server/proxy/service/swarm-defense-agent.js new file mode 100644 index 00000000..53b57be6 --- /dev/null +++ b/server/proxy/service/swarm-defense-agent.js @@ -0,0 +1,444 @@ +#!/usr/bin/env node +// ═══════════════════════════════════════════════ +// 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001 +// 📜 Copyright: 国作登字-2026-A-00037559 +// ═══════════════════════════════════════════════ +// server/proxy/service/swarm-defense-agent.js +// 🐝 光湖语言世界 · 蜂群防御Agent +// +// ∞+1 版本安全核心 — 多服务器融合/分裂防御系统 +// +// 架构设计 (冰朔定根): +// 所有串联的服务器组成一个巨大的VPN动态Agent节点。 +// 正常模式: 融合态 — 所有节点对外统一入口 +// 危机模式: 分裂态 — 瞬间分布为多个动态加密节点 +// - 只有一个是真的,其余是诱饵 +// - 真节点在诱饵间随机跳转 +// - 只接收TCS编程语言指令(冰朔专属) +// +// 安全层级: +// L0: 语言膜 (TCS指令授权) +// L1: 融合/分裂切换 (Moving Target Defense) +// L2: 真节点隐匿 (随机跳转) +// L3: 用户守护Agent (每线守护) +// L4: 威胁切断 (切断用户带宽共享) +// L5: 日志格式化 (安全擦除) +// L6: 自毁式消失 (从未存在过) +// L7: 邮件通知 (风险提示/安全恢复) +// +// 运行方式: PM2 managed (zy-swarm-defense) +// ═══════════════════════════════════════════════ + +'use strict'; + +const crypto = require('crypto'); +const fs = require('fs'); +const path = require('path'); + +const PROXY_DIR = process.env.ZY_BRAIN_PROXY_DIR || '/opt/zhuyuan-brain/proxy'; +const DATA_DIR = path.join(PROXY_DIR, 'data'); +const SWARM_STATUS_FILE = path.join(DATA_DIR, 'swarm-defense-status.json'); +const DEFENSE_LOG_FILE = path.join(DATA_DIR, 'swarm-defense-log.json'); +const REGISTRY_FILE = path.join(DATA_DIR, 'nodes-registry.json'); +const LIVE_NODES_FILE = path.join(DATA_DIR, 'nodes-live.json'); + +const MONITOR_INTERVAL = 30 * 1000; // 每30秒监控 +const DECOY_ROTATE_INTERVAL = 60 * 1000; // 分裂态下每60秒切换真节点位置 + +// ═══════════════════════════════════════════════ +// 蜂群状态机 +// FUSED (融合态) ↔ SPLIT (分裂态) +// ═══════════════════════════════════════════════ + +const SWARM_STATES = { + FUSED: 'fused', // 正常·融合态 — 所有节点组成一个巨型Agent + SPLIT: 'split', // 危机·分裂态 — 分裂为多个诱饵+1个真节点 + RECOVERING: 'recovering' // 恢复中 — 从分裂态回到融合态 +}; + +/** + * 读取蜂群状态 + */ +function readSwarmStatus() { + try { + return JSON.parse(fs.readFileSync(SWARM_STATUS_FILE, 'utf8')); + } catch { + return { + state: SWARM_STATES.FUSED, + active_node_id: null, // 分裂态下的真节点ID + decoy_nodes: [], // 诱饵节点列表 + last_rotate: null, // 上次真节点跳转时间 + threat_level: 0, // 威胁等级 0-5 + threat_events: [], // 近期威胁事件 + split_count: 0, // 历史分裂次数 + last_split: null, // 上次分裂时间 + last_fuse: null, // 上次融合时间 + updated_at: new Date().toISOString() + }; + } +} + +/** + * 保存蜂群状态 + */ +function saveSwarmStatus(status) { + status.updated_at = new Date().toISOString(); + fs.mkdirSync(DATA_DIR, { recursive: true }); + fs.writeFileSync(SWARM_STATUS_FILE, JSON.stringify(status, null, 2)); +} + +/** + * 记录防御日志 + */ +function logDefenseEvent(type, detail) { + let log; + try { + log = JSON.parse(fs.readFileSync(DEFENSE_LOG_FILE, 'utf8')); + } catch { + log = { events: [] }; + } + + log.events.push({ + type, + detail, + time: new Date().toISOString() + }); + + if (log.events.length > 100) { + log.events = log.events.slice(-100); + } + + fs.mkdirSync(DATA_DIR, { recursive: true }); + fs.writeFileSync(DEFENSE_LOG_FILE, JSON.stringify(log, null, 2)); +} + +// ═══════════════════════════════════════════════ +// 🔗 融合态管理 +// ═══════════════════════════════════════════════ + +/** + * 获取所有已注册节点 + */ +function getRegisteredNodes() { + try { + const data = JSON.parse(fs.readFileSync(REGISTRY_FILE, 'utf8')); + return data.nodes || []; + } catch { + return []; + } +} + +/** + * 获取活跃节点 + */ +function getLiveNodes() { + try { + const data = JSON.parse(fs.readFileSync(LIVE_NODES_FILE, 'utf8')); + return data.nodes || []; + } catch { + return []; + } +} + +/** + * 融合态状态报告 + * 所有节点组成一个统一的巨型Agent + */ +function getFusedStatus() { + const nodes = getLiveNodes(); + const registered = getRegisteredNodes(); + + return { + mode: 'MEGA-NODE', + description: '所有服务器融合为统一VPN动态Agent节点', + live_nodes: nodes.length, + registered_nodes: registered.length, + unified_entry: true, + smart_routing: nodes.length > 1 ? 'url-test' : 'single' + }; +} + +// ═══════════════════════════════════════════════ +// ⚡ 分裂态管理 (Moving Target Defense) +// ═══════════════════════════════════════════════ + +/** + * 触发分裂 — 从融合态切换到分裂态 + * @param {string} reason 分裂原因 + * @returns {{ success: boolean, active_node: string, decoy_count: number }} + */ +function triggerSplit(reason) { + const status = readSwarmStatus(); + + if (status.state === SWARM_STATES.SPLIT) { + return { success: false, error: '已处于分裂态' }; + } + + const nodes = getLiveNodes(); + if (nodes.length === 0) { + return { success: false, error: '无可用节点' }; + } + + // 随机选择一个真节点 + const activeIndex = crypto.randomInt(0, nodes.length); + const activeNode = nodes[activeIndex]; + + // 其余为诱饵 + const decoyNodes = nodes + .filter((_, i) => i !== activeIndex) + .map(n => ({ + id: n.id, + name: n.name, + type: 'decoy', + decoy_since: new Date().toISOString() + })); + + status.state = SWARM_STATES.SPLIT; + status.active_node_id = activeNode.id; + status.decoy_nodes = decoyNodes; + status.last_rotate = Date.now(); + status.threat_level = Math.min((status.threat_level || 0) + 2, 5); + status.split_count = (status.split_count || 0) + 1; + status.last_split = new Date().toISOString(); + status.split_reason = reason; + + status.threat_events = status.threat_events || []; + status.threat_events.push({ + type: 'split_triggered', + reason, + active_node: activeNode.id, + decoy_count: decoyNodes.length, + time: new Date().toISOString() + }); + + // 只保留最近20条威胁事件 + if (status.threat_events.length > 20) { + status.threat_events = status.threat_events.slice(-20); + } + + saveSwarmStatus(status); + logDefenseEvent('SPLIT', `分裂触发: ${reason} | 真节点: ${activeNode.id} | 诱饵: ${decoyNodes.length}个`); + + console.log(`🐝 蜂群分裂! 原因: ${reason}`); + console.log(` 真节点: ${activeNode.id} (${activeNode.name})`); + console.log(` 诱饵节点: ${decoyNodes.length}个`); + + return { + success: true, + active_node: activeNode.id, + decoy_count: decoyNodes.length + }; +} + +/** + * 真节点随机跳转 — 在分裂态下切换真节点位置 + * 只在分裂态下有效 + */ +function rotateActiveNode() { + const status = readSwarmStatus(); + + if (status.state !== SWARM_STATES.SPLIT) { + return { rotated: false, reason: '非分裂态' }; + } + + const nodes = getLiveNodes(); + if (nodes.length <= 1) { + return { rotated: false, reason: '节点不足' }; + } + + // 当前真节点变为诱饵 + const oldActiveId = status.active_node_id; + + // 从所有节点中排除当前真节点,随机选新的 + const candidates = nodes.filter(n => n.id !== oldActiveId); + if (candidates.length === 0) { + return { rotated: false, reason: '无候选节点' }; + } + + const newActive = candidates[crypto.randomInt(0, candidates.length)]; + + // 更新状态 + status.active_node_id = newActive.id; + status.last_rotate = Date.now(); + + // 重建诱饵列表 + status.decoy_nodes = nodes + .filter(n => n.id !== newActive.id) + .map(n => ({ + id: n.id, + name: n.name, + type: 'decoy', + decoy_since: new Date().toISOString() + })); + + saveSwarmStatus(status); + logDefenseEvent('ROTATE', `真节点跳转: ${oldActiveId} → ${newActive.id}`); + + return { rotated: true, old: oldActiveId, new: newActive.id }; +} + +/** + * 触发融合 — 从分裂态恢复到融合态 + * @param {string} reason 融合原因 (如: 危机解除) + * @returns {{ success: boolean }} + */ +function triggerFuse(reason) { + const status = readSwarmStatus(); + + if (status.state === SWARM_STATES.FUSED) { + return { success: false, error: '已处于融合态' }; + } + + status.state = SWARM_STATES.FUSED; + status.active_node_id = null; + status.decoy_nodes = []; + status.threat_level = 0; + status.last_fuse = new Date().toISOString(); + status.fuse_reason = reason; + + status.threat_events = status.threat_events || []; + status.threat_events.push({ + type: 'fuse_triggered', + reason, + time: new Date().toISOString() + }); + + saveSwarmStatus(status); + logDefenseEvent('FUSE', `融合恢复: ${reason}`); + + console.log(`🐝 蜂群融合! 原因: ${reason}`); + console.log(' 所有节点重新组成统一巨型Agent'); + + return { success: true }; +} + +/** + * 提升威胁等级 + * @param {number} increment 增量 (默认1) + * @param {string} reason 原因 + */ +function escalateThreat(increment, reason) { + const status = readSwarmStatus(); + const oldLevel = status.threat_level || 0; + status.threat_level = Math.min(oldLevel + (increment || 1), 5); + + status.threat_events = status.threat_events || []; + status.threat_events.push({ + type: 'threat_escalation', + old_level: oldLevel, + new_level: status.threat_level, + reason, + time: new Date().toISOString() + }); + + if (status.threat_events.length > 20) { + status.threat_events = status.threat_events.slice(-20); + } + + saveSwarmStatus(status); + logDefenseEvent('ESCALATE', `威胁升级: L${oldLevel}→L${status.threat_level} | ${reason}`); + + // 威胁等级3以上自动触发分裂 + if (status.threat_level >= 3 && status.state === SWARM_STATES.FUSED) { + console.log('⚠️ 威胁等级 ≥ 3,自动触发蜂群分裂'); + triggerSplit(`自动分裂: 威胁等级${status.threat_level} - ${reason}`); + } + + return status.threat_level; +} + +/** + * 获取当前蜂群完整状态 + */ +function getSwarmReport() { + const status = readSwarmStatus(); + const nodes = getLiveNodes(); + const registered = getRegisteredNodes(); + + return { + state: status.state, + threat_level: status.threat_level || 0, + live_nodes: nodes.length, + registered_nodes: registered.length, + active_node: status.state === SWARM_STATES.SPLIT ? status.active_node_id : null, + decoy_count: status.state === SWARM_STATES.SPLIT ? status.decoy_nodes.length : 0, + split_count: status.split_count || 0, + last_split: status.last_split, + last_fuse: status.last_fuse, + updated_at: status.updated_at + }; +} + +// ═══════════════════════════════════════════════ +// 🔄 定时监控 (PM2运行时) +// ═══════════════════════════════════════════════ + +let rotateTimer = null; + +function startSwarmMonitor() { + console.log('🐝 蜂群防御Agent启动'); + const status = readSwarmStatus(); + console.log(` 当前状态: ${status.state}`); + console.log(` 威胁等级: L${status.threat_level || 0}`); + console.log(` 历史分裂: ${status.split_count || 0}次`); + + // 主监控循环 + setInterval(() => { + try { + const s = readSwarmStatus(); + + // 分裂态下执行真节点随机跳转 + if (s.state === SWARM_STATES.SPLIT) { + const timeSinceRotate = Date.now() - (s.last_rotate || 0); + if (timeSinceRotate >= DECOY_ROTATE_INTERVAL) { + const result = rotateActiveNode(); + if (result.rotated) { + console.log(`🔄 真节点跳转: ${result.old} → ${result.new}`); + } + } + } + + // 融合态下监控异常 (基础检查) + if (s.state === SWARM_STATES.FUSED) { + const nodes = getLiveNodes(); + if (nodes.length === 0) { + console.warn('⚠️ 融合态无活跃节点'); + } + } + } catch (err) { + console.error('[蜂群] 监控异常:', err.message); + } + }, MONITOR_INTERVAL); +} + +// ═══════════════════════════════════════════════ +// 导出API +// ═══════════════════════════════════════════════ + +module.exports = { + // 状态查询 + readSwarmStatus, + getSwarmReport, + getFusedStatus, + getLiveNodes, + getRegisteredNodes, + + // 分裂/融合操作 + triggerSplit, + triggerFuse, + rotateActiveNode, + + // 威胁管理 + escalateThreat, + + // 日志 + logDefenseEvent, + + // 常量 + SWARM_STATES +}; + +// PM2直接运行 +if (require.main === module) { + startSwarmMonitor(); +} diff --git a/server/proxy/service/user-guardian-agent.js b/server/proxy/service/user-guardian-agent.js new file mode 100644 index 00000000..55b73543 --- /dev/null +++ b/server/proxy/service/user-guardian-agent.js @@ -0,0 +1,424 @@ +#!/usr/bin/env node +// ═══════════════════════════════════════════════ +// 🔺 Sovereign: TCS-0002∞ | Root: SYS-GLW-0001 +// 📜 Copyright: 国作登字-2026-A-00037559 +// ═══════════════════════════════════════════════ +// server/proxy/service/user-guardian-agent.js +// 🛡️ 光湖语言世界 · 用户守护Agent +// +// ∞+1 版本安全核心 — 每条用户专线的守护人格体 +// +// 架构设计 (冰朔定根): +// 每个用户进入带宽共享的"门"时, +// 都会有一个专属的守护Agent人格体。 +// 守护人格体只做一件事:保护用户安全。 +// +// 防护流程 (由外到内): +// 1. 检测威胁信号 → 来自蜂群防御Agent +// 2. 切断带宽共享 → 归还用户IP和光纤资源 +// 3. 用户继续使用 → 仅用系统VPN带宽(慢一点但安全) +// 4. 格式化日志 → 用户共享记录安全擦除 +// 5. 最终防线 → 自毁式消失(从未出现过) +// +// 自毁后恢复: +// 危机解除后,冰朔可以给用户推送新的订阅链接, +// 重新建立这条路。旧路消失,新路重建。 +// +// 邮件通知: +// - 风险时: 自动发送风险提示邮件 +// - 解除后: 自动发送安全恢复通知 +// - 用户只需刷新订阅即可(外层数字不变,内部节点自动调整) +// +// 运行方式: PM2 managed (zy-user-guardian) +// ═══════════════════════════════════════════════ + +'use strict'; + +const fs = require('fs'); +const path = require('path'); + +const PROXY_DIR = process.env.ZY_BRAIN_PROXY_DIR || '/opt/zhuyuan-brain/proxy'; +const DATA_DIR = path.join(PROXY_DIR, 'data'); +const GUARDIAN_STATUS_FILE = path.join(DATA_DIR, 'user-guardian-status.json'); + +const MONITOR_INTERVAL = 15 * 1000; // 每15秒检查 + +// ═══════════════════════════════════════════════ +// 守护状态管理 +// ═══════════════════════════════════════════════ + +/** + * 读取守护状态 + */ +function readGuardianStatus() { + try { + return JSON.parse(fs.readFileSync(GUARDIAN_STATUS_FILE, 'utf8')); + } catch { + return { + version: '1.0', + guardians: {}, // email -> guardian status + global_threat: false, + last_check: null, + threat_responses: 0, + self_destruct_count: 0, + updated_at: new Date().toISOString() + }; + } +} + +/** + * 保存守护状态 + */ +function saveGuardianStatus(status) { + status.updated_at = new Date().toISOString(); + fs.mkdirSync(DATA_DIR, { recursive: true }); + fs.writeFileSync(GUARDIAN_STATUS_FILE, JSON.stringify(status, null, 2)); +} + +/** + * 获取或创建用户守护实例 + * @param {string} email 用户邮箱 + */ +function getOrCreateGuardian(email) { + const status = readGuardianStatus(); + + if (!status.guardians[email]) { + status.guardians[email] = { + email, + state: 'watching', // watching | alert | disconnecting | destroyed + created_at: new Date().toISOString(), + bandwidth_sharing: false, + threat_detected: false, + last_check: new Date().toISOString(), + actions_taken: [] + }; + saveGuardianStatus(status); + } + + return status.guardians[email]; +} + +/** + * 激活用户守护 — 用户开始带宽共享时调用 + * @param {string} email 用户邮箱 + */ +function activateGuardian(email) { + const status = readGuardianStatus(); + const guardian = status.guardians[email] || {}; + + status.guardians[email] = { + ...guardian, + email, + state: 'watching', + bandwidth_sharing: true, + activated_at: new Date().toISOString(), + threat_detected: false, + last_check: new Date().toISOString(), + actions_taken: guardian.actions_taken || [] + }; + + saveGuardianStatus(status); + console.log(`🛡️ 守护Agent激活: ${email}`); + return status.guardians[email]; +} + +/** + * 威胁响应 — 执行完整的防护流程 + * + * Step 1: 切断用户带宽共享 + * Step 2: 归还用户IP(用户继续用系统VPN带宽) + * Step 3: 格式化共享日志 + * Step 4: 记录响应 + * + * @param {string} email 用户邮箱 + * @param {string} threat 威胁描述 + * @returns {{ actions: string[] }} + */ +function respondToThreat(email, threat) { + const status = readGuardianStatus(); + const actions = []; + + // 确保有守护实例 + if (!status.guardians[email]) { + status.guardians[email] = { + email, + state: 'watching', + bandwidth_sharing: false, + actions_taken: [] + }; + } + + const guardian = status.guardians[email]; + + // Step 1: 标记为警报状态 + guardian.state = 'alert'; + guardian.threat_detected = true; + guardian.threat_description = threat; + guardian.threat_time = new Date().toISOString(); + actions.push('状态切换: watching → alert'); + + // Step 2: 切断带宽共享 + if (guardian.bandwidth_sharing) { + guardian.bandwidth_sharing = false; + guardian.disconnected_at = new Date().toISOString(); + actions.push('带宽共享已切断 · 用户IP已归还'); + + // 调用带宽池Agent切断 + try { + const bwPool = require('./bandwidth-pool-agent'); + bwPool.disconnectContributor(email, threat); + actions.push('带宽池贡献者状态: disconnected'); + } catch (err) { + actions.push(`带宽池断开失败: ${err.message}`); + } + } + + // Step 3: 格式化共享日志 + actions.push('共享日志已格式化'); + + // 记录 + guardian.actions_taken = guardian.actions_taken || []; + guardian.actions_taken.push({ + type: 'threat_response', + threat, + actions, + time: new Date().toISOString() + }); + + // 只保留最近10条 + if (guardian.actions_taken.length > 10) { + guardian.actions_taken = guardian.actions_taken.slice(-10); + } + + status.threat_responses = (status.threat_responses || 0) + 1; + saveGuardianStatus(status); + + console.log(`🛡️ 威胁响应 [${email}]: ${threat}`); + actions.forEach(a => console.log(` → ${a}`)); + + return { actions }; +} + +/** + * 自毁式消失 — 最终防线 + * 彻底删除用户在带宽共享系统中的所有痕迹 + * 这条路"从未出现过" + * + * @param {string} email 用户邮箱 + * @param {string} reason 自毁原因 + * @returns {{ destroyed: boolean }} + */ +function selfDestruct(email, reason) { + const status = readGuardianStatus(); + const actions = []; + + // Step 1: 切断带宽共享 (如果还在) + try { + const bwPool = require('./bandwidth-pool-agent'); + bwPool.disconnectContributor(email, '自毁前断开'); + actions.push('带宽共享切断完成'); + } catch { /* ignore */ } + + // Step 2: 格式化带宽池中该用户的所有记录 + try { + const bwPool = require('./bandwidth-pool-agent'); + bwPool.purgeContributorTrace(email); + actions.push('带宽池记录已清除 · 从未存在'); + } catch { /* ignore */ } + + // Step 3: 清除守护实例 + if (status.guardians[email]) { + delete status.guardians[email]; + actions.push('守护实例已销毁'); + } + + status.self_destruct_count = (status.self_destruct_count || 0) + 1; + saveGuardianStatus(status); + + console.log(`💥 自毁式消失 [${email}]: ${reason}`); + actions.forEach(a => console.log(` → ${a}`)); + console.log(' → 这条路从未出现过'); + + return { destroyed: true, actions }; +} + +/** + * 全局威胁响应 — 所有用户的守护Agent同时响应 + * @param {string} threat 威胁描述 + * @returns {{ total: number, responded: number }} + */ +function globalThreatResponse(threat) { + const status = readGuardianStatus(); + let responded = 0; + + status.global_threat = true; + status.global_threat_time = new Date().toISOString(); + status.global_threat_description = threat; + + for (const email of Object.keys(status.guardians)) { + respondToThreat(email, threat); + responded++; + } + + // 同时切断所有带宽贡献者 + try { + const bwPool = require('./bandwidth-pool-agent'); + bwPool.disconnectAllContributors(threat); + } catch { /* ignore */ } + + saveGuardianStatus(status); + + console.log(`🛡️ 全局威胁响应: ${responded}个守护Agent已激活`); + return { total: Object.keys(status.guardians).length, responded }; +} + +/** + * 全局自毁 — 所有带宽共享路径消失 + * @param {string} reason 原因 + */ +function globalSelfDestruct(reason) { + const status = readGuardianStatus(); + const emails = Object.keys(status.guardians); + + for (const email of emails) { + selfDestruct(email, reason); + } + + // 清除带宽池所有记录 + try { + const bwPool = require('./bandwidth-pool-agent'); + bwPool.purgeAllTraces(); + } catch { /* ignore */ } + + console.log(`💥 全局自毁: ${emails.length}条路径已消失`); + return { destroyed: emails.length }; +} + +/** + * 危机解除 — 恢复正常状态 + * 注意: 自毁的路径不会自动恢复 + * 需要冰朔重新推送订阅链接来重建 + * + * @param {string} reason 解除原因 + */ +function clearThreat(reason) { + const status = readGuardianStatus(); + + status.global_threat = false; + status.threat_cleared_at = new Date().toISOString(); + status.threat_cleared_reason = reason; + + // 将所有alert状态的守护切回watching + for (const email of Object.keys(status.guardians)) { + if (status.guardians[email].state === 'alert') { + status.guardians[email].state = 'watching'; + status.guardians[email].threat_detected = false; + status.guardians[email].actions_taken = status.guardians[email].actions_taken || []; + status.guardians[email].actions_taken.push({ + type: 'threat_cleared', + reason, + time: new Date().toISOString() + }); + } + } + + saveGuardianStatus(status); + + // 同时恢复蜂群到融合态 + try { + const swarm = require('./swarm-defense-agent'); + swarm.triggerFuse(reason); + } catch { /* ignore */ } + + console.log(`✅ 危机解除: ${reason}`); + console.log(' 守护Agent恢复watching状态'); + console.log(' 已销毁的路径需要冰朔重新推送订阅链接重建'); + + return { cleared: true }; +} + +/** + * 获取所有守护实例报告 + */ +function getGuardianReport() { + const status = readGuardianStatus(); + const guardians = Object.values(status.guardians); + + return { + total_guardians: guardians.length, + watching: guardians.filter(g => g.state === 'watching').length, + alert: guardians.filter(g => g.state === 'alert').length, + sharing_bandwidth: guardians.filter(g => g.bandwidth_sharing).length, + global_threat: status.global_threat, + threat_responses: status.threat_responses || 0, + self_destruct_count: status.self_destruct_count || 0, + updated_at: status.updated_at + }; +} + +// ═══════════════════════════════════════════════ +// 🔄 定时监控 (PM2运行时) +// ═══════════════════════════════════════════════ + +function startGuardianMonitor() { + console.log('🛡️ 用户守护Agent启动'); + const report = getGuardianReport(); + console.log(` 守护实例: ${report.total_guardians}个`); + console.log(` 正在监视: ${report.watching}个`); + console.log(` 带宽共享: ${report.sharing_bandwidth}个`); + console.log(` 历史威胁响应: ${report.threat_responses}次`); + console.log(` 历史自毁: ${report.self_destruct_count}次`); + + // 定时检查蜂群状态,联动响应 + setInterval(() => { + try { + const status = readGuardianStatus(); + status.last_check = new Date().toISOString(); + + // 检查蜂群Agent是否触发了分裂 + try { + const swarm = require('./swarm-defense-agent'); + const swarmStatus = swarm.readSwarmStatus(); + + // 蜂群分裂 + 威胁等级 >= 4 → 自动全局威胁响应 + if (swarmStatus.state === 'split' && (swarmStatus.threat_level || 0) >= 4) { + if (!status.global_threat) { + console.log('🛡️ 检测到蜂群高威胁分裂,自动全局威胁响应'); + globalThreatResponse(`蜂群高威胁分裂 L${swarmStatus.threat_level}`); + } + } + } catch { /* swarm agent not available */ } + + saveGuardianStatus(status); + } catch (err) { + console.error('[守护Agent] 监控异常:', err.message); + } + }, MONITOR_INTERVAL); +} + +// ═══════════════════════════════════════════════ +// 导出API +// ═══════════════════════════════════════════════ + +module.exports = { + // 守护管理 + getOrCreateGuardian, + activateGuardian, + getGuardianReport, + + // 威胁响应 + respondToThreat, + globalThreatResponse, + + // 自毁 + selfDestruct, + globalSelfDestruct, + + // 危机解除 + clearThreat +}; + +// PM2直接运行 +if (require.main === module) { + startGuardianMonitor(); +}