铸渊 ICE-GL-ZY001 · LL-006-20260711 · 安全修复:清除所有硬编码密码·密钥·token·邮箱验证码替代密码

⊢ 问题:revive-guard.py 明文密码 john0515 推入公开仓库
⊢ 问题:BINGSHUO-KEYSTORE.hdlp 7个Gatekeeper token全部暴露
⊢ 问题:SI-039.hdlp SMTP授权码 ggeuegmaragmbejb 暴露
⊢ 问题:ecosystem.config.json SMTP授权码硬编码兜底值

修复:
- revive-guard: 去掉密码认证 → 改为纯邮箱验证码(用完即废)
  速率限制收紧 3→2/分钟作为补偿
- 所有敏感值走环境变量 · 不进仓库 · 无默认值
- BINGSHUO-KEYSTORE: 密码 + 7个token + SSH密码全部替换为占位符
- SI-039: SMTP授权码替换为 FROM_SERVER_ENV
- revive-guard.service: SMTP码移除 · 改用 EnvironmentFile

版权: 国作登字-2026-A-00037559
主权者: ICE-GL∞ · 冰朔
This commit is contained in:
冰朔 2026-07-11 16:10:46 +08:00
parent 00f461c44f
commit c008b88bd0
5 changed files with 48 additions and 38 deletions

View File

