From b8a5355827a05d6b024a9edbd0441a5fdb4af54d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 03:44:32 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=93=B8=E6=B8=8A=E4=B8=93=E7=BA=BF?= =?UTF-8?q?=E5=AF=86=E9=92=A5=E7=94=9F=E6=88=90=E8=84=9A=E6=9C=AC=E5=81=A5?= =?UTF-8?q?=E5=A3=AE=E6=80=A7=E4=BF=AE=E5=A4=8D=20-=20=E7=A7=BB=E9=99=A4se?= =?UTF-8?q?t=20-e=E6=94=B9=E4=B8=BA=E6=89=8B=E5=8A=A8=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E5=A4=84=E7=90=86=20-=20xray=20x25519=E6=94=AF=E6=8C=81stdout/?= =?UTF-8?q?stderr=E5=8F=8C=E8=B7=AF=E6=8D=95=E8=8E=B7=E5=92=8C=E5=A4=9A?= =?UTF-8?q?=E7=A7=8D=E8=BE=93=E5=87=BA=E6=A0=BC=E5=BC=8F=20-=20openssl=20X?= =?UTF-8?q?25519=20fallback=E4=BD=BF=E7=94=A8DER=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E6=8F=90=E5=8F=96base64url=E5=AF=86=E9=92=A5?= =?UTF-8?q?=20-=20=E9=9A=8F=E6=9C=BA=E5=8D=A0=E4=BD=8D=E5=AF=86=E9=92=A5?= =?UTF-8?q?=E5=85=9C=E5=BA=95=20-=20install-xray.sh=E9=98=B2=E6=AD=A2BBR?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E8=BF=BD=E5=8A=A0=E5=92=8Cgenerate-keys?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E4=BC=A0=E6=92=AD=20-=20deploy-proxy.sh?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=E4=BC=98?= =?UTF-8?q?=E5=85=88=E5=92=8C=E5=AF=86=E9=92=A5=E6=96=87=E4=BB=B6fallback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/30c8f4ac-a9ab-450c-85ce-ac2c40ffc705 Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com> --- server/proxy/deploy-proxy.sh | 48 +++++++----- server/proxy/setup/generate-keys.sh | 113 +++++++++++++++++++++++++--- server/proxy/setup/install-xray.sh | 35 ++++++--- 3 files changed, 158 insertions(+), 38 deletions(-) diff --git a/server/proxy/deploy-proxy.sh b/server/proxy/deploy-proxy.sh index 80594cf3..458b29d9 100644 --- a/server/proxy/deploy-proxy.sh +++ b/server/proxy/deploy-proxy.sh @@ -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 diff --git a/server/proxy/setup/generate-keys.sh b/server/proxy/setup/generate-keys.sh index 758f2a06..c5ef1676 100644 --- a/server/proxy/setup/generate-keys.sh +++ b/server/proxy/setup/generate-keys.sh @@ -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: " (标准格式) + # 格式2: "PrivateKey: " + # 格式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@ 'xray x25519'" + echo " 然后更新 $KEYS_FILE 和 GitHub Secrets" +fi diff --git a/server/proxy/setup/install-xray.sh b/server/proxy/setup/install-xray.sh index de9dd2fb..1f3a9d0a 100644 --- a/server/proxy/setup/install-xray.sh +++ b/server/proxy/setup/install-xray.sh @@ -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 </dev/null; then + cat >> /etc/sysctl.conf <