From 17e887653af6e628fea686f5e858793953b07450 Mon Sep 17 00:00:00 2001 From: hailin Date: Sun, 25 Jan 2026 06:36:48 -0800 Subject: [PATCH] feat(deploy): auto-configure system nginx HTTPS on ssl obtain - Add configure_system_nginx_ssl() function to generate nginx HTTPS config - HTTP 80 redirects to HTTPS, HTTPS 443 proxies to Docker nginx 8080 - Include TLS 1.2/1.3, secure ciphers, HSTS headers - Update renew_ssl_cert() to reload both system and Docker nginx - Update auto-renew cron to reload system nginx Co-Authored-By: Claude Opus 4.5 --- deploy.sh | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 5 deletions(-) diff --git a/deploy.sh b/deploy.sh index 4ec40a0..0bb05b0 100755 --- a/deploy.sh +++ b/deploy.sh @@ -1150,7 +1150,8 @@ obtain_ssl_cert() { # 创建证书目录 mkdir -p "$PROJECT_ROOT/nginx/ssl" - # 停止 Nginx (释放 80 端口) + # 停止系统 Nginx 和 Docker Nginx (释放 80 端口) + systemctl stop nginx 2>/dev/null || true $DOCKER_COMPOSE stop nginx 2>/dev/null || true # 使用 standalone 模式申请证书 @@ -1176,12 +1177,103 @@ obtain_ssl_cert() { return 1 fi - # 重启 Nginx + # 配置系统 nginx HTTPS + configure_system_nginx_ssl "$domain" + + # 重启 Docker Nginx $DOCKER_COMPOSE up -d nginx log_success "SSL 证书配置完成" } +# 配置系统 nginx 启用 HTTPS +configure_system_nginx_ssl() { + local domain=${1:-$DOMAIN} + local nginx_conf="/etc/nginx/sites-available/iconsulting.conf" + + log_step "配置系统 nginx HTTPS..." + + # 备份原配置 + cp "$nginx_conf" "${nginx_conf}.bak" 2>/dev/null || true + + # 生成新的 nginx 配置 (HTTP + HTTPS) + cat > "$nginx_conf" << EOF +# iConsulting Nginx 配置 (HTTP 重定向 + HTTPS) +# 自动生成于 $(date) + +# HTTP - 重定向到 HTTPS +server { + listen 80; + listen [::]:80; + server_name $domain; + + # Let's Encrypt 验证 + location /.well-known/acme-challenge/ { + root /var/www/html; + } + + # 其他请求重定向到 HTTPS + location / { + return 301 https://\$host\$request_uri; + } +} + +# HTTPS +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name $domain; + + # SSL 证书 + ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem; + + # SSL 安全配置 + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + + # 安全头 + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header X-Content-Type-Options nosniff; + add_header X-Frame-Options SAMEORIGIN; + add_header X-XSS-Protection "1; mode=block"; + + # 代理到 Docker nginx (端口 8080) + location / { + proxy_pass http://127.0.0.1:8080; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + 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_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } +} +EOF + + # 确保 sites-enabled 链接存在 + ln -sf "$nginx_conf" /etc/nginx/sites-enabled/iconsulting.conf + + # 测试配置 + if nginx -t; then + systemctl start nginx + systemctl reload nginx + log_success "系统 nginx HTTPS 配置完成" + else + log_error "nginx 配置测试失败,恢复备份" + cp "${nginx_conf}.bak" "$nginx_conf" 2>/dev/null || true + systemctl start nginx + return 1 + fi +} + # 续期 SSL 证书 renew_ssl_cert() { log_step "续期 SSL 证书..." @@ -1193,8 +1285,9 @@ renew_ssl_cert() { cp "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" "$PROJECT_ROOT/nginx/ssl/" cp "/etc/letsencrypt/live/$DOMAIN/privkey.pem" "$PROJECT_ROOT/nginx/ssl/" - # 重载 Nginx - $DOCKER_COMPOSE exec nginx nginx -s reload + # 重载系统 Nginx 和 Docker Nginx + systemctl reload nginx 2>/dev/null || true + $DOCKER_COMPOSE exec nginx nginx -s reload 2>/dev/null || true log_success "SSL 证书续期完成" fi } @@ -1206,7 +1299,7 @@ setup_ssl_auto_renew() { # 创建续期脚本 cat > /etc/cron.d/certbot-renew << EOF # 每天凌晨 3 点检查证书续期 -0 3 * * * root certbot renew --quiet && cp /etc/letsencrypt/live/$DOMAIN/*.pem $PROJECT_ROOT/nginx/ssl/ && docker-compose -f $PROJECT_ROOT/docker-compose.yml exec -T nginx nginx -s reload +0 3 * * * root certbot renew --quiet && cp /etc/letsencrypt/live/$DOMAIN/*.pem $PROJECT_ROOT/nginx/ssl/ && systemctl reload nginx && docker-compose -f $PROJECT_ROOT/docker-compose.yml exec -T nginx nginx -s reload EOF log_success "自动续期已配置 (每天 3:00 检查)"