2026-05-10 13:12:44 +08:00

134 lines
4.1 KiB
JavaScript

/**
* ═══════════════════════════════════════════════════════════
* 七层镜防 · Layer 4 · 动态漂移(节点随机化层)
* ═══════════════════════════════════════════════════════════
*
* 当某个节点被扫描/探测时,系统触发动态随机重分配
* 攻击者追踪到的地址在下一秒已经不存在
*
* 当前为框架实现 — 多节点联动需 P3 阶段落地
*
* 守护: 铸渊 · ICE-GL-ZY001
* 版权: 国作登字-2026-A-00037559
* ═══════════════════════════════════════════════════════════
*/
'use strict';
/**
* 探测检测器 — 识别扫描行为特征
*/
const scanDetection = {
// IP → { count, firstSeen, lastSeen }
suspects: new Map(),
threshold: 20, // 60 秒内超过此次数视为扫描
windowMs: 60000, // 检测窗口
banDurationMs: 3600000 // 封禁 1 小时
};
/**
* 被封禁的 IP 列表
*/
const bannedIPs = new Map(); // IP → expires_at
/**
* 记录一次访问,检测是否为扫描行为
*/
function recordAccess(ip) {
const now = Date.now();
// 检查是否已被封禁
const banExpiry = bannedIPs.get(ip);
if (banExpiry && banExpiry > now) {
return { banned: true, reason: 'scan_detected' };
} else if (banExpiry) {
bannedIPs.delete(ip);
}
// 记录访问
let record = scanDetection.suspects.get(ip);
if (!record || (now - record.firstSeen) > scanDetection.windowMs) {
record = { count: 0, firstSeen: now, lastSeen: now };
}
record.count++;
record.lastSeen = now;
scanDetection.suspects.set(ip, record);
// 检查是否超过阈值
if (record.count > scanDetection.threshold) {
bannedIPs.set(ip, now + scanDetection.banDurationMs);
scanDetection.suspects.delete(ip);
return { banned: true, reason: 'threshold_exceeded', count: record.count };
}
return { banned: false };
}
/**
* Layer 4 中间件:动态漂移
*
* 当前实现(单节点):
* - 检测高频访问 IP → 自动封禁
* - 封禁后返回随机响应(迷惑扫描器)
*
* P3 阶段升级(多节点):
* - 联动所有节点触发 IP/端口重分配
* - 节点间通过加密信号总线协调
*/
function driftMiddleware(req, res, next) {
const ip = req.ip || req.connection?.remoteAddress || '';
const check = recordAccess(ip);
if (check.banned) {
// 对扫描者返回随机响应(不是拒绝 — 是迷惑)
const decoys = [
{ status: 200, body: '<html><head><title>Welcome</title></head><body>OK</body></html>' },
{ status: 301, headers: { 'Location': 'https://www.example.com' } },
{ status: 403, body: 'Forbidden' },
{ status: 503, body: 'Service Temporarily Unavailable' }
];
const decoy = decoys[Math.floor(Math.random() * decoys.length)];
if (decoy.headers) {
for (const [k, v] of Object.entries(decoy.headers)) {
res.setHeader(k, v);
}
}
return res.status(decoy.status).end(decoy.body || '');
}
next();
}
/**
* 获取当前封禁统计
*/
function getDriftStats() {
const now = Date.now();
return {
active_bans: Array.from(bannedIPs.entries())
.filter(([, exp]) => exp > now)
.length,
suspects_tracked: scanDetection.suspects.size,
threshold: scanDetection.threshold,
window_sec: scanDetection.windowMs / 1000,
ban_duration_sec: scanDetection.banDurationMs / 1000
};
}
// 定期清理过期记录(每 10 分钟)
setInterval(() => {
const now = Date.now();
for (const [ip, exp] of bannedIPs) {
if (exp < now) bannedIPs.delete(ip);
}
for (const [ip, record] of scanDetection.suspects) {
if ((now - record.lastSeen) > scanDetection.windowMs * 2) {
scanDetection.suspects.delete(ip);
}
}
}, 10 * 60 * 1000).unref();
module.exports = { driftMiddleware, getDriftStats, recordAccess };