diff --git a/modify.md b/modify.md index 5046a941..86fdfff4 100644 --- a/modify.md +++ b/modify.md @@ -1,3 +1,63 @@ +## 2025-01-XX - 修复 SSL 连接错误:优化 Nginx SSL 配置并添加诊断工具 + +### 修复内容 +- **优化 Nginx SSL 配置** (`site/nginx/nginx.conf`): + - 添加 SSL 证书链支持说明和配置选项 + - 添加 SSL 优化配置: + - `ssl_buffer_size 8k` - 优化 SSL 缓冲区大小 + - `ssl_stapling on` - 启用 OCSP Stapling,提升 SSL 握手速度 + - `ssl_stapling_verify on` - 启用 OCSP Stapling 验证 + - `resolver 8.8.8.8 8.8.4.4 valid=300s` - 配置 DNS 解析器用于 OCSP 查询 + - `resolver_timeout 5s` - 设置解析器超时时间 + - 添加证书链文件配置注释,说明如何合并证书链 + +- **创建 SSL 诊断脚本** (`site/check-ssl.sh`): + - 检查证书文件是否存在(`/home/owen/ssl_key/smartsensiguard.cn.pem` 和 `.key`) + - 验证证书文件格式(检查 BEGIN CERTIFICATE 和 BEGIN PRIVATE KEY) + - 检查证书链完整性(统计证书数量) + - 使用 OpenSSL 验证证书信息(有效期、域名、证书和私钥匹配性) + - 检查 Docker 容器状态和 Nginx 日志 + - 提供常见问题解决方案和修复建议 + +### 修改的文件 +- `site/nginx/nginx.conf` - 优化 SSL 配置,添加 OCSP Stapling 和证书链支持 +- `site/check-ssl.sh` - SSL 证书诊断工具(新建) + +### 使用说明 +1. **运行诊断脚本**: + ```bash + cd site + chmod +x check-ssl.sh + ./check-ssl.sh + ``` + +2. **检查证书文件**: + - 确保证书文件存在于 `/home/owen/ssl_key/` 目录 + - 确保证书文件包含完整的证书链(如果证书链是分开的,需要合并) + - 确保证书和私钥文件权限正确(证书 644,私钥 600) + +3. **如果证书链不完整**: + ```bash + # 合并证书和证书链 + cat /home/owen/ssl_key/smartsensiguard.cn.pem /home/owen/ssl_key/chain.pem > /home/owen/ssl_key/smartsensiguard.cn-fullchain.pem + # 然后更新 docker-compose-https.yml 中的证书路径 + ``` + +4. **重启 Nginx 容器**: + ```bash + docker-compose -f docker-compose-https.yml restart nginx + ``` + +### 常见问题 +- **PR_END_OF_FILE_ERROR**:通常由以下原因引起: + 1. 证书文件不存在或路径错误 + 2. 证书文件格式不正确 + 3. 证书链不完整(缺少中间证书) + 4. 证书和私钥不匹配 + 5. SSL 配置问题 + +变更原因:用户遇到 `PR_END_OF_FILE_ERROR` SSL 连接错误,需要优化 SSL 配置并添加诊断工具来排查和解决问题。 + ## 2025-01-XX - CentOS 环境 HTTPS 部署脚本:创建自动化部署脚本 ### 修改内容 diff --git a/site/check-ssl.sh b/site/check-ssl.sh new file mode 100644 index 00000000..f37baed1 --- /dev/null +++ b/site/check-ssl.sh @@ -0,0 +1,155 @@ +#!/bin/bash + +# SSL 证书诊断脚本 +# 用于检查 SSL 证书配置是否正确 + +echo "==========================================" +echo "SSL 证书诊断工具" +echo "==========================================" +echo "" + +# 检查证书文件路径 +CERT_PATH="/home/owen/ssl_key/smartsensiguard.cn.pem" +KEY_PATH="/home/owen/ssl_key/smartsensiguard.cn.key" + +echo "1. 检查证书文件是否存在..." +echo "----------------------------------------" + +if [ -f "$CERT_PATH" ]; then + echo "✓ 证书文件存在: $CERT_PATH" + ls -lh "$CERT_PATH" +else + echo "✗ 证书文件不存在: $CERT_PATH" + echo " 请确保证书文件存在于该路径" +fi + +echo "" + +if [ -f "$KEY_PATH" ]; then + echo "✓ 私钥文件存在: $KEY_PATH" + ls -lh "$KEY_PATH" +else + echo "✗ 私钥文件不存在: $KEY_PATH" + echo " 请确保私钥文件存在于该路径" +fi + +echo "" +echo "2. 检查证书文件内容..." +echo "----------------------------------------" + +if [ -f "$CERT_PATH" ]; then + echo "证书文件内容预览(前 5 行):" + head -5 "$CERT_PATH" + echo "" + + # 检查证书格式 + if grep -q "BEGIN CERTIFICATE" "$CERT_PATH"; then + echo "✓ 证书文件格式正确(包含 BEGIN CERTIFICATE)" + else + echo "✗ 证书文件格式可能不正确(未找到 BEGIN CERTIFICATE)" + fi + + # 检查是否包含证书链 + CERT_COUNT=$(grep -c "BEGIN CERTIFICATE" "$CERT_PATH" || echo "0") + if [ "$CERT_COUNT" -gt 1 ]; then + echo "✓ 证书文件包含证书链($CERT_COUNT 个证书)" + else + echo "⚠ 证书文件可能不包含完整的证书链(仅 $CERT_COUNT 个证书)" + echo " 如果遇到 PR_END_OF_FILE_ERROR,可能需要合并证书链" + fi +else + echo "跳过:证书文件不存在" +fi + +echo "" + +if [ -f "$KEY_PATH" ]; then + echo "私钥文件内容预览(前 5 行):" + head -5 "$KEY_PATH" + echo "" + + # 检查私钥格式 + if grep -q "BEGIN.*PRIVATE KEY" "$KEY_PATH"; then + echo "✓ 私钥文件格式正确(包含 BEGIN PRIVATE KEY)" + else + echo "✗ 私钥文件格式可能不正确(未找到 BEGIN PRIVATE KEY)" + fi +else + echo "跳过:私钥文件不存在" +fi + +echo "" +echo "3. 使用 OpenSSL 验证证书..." +echo "----------------------------------------" + +if command -v openssl >/dev/null 2>&1; then + if [ -f "$CERT_PATH" ]; then + echo "证书信息:" + openssl x509 -in "$CERT_PATH" -text -noout 2>/dev/null | head -20 || echo "✗ 无法解析证书文件" + echo "" + + echo "证书有效期:" + openssl x509 -in "$CERT_PATH" -noout -dates 2>/dev/null || echo "✗ 无法读取证书有效期" + echo "" + + echo "证书域名:" + openssl x509 -in "$CERT_PATH" -noout -subject -issuer 2>/dev/null || echo "✗ 无法读取证书信息" + else + echo "跳过:证书文件不存在" + fi + + if [ -f "$KEY_PATH" ]; then + echo "" + echo "验证私钥:" + openssl rsa -in "$KEY_PATH" -check -noout 2>/dev/null && echo "✓ 私钥格式正确" || echo "✗ 私钥格式可能有问题" + + echo "" + echo "验证证书和私钥是否匹配:" + CERT_MD5=$(openssl x509 -noout -modulus -in "$CERT_PATH" 2>/dev/null | openssl md5) + KEY_MD5=$(openssl rsa -noout -modulus -in "$KEY_PATH" 2>/dev/null | openssl md5) + if [ "$CERT_MD5" = "$KEY_MD5" ] && [ -n "$CERT_MD5" ]; then + echo "✓ 证书和私钥匹配" + else + echo "✗ 证书和私钥不匹配" + fi + else + echo "跳过:私钥文件不存在" + fi +else + echo "⚠ OpenSSL 未安装,跳过证书验证" + echo " 可以运行: yum install openssl -y (CentOS) 或 apt-get install openssl (Ubuntu)" +fi + +echo "" +echo "4. 检查 Docker 容器状态..." +echo "----------------------------------------" + +if command -v docker >/dev/null 2>&1; then + if docker ps -a | grep -q "nginx-https"; then + echo "Nginx 容器状态:" + docker ps -a | grep "nginx-https" + echo "" + echo "Nginx 容器日志(最后 20 行):" + docker logs --tail 20 nginx-https 2>&1 | grep -i "ssl\|cert\|error" || docker logs --tail 20 nginx-https + else + echo "⚠ Nginx 容器未运行" + fi +else + echo "⚠ Docker 未安装或不可用" +fi + +echo "" +echo "==========================================" +echo "诊断完成" +echo "==========================================" +echo "" +echo "常见问题解决方案:" +echo "1. 如果证书文件不存在,请将证书文件放置到: $CERT_PATH" +echo "2. 如果证书链不完整,需要合并证书和证书链:" +echo " cat cert.pem chain.pem > fullchain.pem" +echo "3. 如果证书和私钥不匹配,请检查证书文件是否正确" +echo "4. 如果容器无法启动,检查证书文件权限:" +echo " chmod 644 $CERT_PATH" +echo " chmod 600 $KEY_PATH" +echo "" + diff --git a/site/nginx/nginx.conf b/site/nginx/nginx.conf index 9bba1d0e..d4b49a87 100644 --- a/site/nginx/nginx.conf +++ b/site/nginx/nginx.conf @@ -54,8 +54,13 @@ http { server_name smartsensiguard.cn www.smartsensiguard.cn; # SSL 证书配置 + # 注意:如果证书文件包含完整证书链,直接使用 .pem 文件 + # 如果证书和证书链是分开的,需要合并:cat cert.pem chain.pem > fullchain.pem ssl_certificate /etc/nginx/ssl/smartsensiguard.cn.pem; ssl_certificate_key /etc/nginx/ssl/smartsensiguard.cn.key; + + # 如果证书链文件单独存在,取消下面的注释并指定路径 + # ssl_trusted_certificate /etc/nginx/ssl/chain.pem; # SSL 安全配置 ssl_protocols TLSv1.2 TLSv1.3; @@ -64,6 +69,13 @@ http { ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off; + + # SSL 优化配置 + ssl_buffer_size 8k; + ssl_stapling on; + ssl_stapling_verify on; + resolver 8.8.8.8 8.8.4.4 valid=300s; + resolver_timeout 5s; # 安全头 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;