fix: 铸渊专线密钥生成脚本健壮性修复 - 移除set -e改为手动错误处理 - xray x25519支持stdout/stderr双路捕获和多种输出格式 - openssl X25519 fallback使用DER格式正确提取base64url密钥 - 随机占位密钥兜底 - install-xray.sh防止BBR重复追加和generate-keys错误传播 - deploy-proxy.sh支持环境变量优先和密钥文件fallback

Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/30c8f4ac-a9ab-450c-85ce-ac2c40ffc705

Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-03-31 03:44:32 +00:00 committed by GitHub
parent 5f42028cb2
commit b8a5355827
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 158 additions and 38 deletions

View File

@ -21,7 +21,8 @@
# bash deploy-proxy.sh restart — 重启所有服务
# ═══════════════════════════════════════════════
set -euo pipefail
set -uo pipefail
# 注意: 不使用 set -e关键步骤手动检查错误
PROXY_DIR="/opt/zhuyuan/proxy"
REPO_PROXY_DIR="$(dirname "$0")"
@ -39,7 +40,10 @@ install() {
echo ""
echo "═══ [2/7] 配置Xray ═══"
configure_xray
if ! configure_xray; then
echo "❌ Xray配置失败安装中止"
exit 1
fi
echo ""
echo "═══ [3/7] 启动Xray服务 ═══"
@ -82,21 +86,28 @@ install() {
# ── 配置Xray ──────────────────────────────────
configure_xray() {
# 读取密钥
# 读取密钥 (优先环境变量, 其次密钥文件)
KEYS_FILE="$PROXY_DIR/.env.keys"
if [ ! -f "$KEYS_FILE" ]; then
echo "❌ 密钥文件不存在: $KEYS_FILE"
echo " 请先运行 install-xray.sh 生成密钥"
exit 1
if [ -z "${ZY_PROXY_UUID:-}" ] && [ -f "$KEYS_FILE" ]; then
# shellcheck source=/dev/null
source "$KEYS_FILE"
fi
# shellcheck source=/dev/null
source "$KEYS_FILE"
# 验证关键变量
if [ -z "${ZY_PROXY_UUID:-}" ]; then
echo "❌ 密钥文件中缺少 ZY_PROXY_UUID"
exit 1
echo "❌ 缺少 ZY_PROXY_UUID"
echo " 请先运行 install 生成密钥,或设置环境变量"
return 1
fi
if [ -z "${ZY_PROXY_REALITY_PRIVATE_KEY:-}" ]; then
echo "❌ 缺少 ZY_PROXY_REALITY_PRIVATE_KEY"
return 1
fi
if [ -z "${ZY_PROXY_REALITY_SHORT_ID:-}" ]; then
echo "❌ 缺少 ZY_PROXY_REALITY_SHORT_ID"
return 1
fi
# 用环境变量替换模板
@ -112,9 +123,10 @@ configure_xray() {
if xray run -test -c "$CONFIG_OUTPUT" 2>/dev/null; then
echo "✅ Xray配置验证通过"
else
echo "❌ Xray配置验证失败"
xray run -test -c "$CONFIG_OUTPUT"
exit 1
echo "⚠️ Xray配置验证失败查看详情:"
xray run -test -c "$CONFIG_OUTPUT" 2>&1 || true
echo " 配置文件: $CONFIG_OUTPUT"
return 1
fi
}
@ -145,12 +157,14 @@ configure_nginx() {
else
echo " Nginx代理配置已存在"
fi
nginx -t && nginx -s reload || true
if nginx -t 2>/dev/null; then
nginx -s reload || true
fi
}
# ── 启动PM2服务 ───────────────────────────────
start_pm2_services() {
cd "$PROXY_DIR"
cd "$PROXY_DIR" || { echo "❌ 无法进入 $PROXY_DIR"; return 1; }
# 加载密钥作为环境变量
if [ -f "$PROXY_DIR/.env.keys" ]; then

View File

@ -15,36 +15,120 @@
# ⚠️ 生成的密钥需要添加到GitHub Secrets
# ═══════════════════════════════════════════════
set -euo pipefail
set -uo pipefail
# 注意: 不使用 set -e手动处理错误以确保密钥生成的健壮性
echo "════════════════════════════════════════"
echo "🔑 铸渊专线 · 密钥生成"
echo "════════════════════════════════════════"
echo ""
HAS_ERROR=0
# ── 生成UUID ─────────────────────────────────
UUID=$(xray uuid 2>/dev/null || cat /proc/sys/kernel/random/uuid)
UUID=$(xray uuid 2>/dev/null || cat /proc/sys/kernel/random/uuid || true)
if [ -z "$UUID" ]; then
UUID=$(cat /proc/sys/kernel/random/uuid 2>/dev/null || openssl rand -hex 16 | sed 's/\(.\{8\}\)\(.\{4\}\)\(.\{4\}\)\(.\{4\}\)\(.\{12\}\)/\1-\2-\3-\4-\5/')
fi
echo "ZY_PROXY_UUID=$UUID"
# ── 生成Reality X25519密钥对 ──────────────────
PRIVATE_KEY=""
PUBLIC_KEY=""
# 方法1: 使用 xray x25519
if command -v xray &>/dev/null; then
KEYS=$(xray x25519)
PRIVATE_KEY=$(echo "$KEYS" | grep "Private key:" | awk '{print $3}')
PUBLIC_KEY=$(echo "$KEYS" | grep "Public key:" | awk '{print $3}')
else
# Fallback: 用openssl生成
PRIVATE_KEY=$(openssl genpkey -algorithm X25519 2>/dev/null | openssl pkey -text -noout 2>/dev/null | grep -A5 priv: | tail -4 | tr -d ' :\n' | head -c 43)
PUBLIC_KEY="(需要安装xray后重新生成)"
echo " 尝试 xray x25519 ..."
KEYS_OUTPUT=""
KEYS_STDERR=""
# 捕获stdout和stderr分别处理
KEYS_STDERR_FILE=$(mktemp /tmp/xray-keys-stderr.XXXXXX)
KEYS_OUTPUT=$(xray x25519 2>"$KEYS_STDERR_FILE") || true
KEYS_STDERR=$(cat "$KEYS_STDERR_FILE" 2>/dev/null) || true
rm -f "$KEYS_STDERR_FILE"
# 如果stdout为空尝试从stderr获取某些版本输出到stderr
if [ -z "$KEYS_OUTPUT" ] && [ -n "$KEYS_STDERR" ]; then
echo " xray x25519 输出在stderr自动切换"
KEYS_OUTPUT="$KEYS_STDERR"
fi
if [ -n "$KEYS_OUTPUT" ]; then
# 灵活解析: 支持多种输出格式
# 格式1: "Private key: <key>" (标准格式)
# 格式2: "PrivateKey: <key>"
# 格式3: 仅输出两行key
PRIVATE_KEY=$(echo "$KEYS_OUTPUT" | grep -i "private" | awk '{print $NF}') || true
PUBLIC_KEY=$(echo "$KEYS_OUTPUT" | grep -i "public" | awk '{print $NF}') || true
# 如果上面的解析失败,尝试按行解析(假设第一行私钥第二行公钥)
if [ -z "$PRIVATE_KEY" ]; then
LINE_COUNT=$(echo "$KEYS_OUTPUT" | wc -l)
if [ "$LINE_COUNT" -ge 2 ]; then
PRIVATE_KEY=$(echo "$KEYS_OUTPUT" | sed -n '1p' | awk '{print $NF}')
PUBLIC_KEY=$(echo "$KEYS_OUTPUT" | sed -n '2p' | awk '{print $NF}')
fi
fi
fi
if [ -n "$PRIVATE_KEY" ] && [ -n "$PUBLIC_KEY" ]; then
echo " ✅ xray x25519 密钥生成成功"
else
echo " ⚠️ xray x25519 解析失败"
if [ -n "$KEYS_OUTPUT" ]; then
echo " stdout: $KEYS_OUTPUT"
fi
if [ -n "$KEYS_STDERR" ]; then
echo " stderr: $KEYS_STDERR"
fi
PRIVATE_KEY=""
PUBLIC_KEY=""
fi
fi
# 方法2: 使用 openssl 生成 X25519 密钥
if [ -z "$PRIVATE_KEY" ] && command -v openssl &>/dev/null; then
echo " 尝试 openssl X25519 ..."
TMPKEY=$(mktemp /tmp/xray-privkey.XXXXXX)
if openssl genpkey -algorithm X25519 -out "$TMPKEY" 2>/dev/null; then
# 从DER格式提取原始32字节密钥转为base64url (43字符)
PRIVATE_KEY=$(openssl pkey -in "$TMPKEY" -outform DER 2>/dev/null \
| tail -c 32 | base64 | tr '+/' '-_' | tr -d '=') || true
PUBLIC_KEY=$(openssl pkey -in "$TMPKEY" -pubout -outform DER 2>/dev/null \
| tail -c 32 | base64 | tr '+/' '-_' | tr -d '=') || true
fi
rm -f "$TMPKEY"
if [ -n "$PRIVATE_KEY" ]; then
echo " ✅ openssl X25519 密钥生成成功"
if [ -z "$PUBLIC_KEY" ]; then
PUBLIC_KEY="(需要在服务器上运行 xray x25519 重新生成公钥)"
fi
else
echo " ⚠️ openssl X25519 生成失败"
fi
fi
# 方法3: 最终兜底 - 生成随机占位密钥
if [ -z "$PRIVATE_KEY" ]; then
echo " ⚠️ 所有X25519生成方法均失败使用随机占位密钥"
echo " ⚠️ 请在服务器上手动运行: xray x25519"
PRIVATE_KEY=$(openssl rand -base64 32 | tr '+/' '-_' | tr -d '=' | head -c 43)
PUBLIC_KEY="PLACEHOLDER_REGENERATE_WITH_XRAY_X25519"
HAS_ERROR=1
fi
echo "ZY_PROXY_REALITY_PRIVATE_KEY=$PRIVATE_KEY"
echo "ZY_PROXY_REALITY_PUBLIC_KEY=$PUBLIC_KEY"
# ── 生成ShortId ──────────────────────────────
SHORT_ID=$(openssl rand -hex 8)
SHORT_ID=$(openssl rand -hex 8 || head -c 8 /dev/urandom | xxd -p)
echo "ZY_PROXY_REALITY_SHORT_ID=$SHORT_ID"
# ── 生成订阅Token ────────────────────────────
SUB_TOKEN=$(openssl rand -hex 32)
SUB_TOKEN=$(openssl rand -hex 32 || head -c 32 /dev/urandom | xxd -p)
echo "ZY_PROXY_SUB_TOKEN=$SUB_TOKEN"
echo ""
@ -77,3 +161,10 @@ EOF
chmod 600 "$KEYS_FILE"
echo ""
echo "密钥已保存到服务器: $KEYS_FILE (权限600)"
if [ "$HAS_ERROR" -eq 1 ]; then
echo ""
echo "⚠️ 密钥生成使用了占位符,请手动重新生成:"
echo " ssh root@<server> 'xray x25519'"
echo " 然后更新 $KEYS_FILE 和 GitHub Secrets"
fi

View File

@ -12,7 +12,8 @@
# 用法: bash install-xray.sh
# ═══════════════════════════════════════════════
set -euo pipefail
set -uo pipefail
# 注意: 不使用 set -e手动处理关键步骤错误
echo "════════════════════════════════════════"
echo "🌐 铸渊专线 · Xray-core 安装"
@ -20,8 +21,8 @@ echo "════════════════════════
# ── 1. 系统更新 ──────────────────────────────
echo "[1/6] 系统更新..."
apt-get update -y
apt-get upgrade -y
apt-get update -y || { echo "❌ apt-get update 失败"; exit 1; }
apt-get upgrade -y || echo "⚠️ apt-get upgrade 部分失败,继续安装"
# ── 2. 安装Xray-core ────────────────────────
echo "[2/6] 安装Xray-core..."
@ -31,7 +32,12 @@ else
# 使用XTLS官方安装脚本 (https://github.com/XTLS/Xray-install)
# 安装脚本自带GPG签名验证确保二进制完整性
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
echo " Xray安装完成: $(xray version | head -1)"
if command -v xray &>/dev/null; then
echo " Xray安装完成: $(xray version | head -1)"
else
echo "❌ Xray安装失败"
exit 1
fi
fi
# ── 3. 启用BBR TCP加速 ──────────────────────
@ -39,7 +45,9 @@ echo "[3/6] 配置BBR TCP加速..."
if sysctl net.ipv4.tcp_congestion_control 2>/dev/null | grep -q bbr; then
echo " BBR已启用"
else
cat >> /etc/sysctl.conf <<EOF
# 检查是否已添加过BBR配置避免重复追加
if ! grep -q "铸渊专线 BBR加速" /etc/sysctl.conf 2>/dev/null; then
cat >> /etc/sysctl.conf <<EOF
# ── 铸渊专线 BBR加速 ──
net.core.default_qdisc=fq
@ -51,20 +59,27 @@ net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
EOF
sysctl -p
fi
sysctl -p || echo "⚠️ sysctl -p 有警告,继续"
echo " BBR已启用"
fi
# ── 4. 防火墙配置 ────────────────────────────
echo "[4/6] 配置防火墙..."
ufw allow 443/tcp comment "Xray VLESS+Reality"
ufw allow 3802/tcp comment "ZY-Proxy subscription service"
ufw reload
ufw allow 443/tcp comment "Xray VLESS+Reality" || true
ufw allow 3802/tcp comment "ZY-Proxy subscription service" || true
ufw reload || echo "⚠️ 防火墙重载失败,请手动检查"
echo " 防火墙已配置: 443(Xray) + 3802(订阅服务)"
# ── 5. 生成密钥 ──────────────────────────────
echo "[5/6] 生成密钥..."
bash "$(dirname "$0")/generate-keys.sh"
SCRIPT_DIR="$(dirname "$0")"
if bash "$SCRIPT_DIR/generate-keys.sh"; then
echo " ✅ 密钥生成完成"
else
echo " ⚠️ 密钥生成脚本返回非零退出码,检查上方输出"
echo " 密钥文件可能仍已创建,继续安装..."
fi
# ── 6. 创建数据目录 ──────────────────────────
echo "[6/6] 创建数据目录..."