This commit is contained in:
jeremygan2021
2026-03-22 23:40:37 +08:00
parent d359244bfd
commit c26c04cf44

View File

@@ -563,12 +563,15 @@ install_certificate() {
generate_https_config() {
log_step "生成 HTTPS 配置..."
cat > "$HTTPS_CONF_FILE" <<EOF
# 使用 cat <<'EOF' 来防止 bash 解释 $ 变量
cat > "$HTTPS_CONF_FILE" <<'EOF'
# HTTP 到 HTTPS 的强制跳转
server {
listen 80;
listen [::]:80;
server_name ${DOMAIN};
server_name DOMAIN_PLACEHOLDER;
# 正确的 301 跳转配置
return 301 https://$host$request_uri;
}
@@ -576,11 +579,11 @@ server {
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name ${DOMAIN};
server_name DOMAIN_PLACEHOLDER;
# SSL 证书配置
ssl_certificate ${CERT_DIR}/cert.pem;
ssl_certificate_key ${CERT_DIR}/key.pem;
ssl_certificate CERT_DIR_PLACEHOLDER/cert.pem;
ssl_certificate_key CERT_DIR_PLACEHOLDER/key.pem;
# SSL 安全配置
ssl_protocols TLSv1.2 TLSv1.3;
@@ -591,21 +594,28 @@ server {
# add_header Strict-Transport-Security "max-age=31536000" always;
# 日志配置
access_log /var/log/nginx/${DOMAIN}.access.log;
error_log /var/log/nginx/${DOMAIN}.error.log;
access_log /var/log/nginx/DOMAIN_PLACEHOLDER.access.log;
error_log /var/log/nginx/DOMAIN_PLACEHOLDER.error.log;
# 后端服务代理
location / {
proxy_pass http://localhost:${BACKEND_PORT};
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_pass http://localhost:PORT_PLACEHOLDER;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
EOF
# 使用 sed 替换占位符
sed -i "s/DOMAIN_PLACEHOLDER/${DOMAIN}/g" "$HTTPS_CONF_FILE"
sed -i "s|CERT_DIR_PLACEHOLDER|${CERT_DIR}|g" "$HTTPS_CONF_FILE"
sed -i "s/PORT_PLACEHOLDER/${BACKEND_PORT}/g" "$HTTPS_CONF_FILE"
log_success "HTTPS 配置已生成: $HTTPS_CONF_FILE"
log_info "配置内容预览:"
head -n 15 "$HTTPS_CONF_FILE"
}
# 最终验证
@@ -688,15 +698,34 @@ final_verification() {
echo -e "${CYAN}测试 2: HTTP 跳转测试${NC}"
local http_response=$(curl -I -s --connect-timeout 10 "http://${DOMAIN}" 2>&1)
local http_code=$(echo "$http_response" | grep -i "HTTP/" | head -n1 | awk '{print $2}')
local location=$(echo "$http_response" | grep -i "Location:" | head -n1)
local location=$(echo "$http_response" | grep -i "^Location:" | head -n1 | sed 's/Location: *//i' | tr -d '\r')
if [[ "$http_code" == "301" ]] || [[ "$http_code" == "302" ]]; then
log_success "✅ HTTP 跳转正常 (HTTP $http_code)"
if [[ -n "$location" ]]; then
log_info "跳转目标: $location"
# 验证跳转目标是否正确
if [[ "$location" =~ ^https://${DOMAIN} ]] || [[ "$location" =~ ^https://${DOMAIN}/ ]]; then
log_success "✅ 跳转目标正确: $location"
else
log_warn "⚠️ 跳转目标可能不正确: $location"
log_info "期望格式: https://${DOMAIN}..."
fi
else
log_warn "⚠️ 收到 HTTP $http_code 但没有 Location 头"
log_error "这可能导致浏览器无法自动跳转"
fi
else
log_warn "⚠️ HTTP 跳转异常: ${http_code:-无响应}"
echo ""
log_error "完整响应头:"
echo "$http_response" | head -n 10
echo ""
log_error "如果显示 nginx 默认页面,可能原因:"
echo " 1. nginx 使用了旧的配置文件"
echo " 2. 80 端口有多个 server 块冲突"
echo " 3. 需要完全重启 nginx 而不是重载"
fi
# 验证 SSL 证书
@@ -735,6 +764,19 @@ final_verification() {
echo " 3. 在线验证 SSL 配置:"
echo -e " ${GREEN}https://www.ssllabs.com/ssltest/analyze.html?d=${DOMAIN}${NC}"
echo ""
echo -e "${CYAN}🔧 手动诊断命令(如遇问题):${NC}"
echo " # 查看生成的配置文件:"
echo -e " ${GREEN}cat $HTTPS_CONF_FILE${NC}"
echo ""
echo " # 检查 80 端口的 server 配置:"
echo -e " ${GREEN}grep -A 5 'listen 80' $HTTPS_CONF_FILE${NC}"
echo ""
echo " # 测试 nginx 配置:"
echo -e " ${GREEN}nginx -t && systemctl restart nginx${NC}"
echo ""
echo " # 手动测试 301 跳转(查看 Location 头):"
echo -e " ${GREEN}curl -I -v http://${DOMAIN} 2>&1 | grep -i location${NC}"
echo ""
echo -e "${YELLOW}⚠️ 提示:${NC}"
echo " - HTTP 请求会自动 301 跳转到 HTTPS"
echo " - 证书将在 60 天后自动续期"