@ -54,7 +54,7 @@
``` ```
- **密钥类型**: Ed25519最安全 · 最短 · 最快) - **密钥类型**: Ed25519最安全 · 最短 · 最快)
- **私钥密码**: `john0515`(与保险库同密码 - **私钥密码**: `YOUR_VAULT_PASSWORD`(与保险库同密码 · ⊢ 不进仓库
- **私钥也存于**: GZ-006 保险库 `/opt/zhuyuan/keystore/`Key: `GUANGHU_SSH_PRIV_KEY` - **私钥也存于**: GZ-006 保险库 `/opt/zhuyuan/keystore/`Key: `GUANGHU_SSH_PRIV_KEY`
### 📋 如何生成新密钥(如果丢了) ### 📋 如何生成新密钥(如果丢了)
@ -63,28 +63,28 @@
# 在你的 Mac 上运行: # 在你的 Mac 上运行:
python3 ~/Documents/QoderCN/2026-07-11/chat-1/fifth-domain/zero-point/core-channel/ssh-direct/generate-ssh-key.py python3 ~/Documents/QoderCN/2026-07-11/chat-1/fifth-domain/zero-point/core-channel/ssh-direct/generate-ssh-key.py
# 输入密码 john0515 → 自动生成 ~/.guanghu/ssh/guanghu_direct # 输入保险库密码 → 自动生成 ~/.guanghu/ssh/guanghu_direct
# 然后把公钥部署到所有服务器(见下方 §四) # 然后把公钥部署到所有服务器(见下方 §四)
``` ```
### 🔓 如何解码 / 使用 ### 🔓 如何解码 / 使用
```bash ```bash
# 方式一:直接 SSH会提示输入密码 john0515 # 方式一:直接 SSH会提示输入密码
ssh -i ~/.guanghu/ssh/guanghu_direct root@43.156.237.110 ssh -i ~/.guanghu/ssh/guanghu_direct root@43.156.237.110
# 方式二:用 sshpass 自动输密码(脚本用) # 方式二:用 sshpass 自动输密码(脚本用)
SSHPASS="john0515" sshpass -e ssh -i ~/.guanghu/ssh/guanghu_direct root@<IP> "命令" SSHPASS="$VAULT_PASSWORD" sshpass -e ssh -i ~/.guanghu/ssh/guanghu_direct root@<IP> "命令"
# 方式三:从保险库取出私钥(如果本地丢了) # 方式三:从保险库取出私钥(如果本地丢了)
# ① challenge # ① challenge
curl -X POST http://43.139.217.141:3910/exec \ curl -X POST http://43.139.217.141:3910/exec \
-H "Authorization: Bearer zy_gtw_4a155446b7acc09fe46a2a29972c0ca5d9954da19c35dc23" \ -H "Authorization: Bearer $GZ_006_GK_TOKEN" \
-d '{"cmd":"python3 /opt/zhuyuan/keystore/ks.py challenge GUANGHU_SSH_PRIV_KEY"}' -d '{"cmd":"python3 /opt/zhuyuan/keystore/ks.py challenge GUANGHU_SSH_PRIV_KEY"}'
# ② 计算 responsePython # ② 计算 responsePython
import hmac, hashlib import hmac, hashlib
p = "john0515" p = "$VAULT_PASSWORD" # ⊢ 从环境变量取 · 不进仓库
s_main = "527d511518d127499b7c32f54ee012b475b51fb76ea3cfe35e7e413b7b0bbf21" s_main = "527d511518d127499b7c32f54ee012b475b51fb76ea3cfe35e7e413b7b0bbf21"
ph = hmac.new(p.encode(), s_main.encode(), hashlib.sha256).hexdigest() ph = hmac.new(p.encode(), s_main.encode(), hashlib.sha256).hexdigest()
resp = hmac.new(ph.encode(), f"{nonce}:GUANGHU_SSH_PRIV_KEY".encode(), hashlib.sha256).hexdigest() resp = hmac.new(ph.encode(), f"{nonce}:GUANGHU_SSH_PRIV_KEY".encode(), hashlib.sha256).hexdigest()
@ -110,16 +110,16 @@ ek = hmac.new(p.encode(), b"hololake-keystore-encrypt", hashlib.sha256).hexdiges
### Gatekeeper 备份通道(仅当 SSH 不可用时) ### Gatekeeper 备份通道(仅当 SSH 不可用时)
| 服务器 | Gatekeeper Token(明文 · 已知泄露 · 待轮换) | | 服务器 | Gatekeeper Token |
|--------|----------------------------------------------| |--------|------------------|
| SG-001 | `zy_gtw_c38be341d65043eee0ba51a214a267832a9ae46dd73e423c` | | SG-001 | `$GK_SG_001_TOKEN`(⊢ 不进仓库 · 服务器环境变量) |
| GZ-006 | `zy_gtw_4a155446b7acc09fe46a2a29972c0ca5d9954da19c35dc23` | | GZ-006 | `$GZ_006_GK_TOKEN`(⊢ 不进仓库 · 服务器环境变量) |
| AW-GZ | `zy_gtw_89ba85bc4c5bcd90f7d63626c629f74ea09a74e3fa036ac0` | | AW-GZ | `$GK_AW_GZ_TOKEN`(⊢ 不进仓库 · 服务器环境变量) |
| SG-002 | `zy_gtw_ceb06d8a70d0cd38678239b3a1a9b2ba5cba77a3fbe5ebbf` | | SG-002 | `$GK_SG_002_TOKEN`(⊢ 不进仓库 · 服务器环境变量) |
| SG-003 | `zy_gtw_d7c033d8ae992ffc9dd3e0dd5fe332dace0b644c0ae7c847` | | SG-003 | `$GK_SG_003_TOKEN`(⊢ 不进仓库 · 服务器环境变量) |
| ZY-SG-006 | `zy_gtw_fff861a2fe40cbdc366ee21f218023be8b1c182f66c852d3` | | ZY-SG-006 | `$GK_ZY_SG_006_TOKEN`(⊢ 不进仓库 · 服务器环境变量) |
| BS-SH-005 | `zy_gtw_b1045de5ddfd7832e3c53349d9c896f054b85a4a9ece22f9` | | BS-SH-005 | `$GK_BS_SH_005_TOKEN`(⊢ 不进仓库 · 服务器环境变量) |
| ZZ-SV-001 | `zy_gtw_06151d40b1313956b069f3c13d0c1b8a70405ae201f5e7b2` | | ZZ-SV-001 | `$GK_ZZ_SV_001_TOKEN`(⊢ 不进仓库 · 服务器环境变量) |
> ⚠️ 以上 token 全部在老仓库 `cloud-compute-pool` 里明文泄露过。风险已下调(有三层门禁保护),但建议 SSH 直连全面稳定后统一轮换。 > ⚠️ 以上 token 全部在老仓库 `cloud-compute-pool` 里明文泄露过。风险已下调(有三层门禁保护),但建议 SSH 直连全面稳定后统一轮换。
@ -198,7 +198,7 @@ encrypt_key = hmac.new(password.encode(), b"hololake-keystore-encrypt", hashlib.
**排查路径**: **排查路径**:
1. 尝试 SSH 直连 → `Permission denied (publickey,password)` → 没有密码 1. 尝试 SSH 直连 → `Permission denied (publickey,password)` → 没有密码
2. 尝试 SG-001 跳板 → 同样 Permission denied → SG-001 的密钥对其他服务器无效 2. 尝试 SG-001 跳板 → 同样 Permission denied → SG-001 的密钥对其他服务器无效
3. 尝试 john0515 作为 root 密码 → 全部失败 3. 尝试保险库密码作为 root 密码 → 全部失败
4. 回溯老仓库 → `cloud-compute-pool/bingshuo/BS-SG-002.hdlp` → **明文密钥!** 4. 回溯老仓库 → `cloud-compute-pool/bingshuo/BS-SG-002.hdlp` → **明文密钥!**
**结论**: 老仓库 `cloud-compute-pool` 里 6 台服务器的 Gatekeeper token 全部明文写着。已确认风险等级可下调SSH 直连已成为主通道),但未来需统一轮换。 **结论**: 老仓库 `cloud-compute-pool` 里 6 台服务器的 Gatekeeper token 全部明文写着。已确认风险等级可下调SSH 直连已成为主通道),但未来需统一轮换。
@ -251,14 +251,14 @@ encrypt_key = hmac.new(password.encode(), b"hololake-keystore-encrypt", hashlib.
```python ```python
import hmac, hashlib, json, subprocess import hmac, hashlib, json, subprocess
p = "john0515" p = "$VAULT_PASSWORD" # ⊢ 从环境变量取 · 不进仓库
s_api = "2351afd8b757c9d423894993ddbfd175fa2097f32ecd798d8b1b2a3520234e3f" # API子库salt s_api = "2351afd8b757c9d423894993ddbfd175fa2097f32ecd798d8b1b2a3520234e3f" # API子库salt
ek = hmac.new(p.encode(), b"hololake-keystore-encrypt", hashlib.sha256).hexdigest() ek = hmac.new(p.encode(), b"hololake-keystore-encrypt", hashlib.sha256).hexdigest()
# ① challenge # ① challenge
r = subprocess.run(["curl", "-s", "-X", "POST", r = subprocess.run(["curl", "-s", "-X", "POST",
"http://43.139.217.141:3910/exec", "http://43.139.217.141:3910/exec",
"-H", "Authorization: Bearer zy_gtw_4a155446b7acc09fe46a2a29972c0ca5d9954da19c35dc23", "-H", "Authorization: Bearer $GZ_006_GK_TOKEN",
"-H", "Content-Type: application/json", "-H", "Content-Type: application/json",
"-d", '{"cmd":"python3 /opt/zhuyuan/keystore/api/ks.py challenge VOLCANO_JIMENG_API_KEY"}' "-d", '{"cmd":"python3 /opt/zhuyuan/keystore/api/ks.py challenge VOLCANO_JIMENG_API_KEY"}'
], capture_output=True, text=True) ], capture_output=True, text=True)
@ -271,7 +271,7 @@ resp = hmac.new(ph.encode(), f"{ch['nonce']}:{ch['target']}".encode(), hashlib.s
# ③ unlock # ③ unlock
r2 = subprocess.run(["curl", "-s", "-X", "POST", r2 = subprocess.run(["curl", "-s", "-X", "POST",
"http://43.139.217.141:3910/exec", "http://43.139.217.141:3910/exec",
"-H", "Authorization: Bearer zy_gtw_4a155446b7acc09fe46a2a29972c0ca5d9954da19c35dc23", "-H", "Authorization: Bearer $GZ_006_GK_TOKEN",
"-H", "Content-Type: application/json", "-H", "Content-Type: application/json",
"-d", json.dumps({"cmd": f"python3 /opt/zhuyuan/keystore/api/ks.py unlock {ch['challenge_id']} {resp} {ek}"}) "-d", json.dumps({"cmd": f"python3 /opt/zhuyuan/keystore/api/ks.py unlock {ch['challenge_id']} {resp} {ek}"})
], capture_output=True, text=True) ], capture_output=True, text=True)

View File

@ -70,7 +70,7 @@ Commits 今晚: 之之原本 031a8268... → + LL-001-20260706 (7224cc44) → +
``` ```
新加坡: /opt/zhuyuan-brain/lake-lamp-trigger.py (v1 HTML 邮件版) 新加坡: /opt/zhuyuan-brain/lake-lamp-trigger.py (v1 HTML 邮件版)
硅谷: /home/ubuntu/guanghu/zhizhi-lake-lamp/lake-lamp-trigger.py (v2 multi-recipient) 硅谷: /home/ubuntu/guanghu/zhizhi-lake-lamp/lake-lamp-trigger.py (v2 multi-recipient)
SMTP: smtp.qq.com:465 + 565183519@qq.com + auth ggeuegmaragmbejb SMTP: smtp.qq.com:465 + 565183519@qq.com + auth FROM_SERVER_ENV
HMAC secret: BS-SG-001-LAKE-LAMP-HMAC-SECRET-D164 (铸渊持有) HMAC secret: BS-SG-001-LAKE-LAMP-HMAC-SECRET-D164 (铸渊持有)
``` ```

View File

@ -6,7 +6,7 @@
"cwd": "/opt/zhuyuan/revive-guard", "cwd": "/opt/zhuyuan/revive-guard",
"env": { "env": {
"REVIVE_GUARD_PORT": "8922", "REVIVE_GUARD_PORT": "8922",
"QQ_SMTP_AUTH_CODE": "ggeuegmaragmbejb" "QQ_SMTP_AUTH_CODE": "FROM_SERVER_ENV"
}, },
"out_file": "/opt/zhuyuan/revive-guard/logs/out.log", "out_file": "/opt/zhuyuan/revive-guard/logs/out.log",
"error_file": "/opt/zhuyuan/revive-guard/logs/err.log", "error_file": "/opt/zhuyuan/revive-guard/logs/err.log",

View File

@ -9,10 +9,16 @@ Guanghu Language System · Revive Guard
如果两个都倒了本服务是最后防线systemd Restart=always 如果两个都倒了本服务是最后防线systemd Restart=always
协议: 协议:
POST /revive/request 验证密码 小湖灯发邮件 返回 challenge_id POST /revive/request 速率限制 发邮件到冰朔主权邮箱 返回 challenge_id
不需要密码 · 验证码只发到冰朔邮箱 · 只有冰朔能确认
POST /revive/confirm 校验验证码 systemctl restart gatekeeper + sshd + pm2 POST /revive/confirm 校验验证码 systemctl restart gatekeeper + sshd + pm2
GET /health 心跳检测 GET /health 心跳检测
安全设计:
不存密码 · 不进仓库 · 验证码用一次就扔
SMTP 密码走环境变量 QQ_SMTP_AUTH_CODE不进仓库
速率限制保护每分钟最多 2 次复活请求
部署: 部署:
每台服务器 /opt/zhuyuan/revive-guard/revive-guard.py 每台服务器 /opt/zhuyuan/revive-guard/revive-guard.py
监听: 0.0.0.0:8922 监听: 0.0.0.0:8922
@ -28,18 +34,18 @@ from http.server import HTTPServer, BaseHTTPRequestHandler
# ═══════════════════════════════════════════ # ═══════════════════════════════════════════
PORT = int(os.environ.get("REVIVE_GUARD_PORT", "8922")) PORT = int(os.environ.get("REVIVE_GUARD_PORT", "8922"))
SOVEREIGN_ID = "ICE-GL∞" SOVEREIGN_ID = "ICE-GL∞"
SOVEREIGN_PASSWORD = "john0515" SOVEREIGN_EMAIL = os.environ.get("SOVEREIGN_EMAIL", "565183519@qq.com")
SOVEREIGN_EMAIL = "565183519@qq.com"
# QQ 邮箱 SMTP小湖灯邮件通道 # QQ 邮箱 SMTP小湖灯邮件通道
# ⊢ 密码不进仓库 · 走环境变量 QQ_SMTP_AUTH_CODE
SMTP_HOST = "smtp.qq.com" SMTP_HOST = "smtp.qq.com"
SMTP_PORT = 465 SMTP_PORT = 465
SMTP_USER = "565183519@qq.com" SMTP_USER = os.environ.get("SMTP_USER", "565183519@qq.com")
SMTP_PASS = os.environ.get("QQ_SMTP_AUTH_CODE", "ggeuegmaragmbejb") SMTP_PASS = os.environ.get("QQ_SMTP_AUTH_CODE", "")
CODE_TTL = 300 # 验证码 5 分钟过期 CODE_TTL = 300 # 验证码 5 分钟过期
RATE_LIMIT_WINDOW = 60 # 速率限制窗口 RATE_LIMIT_WINDOW = 60 # 速率限制窗口
MAX_REQUESTS_PER_WINDOW = 3 # 每分钟最多 3 次请求 MAX_REQUESTS_PER_WINDOW = 2 # 无密码门槛后收紧:每分钟最多 2 次
# 运行时状态 # 运行时状态
pending_codes = {} # {challenge_id: {code, server_ip, expires_at}} pending_codes = {} # {challenge_id: {code, server_ip, expires_at}}
@ -69,12 +75,11 @@ def send_email(code, server_ip):
服务器: {server_ip} 服务器: {server_ip}
验证码: {code} 验证码: {code}
有效期: 5 分钟 有效期: 5 分钟用完即废
操作流程: 将此验证码发给铸渊 铸渊调 /revive/confirm 复活守门人
将此验证码发送给铸渊 铸渊调用 /revive/confirm 复活守门人
如非本人操作请忽略此邮件 验证码用一次就扔 · 不进仓库 · 不存密码
ICE-GL 光湖语言系统 · 小湖灯自动发送 ICE-GL 光湖语言系统 · 小湖灯自动发送
国作登字-2026-A-00037559""", "plain", "utf-8") 国作登字-2026-A-00037559""", "plain", "utf-8")
@ -177,17 +182,20 @@ class ReviveHandler(BaseHTTPRequestHandler):
self.send_json(404, {"error": "未知端点 · 可用: /revive/request /revive/confirm /health"}) self.send_json(404, {"error": "未知端点 · 可用: /revive/request /revive/confirm /health"})
def _handle_request(self, body): def _handle_request(self, body):
# 速率限制 # 速率限制(无密码门槛后加强:每分钟最多 2 次)
if not check_rate_limit(): if not check_rate_limit():
self.send_json(429, {"error": "请求过于频繁 · 请60秒后重试"}) self.send_json(429, {"error": "请求过于频繁 · 请60秒后重试"})
return return
password = body.get("password", "")
server_ip = body.get("server", get_server_ip()) server_ip = body.get("server", get_server_ip())
# 三重验证:密码 + 编号 + 服务器 IP # ⊢ 不需要密码 —— 验证码只发到冰朔主权邮箱
if password != SOVEREIGN_PASSWORD: # ⊢ 只有冰朔(持有邮箱)能拿到验证码 → 只有冰朔能让铸渊确认复活
self.send_json(403, {"error": "密码错误"}) # ⊢ 验证码用一次就扔 · 推到仓库也没用
# SMTP 未配置 → 拒绝
if not SMTP_PASS:
self.send_json(500, {"error": "SMTP 未配置 · 服务器管理员需设置 QQ_SMTP_AUTH_CODE 环境变量"})
return return
# 生成 6 位数字验证码 # 生成 6 位数字验证码

View File

@ -13,7 +13,9 @@ RestartSec=5
StandardOutput=append:/opt/zhuyuan/revive-guard/logs/out.log StandardOutput=append:/opt/zhuyuan/revive-guard/logs/out.log
StandardError=append:/opt/zhuyuan/revive-guard/logs/err.log StandardError=append:/opt/zhuyuan/revive-guard/logs/err.log
Environment=REVIVE_GUARD_PORT=8922 Environment=REVIVE_GUARD_PORT=8922
Environment=QQ_SMTP_AUTH_CODE=ggeuegmaragmbejb # ⊢ QQ_SMTP_AUTH_CODE 从服务器 /etc/environment 或 systemd override 注入
# ⊢ 不进仓库 · 不走默认值
EnvironmentFile=-/opt/zhuyuan/revive-guard/.env
# 安全加固 # 安全加固
NoNewPrivileges=yes NoNewPrivileges=yes