# ═══════════════════════════════════════════════════════════ # 语言保护罩 · Novel智库节点入站保护配置 # ═══════════════════════════════════════════════════════════ # # 编号: ZY-SVR-NGX-006-SHIELD # 服务器: ZY-SVR-006 (43.153.203.105 · 新加坡 · 智库节点) # 守护: 铸渊 · ICE-GL-ZY001 # 版权: 国作登字-2026-A-00037559 # # 语言保护罩三层架构 (L2 + L3 由本配置实现): # # L1 · 出站伪装层 — 由 novel-api 的代理池模块负责 # L2 · 入站蜜罐层 — 本配置: 扫描者看到自己的镜像 # L3 · 自动封禁层 — fail2ban 监控 nginx 日志自动 ban # # 蜜罐原理: # 未授权访问 → 返回 JSON 镜像,把扫描者的信息原样反射 # 服务器伪装为 CDN 静态节点,不暴露任何技术栈 # 真实应用 (4000/4001/4002) 只绑定 127.0.0.1,不直接暴露 # # ═══════════════════════════════════════════════════════════ # ─── 全局:隐藏 Nginx 版本,伪装为 CDN ─── # 在 nginx.conf 主配置 http{} 块内设置: # server_tokens off; # more_set_headers 'Server: cloudfront'; # 需要 headers_more 模块 # 本配置通过 add_header 覆盖实现类似效果 # ─── 速率限制区域 (在 http{} 块定义,此处注释说明) ─── # limit_req_zone $binary_remote_addr zone=shield_limit:10m rate=10r/m; # limit_conn_zone $binary_remote_addr zone=shield_conn:10m; # ─── GeoIP 封锁区 (可选,需 ngx_http_geoip2_module) ─── # geo $blocked_country { # default 0; # # 如需按国家封锁,在此添加 # } # ═══════════════════════════════════════════════════════════ # HTTP → HTTPS 重定向 · novel.guanghuyaoming.com # ─────────────────────────────────────────────────────────── # 必须在 default_server (蜜罐) 之前定义,让合法域名流量 # 在到达蜜罐之前先被这个 server block 捕获并重定向到 HTTPS。 # Let's Encrypt ACME 挑战也在此处处理。 # ═══════════════════════════════════════════════════════════ server { listen 80; listen [::]:80; server_name novel.guanghuyaoming.com; server_tokens off; # Let's Encrypt ACME 验证路径(certbot 申请证书时需要) location /.well-known/acme-challenge/ { root /var/www/certbot; try_files $uri =404; } # 所有其他请求重定向到 HTTPS location / { return 301 https://$host$request_uri; } } # ═══════════════════════════════════════════════════════════ # 蜜罐 · 80 端口 — HTTP 入站捕获 # ═══════════════════════════════════════════════════════════ server { listen 80 default_server; listen [::]:80 default_server; server_name _; # 隐藏服务器信息,伪装为静态 CDN 节点 server_tokens off; add_header Server "AmazonS3" always; add_header X-Cache "Miss from cloudfront" always; add_header Via "1.1 cloudfront.net (CloudFront)" always; # 访问日志(fail2ban 监控此日志) access_log /var/log/nginx/shield-access.log; error_log /var/log/nginx/shield-error.log warn; # ─── 蜜罐路由:所有未知路径 ─── # 将扫描者的信息原样镜像反射回去 location / { # 速率限制:每分钟10次,超出返回 429 limit_req zone=shield_limit burst=5 nodelay; # 返回镜像响应 (纯静态 HTML,不暴露后端) default_type text/html; return 200 ' Amazon S3

AccessDenied

Access Denied

RequestId: $request_id
HostId: novel.guanghuyaoming.com
'; } # ─── 健康检查(内部监控用,外部不知道此路径)─── location = /_shield_health { allow 127.0.0.1; deny all; default_type application/json; return 200 '{"status":"alive","shield":"active","layer":"L2"}'; } } # ═══════════════════════════════════════════════════════════ # 正式入口 · 443 端口 — HTTPS(SSL 由 certbot 配置) # ═══════════════════════════════════════════════════════════ server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name novel.guanghuyaoming.com; # SSL 证书(certbot --nginx 自动填写) ssl_certificate /etc/letsencrypt/live/novel.guanghuyaoming.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/novel.guanghuyaoming.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # 强化 SSL:隐藏版本,伪装 CDN server_tokens off; add_header Server "cloudfront" always; add_header X-Frame-Options SAMEORIGIN always; add_header X-Content-Type-Options nosniff always; add_header X-XSS-Protection "1; mode=block" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # 不暴露后端 IP add_header X-Powered-By "" always; # 访问日志 access_log /var/log/nginx/novel-access.log; error_log /var/log/nginx/novel-error.log warn; # ─── 小说 API 后端 (:4000) ─── location /api/ { proxy_pass http://127.0.0.1:4000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 不向后端暴露真实连接信息头 proxy_hide_header X-Powered-By; proxy_hide_header Server; proxy_read_timeout 120s; } # ─── Phase 1: 阅读器静态入口(Phase 2 替换为 Node.js 阅读器)─── location / { root /opt/novel-db/app/public; try_files $uri $uri/ /index.html; } # ─── 成员 Agent API (:4002) ─── location /agent/ { proxy_pass http://127.0.0.1:4002; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_hide_header X-Powered-By; proxy_hide_header Server; # Agent 长连接支持 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 300s; } # ─── 保护罩状态 API(供面板拉取,仅已认证用户可访问)─── location /shield/ { proxy_pass http://127.0.0.1:4000/shield/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # ─── 蜜罐:未知路径扫描捕获 ─── location @honeypot { default_type application/json; add_header Server "cloudfront" always; add_header X-Cache "Hit" always; return 403 '{"error":"AccessDenied","requestId":"$request_id","message":"Access Denied"}'; } } # ═══════════════════════════════════════════════════════════ # 扫描捕获 · 非标准端口蜜罐(需 iptables 引流) # ═══════════════════════════════════════════════════════════ # 在 stream{} 块配置(须在 nginx.conf 引入 stream 模块) # 将常见扫描端口(8080/8443/3000/3001/3002)流量引入蜜罐 # 可通过 iptables REDIRECT 规则实现: # iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80 # iptables -t nat -A PREROUTING -p tcp --dport 8443 -j REDIRECT --to-port 80 # iptables -t nat -A PREROUTING -p tcp --dport 3000 -j REDIRECT --to-port 80 # 这样所有扫描常用端口的流量都被引导到蜜罐 80 端口