fix: deploy.sh/test.sh 审计修复
Some checks failed
Deploy Backend / deploy (push) Has been cancelled

deploy.sh:
- 修复重复的 header 注释行

lib/common.sh:
- view_logs/tail_logs/status: 从日志文件切换为 journalctl(上次改
  日志输出到 stdout 后,日志文件已不存在)
- init_env 模板: User=root → User=rust-backend(匹配最小权限原则)

lib/test.sh:
- test_notify_url_domain: 添加自定义 Host 头(TEST_DOMAIN),模拟
  真实外部请求场景。之前测试走 127.0.0.1 直连,Host 头为 localhost
  导致 notify_url 校验永远通过但实际配置可能是错误的
This commit is contained in:
2026-07-23 12:25:46 +08:00
parent 0b0757939b
commit 217e7f8a55
3 changed files with 20 additions and 26 deletions

View File

@@ -2,8 +2,6 @@
# =========================================== # ===========================================
# Rust Backend Deployment Script # Rust Backend Deployment Script
# =========================================== # ===========================================
# Rust Backend Deployment Script
# ===========================================
# Usage: ./deploy.sh [development|production] [options] # Usage: ./deploy.sh [development|production] [options]
# #
# Options: # Options:

View File

@@ -187,8 +187,8 @@ Wants=network.target
[Service] [Service]
Type=simple Type=simple
User=root User=rust-backend
Group=root Group=rust-backend
WorkingDirectory=${REMOTE_DIR} WorkingDirectory=${REMOTE_DIR}
ExecStart=${REMOTE_DIR}/rust-backend ExecStart=${REMOTE_DIR}/rust-backend
Restart=always Restart=always
@@ -403,19 +403,15 @@ rollback_on_failure() {
view_logs() { view_logs() {
local lines="${LOG_LINES:-50}" local lines="${LOG_LINES:-50}"
log_step "查看后端日志(最后 ${lines} 行)..." log_step "查看后端日志(最后 ${lines} 行)..."
[ "$DRY_RUN" = true ] && { log_dry "tail -${lines} 日志文件"; return 0; } [ "$DRY_RUN" = true ] && { log_dry "journalctl -u ${SERVICE_NAME} -n ${lines}"; return 0; }
local lf; lf=$(remote "ls -t ${REMOTE_DIR}/logs/rust-backend.*.log 2>/dev/null | head -1" || echo "") remote "journalctl -u ${SERVICE_NAME} -n ${lines} --no-pager 2>/dev/null" || log_warn "无法读取 journalctl 日志"
[ -z "$lf" ] && { log_warn "未找到日志文件"; return 1; }
echo -e "${BLUE}=== ${lf} ===${NC}"; remote "tail -${lines} '${lf}'"
} }
tail_logs() { tail_logs() {
local lines="${LOG_LINES:-100}" local lines="${LOG_LINES:-100}"
log_step "实时跟踪日志..." log_step "实时跟踪日志..."
[ "$DRY_RUN" = true ] && return 0 [ "$DRY_RUN" = true ] && return 0
local lf; lf=$(remote "ls -t ${REMOTE_DIR}/logs/rust-backend.*.log 2>/dev/null | head -1" || echo "") ssh -t "${REMOTE_USER}@${REMOTE_HOST}" "journalctl -u ${SERVICE_NAME} -n ${lines} -f"
[ -z "$lf" ] && { log_warn "未找到日志文件"; return 1; }
ssh -t "${REMOTE_USER}@${REMOTE_HOST}" "tail -f -n ${lines} '${lf}'"
} }
status() { status() {
@@ -423,8 +419,8 @@ status() {
[ "$DRY_RUN" = true ] && { log_dry "systemctl status ${SERVICE_NAME}"; return 0; } [ "$DRY_RUN" = true ] && { log_dry "systemctl status ${SERVICE_NAME}"; return 0; }
echo -e "${BLUE}=== ${SERVICE_NAME} ===${NC}" echo -e "${BLUE}=== ${SERVICE_NAME} ===${NC}"
remote "systemctl status ${SERVICE_NAME} --no-pager" remote "systemctl status ${SERVICE_NAME} --no-pager"
local lf; lf=$(remote "ls -t ${REMOTE_DIR}/logs/rust-backend.*.log 2>/dev/null | head -1" || echo "") echo -e "${BLUE}=== 最近日志 ===${NC}"
[ -n "$lf" ] && { echo -e "${BLUE}=== 最近日志 ===${NC}"; remote "tail -20 '${lf}'"; } remote "journalctl -u ${SERVICE_NAME} -n 20 --no-pager 2>/dev/null" || log_warn "无法读取 journalctl 日志"
} }
# ---------- 确认 ---------- # ---------- 确认 ----------

View File

@@ -475,10 +475,10 @@ test_nginx_proxy_temp() {
test_notify_url_domain() { test_notify_url_domain() {
log_info "校验支付表单 notify_url 域名..." log_info "校验支付表单 notify_url 域名..."
local domain # 用 TEST_DOMAIN 构造 Host 头,模拟外部请求(而非 localhost 直连)
domain=$(echo "$BASE_URL" | sed 's|https://||' | sed 's|http://||' | sed 's|/||g') local test_domain="${TEST_DOMAIN#https://}"
# 获取访客 JWT # 获取访客 JWT(通过本地后端)
local jwt local jwt
jwt=$(remote "curl -sk -X POST '${BASE_URL}/api/guest-login'" 2>/dev/null | python3 -c "import sys,json; print(json.load(sys.stdin).get('token',''))" 2>/dev/null) jwt=$(remote "curl -sk -X POST '${BASE_URL}/api/guest-login'" 2>/dev/null | python3 -c "import sys,json; print(json.load(sys.stdin).get('token',''))" 2>/dev/null)
if [ -z "$jwt" ]; then if [ -z "$jwt" ]; then
@@ -486,26 +486,26 @@ test_notify_url_domain() {
return 1 return 1
fi fi
# 提取支付表单的 notify_url # 用正确的 Host 头请求支付表单(模拟外部用户访问)
# 后端此时通过 Host 头构建 notify_url应等于 TEST_DOMAIN
local notify_url local notify_url
notify_url=$(remote "curl -sk '${BASE_URL}/payment/page?package=monthly&jwt=${jwt}'" 2>/dev/null | grep -oP 'notify_url" value="\K[^"]+' | head -1) notify_url=$(remote "curl -sk '${BASE_URL}/payment/page?package=monthly&jwt=${jwt}' -H 'Host: ${test_domain}'" 2>/dev/null | grep -oP 'notify_url" value="\K[^"]+' | head -1)
if [ -z "$notify_url" ]; then if [ -z "$notify_url" ]; then
log_error "无法提取 notify_url可能为 Mock 支付模式)" log_error "无法提取 notify_url可能为 Mock 支付模式)"
return 0 # Mock 模式下不校验 return 0 # Mock 模式下不校验
fi fi
# 检查 notify_url 的域名是否与 BASE_URL 一致 # 检查 notify_url 是否以 TEST_DOMAIN 开头
local notify_domain local expected_prefix="https://${test_domain}/payment/notify"
notify_domain=$(echo "$notify_url" | sed 's|https://||' | sed 's|http://||' | sed 's|/payment/notify||') if [ "$notify_url" != "$expected_prefix" ]; then
log_error "notify_url 不匹配: 表单=${notify_url}"
if [ "$notify_domain" != "$domain" ]; then log_error " 期望: ${expected_prefix}"
log_error "notify_url 域名不匹配: 表单=${notify_domain}, 期望=${domain}" log_error "请检查 APP_BASE_URL 环境变量配置"
log_error "请检查 APP_BASE_URL 配置"
return 1 return 1
fi fi
log_info " notify_url 域名 ${notify_domain}" log_info " notify_url 正确: ${notify_url}"
return 0 return 0
} }