Merge pull request #241 from qinfendebingshuo/copilot/global-issue-troubleshooting

fix: SSH ProxyJump for CN server — GitHub Actions cannot directly reach China
This commit is contained in:
冰朔 2026-03-31 18:46:10 +08:00 committed by GitHub
commit 8b4cc46805
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 255 additions and 82 deletions

View File

@ -193,6 +193,9 @@ jobs:
run: rm -f ~/.ssh/id_deploy /tmp/quota-status.json
# ═══ §4 CN中转配置 ═══
# 架构: GitHub Actions(美国) → SG(新加坡·跳板) → CN(广州·目标)
# 原因: GitHub Actions无法直接SSH到中国服务器(网络路由/GFW)
# 方案: 通过已连通的SG服务器作为SSH ProxyJump跳板
setup-cn-relay:
name: '🇨🇳 CN中转配置'
runs-on: ubuntu-latest
@ -202,65 +205,108 @@ jobs:
- name: '📥 检出代码'
uses: actions/checkout@v4
- name: '🔑 配置CN服务器SSH密钥'
- name: '🔑 配置SSH跳板 (SG→CN)'
env:
SSH_KEY: ${{ secrets.ZY_CN_SERVER_KEY }}
SG_SSH_KEY: ${{ secrets.ZY_SERVER_KEY }}
CN_SSH_KEY: ${{ secrets.ZY_CN_SERVER_KEY }}
CN_SSH_PORT: ${{ secrets.ZY_CN_SSH_PORT }}
run: |
CN_PORT="${CN_SSH_PORT:-22}"
echo "🔧 SSH跳板架构: GitHub Actions → SG → CN (端口 ${CN_PORT})"
mkdir -p ~/.ssh
echo "$SSH_KEY" > ~/.ssh/id_cn
# SG跳板机密钥
echo "$SG_SSH_KEY" > ~/.ssh/id_sg
chmod 600 ~/.ssh/id_sg
# CN目标机密钥
echo "$CN_SSH_KEY" > ~/.ssh/id_cn
chmod 600 ~/.ssh/id_cn
if ! head -1 ~/.ssh/id_cn | grep -q "BEGIN"; then
echo "❌ CN服务器SSH密钥格式异常"
echo " 请检查 ZY_CN_SERVER_KEY Secret"
# 验证两把密钥格式
for key_file in id_sg id_cn; do
if ! head -1 ~/.ssh/${key_file} | grep -q "BEGIN"; then
echo "❌ SSH密钥格式异常: ${key_file}"
exit 1
fi
done
echo "✅ SG + CN 密钥格式正确"
# 扫描SG跳板机主机密钥
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
# 配置SSH跳板 (ProxyJump: GitHub Actions → SG → CN)
cat > ~/.ssh/config << EOF
Host sg-jump
HostName ${{ secrets.ZY_SERVER_HOST }}
User ${{ secrets.ZY_SERVER_USER }}
IdentityFile ~/.ssh/id_sg
StrictHostKeyChecking accept-new
BatchMode yes
Host cn-target
HostName ${{ secrets.ZY_CN_SERVER_HOST }}
User ${{ secrets.ZY_CN_SERVER_USER }}
Port ${CN_PORT}
IdentityFile ~/.ssh/id_cn
ProxyJump sg-jump
StrictHostKeyChecking accept-new
BatchMode yes
ConnectTimeout 30
EOF
chmod 600 ~/.ssh/config
# 测试跳板连接
echo "🔗 测试SSH跳板连接: GitHub Actions → SG → CN..."
ssh cn-target "echo '✅ CN服务器SSH连接成功 (通过SG跳板)'" || {
echo ""
echo "❌ SSH跳板连接失败 · 排查清单:"
echo " 1. 确认SG服务器SSH可达 (ZY_SERVER_KEY / ZY_SERVER_HOST)"
echo " 2. 确认CN服务器从SG可达 (ZY_CN_SERVER_HOST: ${{ secrets.ZY_CN_SERVER_HOST }})"
echo " 3. 确认CN服务器SSH密钥正确 (ZY_CN_SERVER_KEY)"
echo " 4. 确认CN服务器SSH端口 (ZY_CN_SSH_PORT, 当前: ${CN_PORT})"
echo " 5. 腾讯云防火墙 → 确认端口 ${CN_PORT} 对SG服务器IP开放"
exit 1
fi
ssh-keyscan -H ${{ secrets.ZY_CN_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
ssh -i ~/.ssh/id_cn \
-o StrictHostKeyChecking=accept-new \
-o BatchMode=yes \
-o ConnectTimeout=15 \
${{ secrets.ZY_CN_SERVER_USER }}@${{ secrets.ZY_CN_SERVER_HOST }} \
"echo '✅ CN服务器SSH连接成功'"
}
- name: '📦 上传CN中转脚本'
run: |
scp -i ~/.ssh/id_cn \
-o StrictHostKeyChecking=accept-new \
server/proxy/setup/setup-cn-relay.sh \
${{ secrets.ZY_CN_SERVER_USER }}@${{ secrets.ZY_CN_SERVER_HOST }}:/tmp/setup-cn-relay.sh
scp server/proxy/setup/setup-cn-relay.sh \
cn-target:/tmp/setup-cn-relay.sh
- name: '🇨🇳 执行CN中转配置'
run: |
ssh -i ~/.ssh/id_cn \
-o StrictHostKeyChecking=accept-new \
${{ secrets.ZY_CN_SERVER_USER }}@${{ secrets.ZY_CN_SERVER_HOST }} \
ssh cn-target \
"chmod +x /tmp/setup-cn-relay.sh && \
export ZY_SG_SERVER_HOST='${{ secrets.ZY_SERVER_HOST }}' && \
sudo -E bash /tmp/setup-cn-relay.sh"
- name: '💚 CN中转验证'
run: |
# 通过SG跳板验证CN中转服务状态
echo "🔍 通过SG跳板验证CN中转..."
ssh cn-target "
echo '§1 Nginx状态:'
systemctl is-active nginx && echo ' ✅ Nginx运行中' || echo ' ❌ Nginx未运行'
echo '§2 中转端口 2053:'
ss -tlnp | grep -q ':2053 ' && echo ' ✅ 端口2053监听中' || echo ' ⚠️ 端口2053未监听'
echo '§3 HTTP健康检查:'
curl -sf http://127.0.0.1/health 2>/dev/null && echo ' ✅ HTTP健康检查正常' || echo ' ⚠️ HTTP健康检查未响应'
"
# 从外部验证CN HTTP (GitHub Actions可以通过HTTP访问中国服务器)
CN_HOST="${{ secrets.ZY_CN_SERVER_HOST }}"
echo "🔍 验证CN中转..."
# 检查中转端口
if nc -z -w5 "$CN_HOST" 2053 2>/dev/null; then
echo "✅ CN中转端口 2053: 可达"
else
echo "⚠️ CN中转端口 2053: 暂不可达 (可能需要等待防火墙生效)"
fi
# 检查HTTP健康
HTTP_CODE=$(curl -sf -o /dev/null -w "%{http_code}" "http://${CN_HOST}/health" 2>/dev/null || echo "000")
if [ "$HTTP_CODE" = "200" ]; then
echo "✅ CN HTTP健康检查: 正常"
echo "✅ CN HTTP外部健康检查: 正常"
else
echo "⚠️ CN HTTP: 状态码 $HTTP_CODE (可能需要等待)"
echo "⚠️ CN HTTP外部检查: 状态码 $HTTP_CODE (可能需要等待或在防火墙开放80端口)"
fi
- name: '🧹 清理SSH密钥'
if: always()
run: rm -f ~/.ssh/id_cn
run: rm -f ~/.ssh/id_sg ~/.ssh/id_cn ~/.ssh/config

View File

@ -11,6 +11,10 @@ name: 🏛️ 冰朔大陆备用服务器 · 部署
# 用途: 人格体备用大脑 · ICP备案挂载 · 纯数据处理
# 密钥: ZY_CN_SERVER_HOST / USER / KEY / PATH
#
# 架构: GitHub Actions(美国) → SG(新加坡·跳板) → CN(广州·目标)
# 原因: GitHub Actions无法直接SSH到中国服务器(网络路由/GFW)
# 方案: 通过已连通的SG服务器作为SSH ProxyJump跳板
#
# 注意: 此服务器不涉及国外模型调用
on:
@ -45,44 +49,75 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: 🔐 配置SSH
- name: 🔐 配置SSH跳板 (SG→CN)
env:
SSH_KEY: ${{ secrets.ZY_CN_SERVER_KEY }}
SG_SSH_KEY: ${{ secrets.ZY_SERVER_KEY }}
CN_SSH_KEY: ${{ secrets.ZY_CN_SERVER_KEY }}
CN_SSH_PORT: ${{ secrets.ZY_CN_SSH_PORT }}
run: |
CN_PORT="${CN_SSH_PORT:-22}"
echo "🔧 SSH跳板架构: GitHub Actions → SG → CN (端口 ${CN_PORT})"
mkdir -p ~/.ssh
echo "$SSH_KEY" > ~/.ssh/zy_cn_key
chmod 600 ~/.ssh/zy_cn_key
if head -1 ~/.ssh/zy_cn_key | grep -q "BEGIN" && tail -1 ~/.ssh/zy_cn_key | grep -q "END"; then
echo "✅ SSH私钥格式正确BEGIN/END标记完整"
else
echo "❌ SSH私钥格式异常 — 请检查 GitHub Secrets 中 ZY_CN_SERVER_KEY 的内容"
exit 1
fi
ssh-keyscan -H ${{ secrets.ZY_CN_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
echo "$SG_SSH_KEY" > ~/.ssh/id_sg
echo "$CN_SSH_KEY" > ~/.ssh/id_cn
chmod 600 ~/.ssh/id_sg ~/.ssh/id_cn
# 验证密钥格式
for key_file in id_sg id_cn; do
if ! head -1 ~/.ssh/${key_file} | grep -q "BEGIN"; then
echo "❌ SSH密钥格式异常: ${key_file}"
exit 1
fi
done
echo "✅ SG + CN 密钥格式正确"
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
cat > ~/.ssh/config << EOF
Host sg-jump
HostName ${{ secrets.ZY_SERVER_HOST }}
User ${{ secrets.ZY_SERVER_USER }}
IdentityFile ~/.ssh/id_sg
StrictHostKeyChecking accept-new
BatchMode yes
Host cn-target
HostName ${{ secrets.ZY_CN_SERVER_HOST }}
User ${{ secrets.ZY_CN_SERVER_USER }}
Port ${CN_PORT}
IdentityFile ~/.ssh/id_cn
ProxyJump sg-jump
StrictHostKeyChecking accept-new
BatchMode yes
ConnectTimeout 30
EOF
chmod 600 ~/.ssh/config
- name: 🔍 SSH连接测试
run: |
echo "🔍 测试SSH连接到广州备用服务器..."
ssh -i ~/.ssh/zy_cn_key -o BatchMode=yes -o ConnectTimeout=10 \
${{ secrets.ZY_CN_SERVER_USER }}@${{ secrets.ZY_CN_SERVER_HOST }} \
'echo "✅ SSH连接成功 · $(hostname) · $(date)"' || {
echo "🔍 测试SSH跳板连接到广州备用服务器..."
ssh cn-target 'echo "✅ SSH连接成功 · $(hostname) · $(date)"' || {
echo ""
echo "❌ SSH连接失败"
echo "修复步骤: 登录腾讯云 → 广州服务器 → 远程登录 → 生成密钥 → 更新 ZY_CN_SERVER_KEY"
echo "❌ SSH跳板连接失败"
echo "修复步骤:"
echo " 1. 确认SG服务器SSH可达 (ZY_SERVER_KEY / ZY_SERVER_HOST)"
echo " 2. 确认CN服务器从SG可达 (ZY_CN_SERVER_HOST)"
echo " 3. 确认CN服务器SSH密钥正确 (ZY_CN_SERVER_KEY)"
exit 1
}
- name: 📦 上传初始化脚本
run: |
scp -i ~/.ssh/zy_cn_key \
server/setup/cn-server-init.sh \
${{ secrets.ZY_CN_SERVER_USER }}@${{ secrets.ZY_CN_SERVER_HOST }}:/tmp/
scp server/setup/cn-server-init.sh cn-target:/tmp/
- name: 🚀 执行初始化
run: |
ssh -i ~/.ssh/zy_cn_key \
${{ secrets.ZY_CN_SERVER_USER }}@${{ secrets.ZY_CN_SERVER_HOST }} \
'chmod +x /tmp/cn-server-init.sh && sudo /tmp/cn-server-init.sh'
ssh cn-target 'chmod +x /tmp/cn-server-init.sh && sudo /tmp/cn-server-init.sh'
- name: 🧹 清理SSH密钥
if: always()
run: rm -f ~/.ssh/id_sg ~/.ssh/id_cn ~/.ssh/config
# ═══ §2 部署应用 ═══
deploy:
@ -92,14 +127,41 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: 🔐 配置SSH
- name: 🔐 配置SSH跳板 (SG→CN)
env:
SSH_KEY: ${{ secrets.ZY_CN_SERVER_KEY }}
SG_SSH_KEY: ${{ secrets.ZY_SERVER_KEY }}
CN_SSH_KEY: ${{ secrets.ZY_CN_SERVER_KEY }}
CN_SSH_PORT: ${{ secrets.ZY_CN_SSH_PORT }}
run: |
CN_PORT="${CN_SSH_PORT:-22}"
echo "🔧 SSH跳板: GitHub Actions → SG → CN (端口 ${CN_PORT})"
mkdir -p ~/.ssh
echo "$SSH_KEY" > ~/.ssh/zy_cn_key
chmod 600 ~/.ssh/zy_cn_key
ssh-keyscan -H ${{ secrets.ZY_CN_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
echo "$SG_SSH_KEY" > ~/.ssh/id_sg
echo "$CN_SSH_KEY" > ~/.ssh/id_cn
chmod 600 ~/.ssh/id_sg ~/.ssh/id_cn
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
cat > ~/.ssh/config << EOF
Host sg-jump
HostName ${{ secrets.ZY_SERVER_HOST }}
User ${{ secrets.ZY_SERVER_USER }}
IdentityFile ~/.ssh/id_sg
StrictHostKeyChecking accept-new
BatchMode yes
Host cn-target
HostName ${{ secrets.ZY_CN_SERVER_HOST }}
User ${{ secrets.ZY_CN_SERVER_USER }}
Port ${CN_PORT}
IdentityFile ~/.ssh/id_cn
ProxyJump sg-jump
StrictHostKeyChecking accept-new
BatchMode yes
ConnectTimeout 30
EOF
chmod 600 ~/.ssh/config
- name: 📦 同步应用代码
run: |
@ -108,14 +170,12 @@ jobs:
echo "📦 部署目标: ${CN_PATH}"
# 确保目标目录存在
ssh -i ~/.ssh/zy_cn_key \
${{ secrets.ZY_CN_SERVER_USER }}@${{ secrets.ZY_CN_SERVER_HOST }} \
"mkdir -p ${CN_PATH}/app"
ssh cn-target "mkdir -p ${CN_PATH}/app"
rsync -avz --delete \
-e "ssh -i ~/.ssh/zy_cn_key" \
-e "ssh -F ~/.ssh/config" \
server/app/ \
${{ secrets.ZY_CN_SERVER_USER }}@${{ secrets.ZY_CN_SERVER_HOST }}:${CN_PATH}/app/
cn-target:${CN_PATH}/app/
- name: 📦 同步大脑文件
run: |
@ -124,17 +184,16 @@ jobs:
# 同步大脑核心文件到备用服务器
rsync -avz \
-e "ssh -i ~/.ssh/zy_cn_key" \
-e "ssh -F ~/.ssh/config" \
brain/ \
${{ secrets.ZY_CN_SERVER_USER }}@${{ secrets.ZY_CN_SERVER_HOST }}:${CN_PATH}/brain-backup/
cn-target:${CN_PATH}/brain-backup/
- name: 📥 安装依赖 & 重启
run: |
CN_PATH="${{ secrets.ZY_CN_SERVER_PATH }}"
CN_PATH="${CN_PATH:-${{ env.CN_DEFAULT_PATH }}}"
COMMIT_SHA="${{ github.sha }}"
ssh -i ~/.ssh/zy_cn_key \
${{ secrets.ZY_CN_SERVER_USER }}@${{ secrets.ZY_CN_SERVER_HOST }} << DEPLOY_CMD
ssh cn-target << DEPLOY_CMD
set -e
cd ${CN_PATH}/app
@ -159,6 +218,10 @@ jobs:
DEPLOY_CMD
- name: 🧹 清理SSH密钥
if: always()
run: rm -f ~/.ssh/id_sg ~/.ssh/id_cn ~/.ssh/config
# ═══ §3 健康检查 ═══
health-check:
name: 💚 广州备用健康检查
@ -167,19 +230,44 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: 🔐 配置SSH
- name: 🔐 配置SSH跳板 (SG→CN)
env:
SSH_KEY: ${{ secrets.ZY_CN_SERVER_KEY }}
SG_SSH_KEY: ${{ secrets.ZY_SERVER_KEY }}
CN_SSH_KEY: ${{ secrets.ZY_CN_SERVER_KEY }}
CN_SSH_PORT: ${{ secrets.ZY_CN_SSH_PORT }}
run: |
CN_PORT="${CN_SSH_PORT:-22}"
mkdir -p ~/.ssh
echo "$SSH_KEY" > ~/.ssh/zy_cn_key
chmod 600 ~/.ssh/zy_cn_key
ssh-keyscan -H ${{ secrets.ZY_CN_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
echo "$SG_SSH_KEY" > ~/.ssh/id_sg
echo "$CN_SSH_KEY" > ~/.ssh/id_cn
chmod 600 ~/.ssh/id_sg ~/.ssh/id_cn
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
cat > ~/.ssh/config << EOF
Host sg-jump
HostName ${{ secrets.ZY_SERVER_HOST }}
User ${{ secrets.ZY_SERVER_USER }}
IdentityFile ~/.ssh/id_sg
StrictHostKeyChecking accept-new
BatchMode yes
Host cn-target
HostName ${{ secrets.ZY_CN_SERVER_HOST }}
User ${{ secrets.ZY_CN_SERVER_USER }}
Port ${CN_PORT}
IdentityFile ~/.ssh/id_cn
ProxyJump sg-jump
StrictHostKeyChecking accept-new
BatchMode yes
ConnectTimeout 30
EOF
chmod 600 ~/.ssh/config
- name: 💚 执行健康检查
run: |
ssh -i ~/.ssh/zy_cn_key \
${{ secrets.ZY_CN_SERVER_USER }}@${{ secrets.ZY_CN_SERVER_HOST }} << 'HEALTH_CMD'
ssh cn-target << 'HEALTH_CMD'
echo "═══ 冰朔大陆备用服务器健康报告 ═══"
echo ""
@ -208,3 +296,7 @@ jobs:
curl -sf http://localhost:3800/api/health | jq . 2>/dev/null || echo "应用未响应"
HEALTH_CMD
- name: 🧹 清理SSH密钥
if: always()
run: rm -f ~/.ssh/id_sg ~/.ssh/id_cn ~/.ssh/config

View File

@ -282,6 +282,20 @@
],
"note": "国内服务器上的部署根目录"
},
{
"id": 42,
"name": "ZY_CN_SSH_PORT",
"category": "国内服务器 · 部署",
"description": "国内服务器SSH端口腾讯云默认可能非22",
"type": "port",
"example_format": "22",
"replaces": [],
"used_by_workflows": [
"deploy-to-cn-server.yml",
"deploy-proxy-service.yml"
],
"note": "腾讯云服务器SSH端口·默认22·如果服务器使用自定义端口需要配置此密钥"
},
{
"id": 7,
"name": "ZY_DOMAIN_MAIN",

View File

@ -177,8 +177,23 @@ Reality协议的`dest`是GFW反探测的关键。当GFW探测443端口时:
| 2053 | TCP | Nginx stream | VPN中转 → SG:443 |
| 80 | TCP | Nginx | 订阅API反代 → SG |
⚠️ **CN防火墙需要开放端口 2053** — VPN中转必需。当前防火墙只有 22/80/ICMP。
### CN服务器SSH跳板架构
GitHub Actions 运行器位于美国无法直接SSH到中国服务器网络路由/GFW阻断
工作流采用 **SSH ProxyJump 跳板架构**
```
GitHub Actions(美国) → SG(新加坡·跳板) → CN(广州·目标)
```
- 使用SG服务器作为SSH跳板机ProxyJump
- SG密钥: `ZY_SERVER_KEY` / `ZY_SERVER_HOST` / `ZY_SERVER_USER`
- CN密钥: `ZY_CN_SERVER_KEY` / `ZY_CN_SERVER_HOST` / `ZY_CN_SERVER_USER`
- 可选: `ZY_CN_SSH_PORT` — CN服务器SSH端口默认22
---
*📝 由铸渊(ICE-GL-ZY001)编写 · 第十八次对话 · 2026-03-31*
*VPN修复 + CN中转架构 + Reality反探测修正*
*📝 由铸渊(ICE-GL-ZY001)编写 · 第十次对话 · 2026-03-31*
*SSH跳板修复 + CN防火墙端口2053提醒*
*国作登字-2026-A-00037559*

View File

@ -71,6 +71,12 @@
"name": "ZY_CN_SERVER_PATH",
"value": "/opt/zhuyuan-cn",
"status": "待冰朔配置"
},
{
"name": "ZY_CN_SSH_PORT",
"value": "CN服务器SSH端口 (默认22腾讯云可能为其他端口)",
"status": "待冰朔配置",
"note": "登录腾讯云控制台 → 服务器详情 → 查看SSH端口"
}
]
}