Nginx HTTPS 配置指南(内网 CA 方案)

Nginx HTTPS 配置指南(内网 CA 方案)
1 整体架构ca.key根私钥仅服务器保管 │ ▼ 自签 ca.crt根证书─────────────────────▶ 导入 Windows「受信任的根 CA」每台客户端一次 │ ▼ 签发 server.crt站点证书────────────────▶ Nginx ssl_certificate server.key站点私钥无密码────────▶ Nginx ssl_certificate_key角色文件用途根 CA 私钥ca.key签发站点证书绝不外泄根 CA 证书ca.crt分发给客户端导入信任站点私钥server.keyNginx 启动用无密码站点私钥备份server.pass.key带密码加密备份可选证书请求server.csr中间文件签发后保留备查站点证书server.crtNginx 使用完整证书链server-fullchain.crt可选server.crt ca.crt 合并SAN 扩展配置server-ext.cnf定义 IP/域名备用名序列号文件ca.srlCA 签发时自动生成勿删目录说明本文所有证书放在D:\nginx\ssl\Nginx 配置中的ssl/server.crt相对nginx 根目录D:\nginx不是conf\ssl\。2 环境准备2.1 安装 OpenSSLWindows 推荐使用 Git for Windows 自带的 OpenSSL或单独安装 OpenSSL for Windows。验证是否可用openssl version2.2 解决 openssl.cnf 找不到若报错Cant open openssl.cnf在当前 PowerShell 窗口执行$env:OPENSSL_CONF C:\Program Files\Git\usr\ssl\openssl.cnf或每次命令加-config参数见下文示例。2.3 进入工作目录cd D:\nginx\ssl3 从零开始完整操作流程若是首次配置或重建 CA从第 1 步做到第 7 步。若 CA 已存在只需续签站点证书跳到 八、站点证书续签。第 1 步生成根 CA 私钥# 4096 位 RSA 私钥无密码便于脚本签发 openssl genrsa -out ca.key 4096如需加密备份可额外生成带密码版本openssl genrsa -des3 -out ca.pass.key 4096 openssl rsa -in ca.pass.key -out ca.key第 2 步生成根 CA 自签证书有效期 10 年3650 天CN 建议使用有意义的 CA 名称openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj /CCN/STHubei/LWuhan/OCCNU/OUChenghuan/CNCCNU-Internal-CA/emailAddresszhz5214qq.com验证 CA 证书openssl x509 -in ca.crt -text -noout第 3 步生成站点私钥# 3.1 生成带密码私钥可选用于安全备份 openssl genrsa -des3 -out server.pass.key 2048 # 3.2 导出无密码私钥Nginx 必须使用此文件 openssl rsa -in server.pass.key -out server.key说明Nginx 无法交互输入私钥密码因此ssl_certificate_key必须指向无密码的server.key。若不需要加密备份可简化为openssl genrsa -out server.key 2048第 4 步准备 SAN 扩展配置创建D:\nginx\ssl\server-ext.cnf已存在可跳过按需修改 IP/域名[ req ] default_bits 2048 prompt no default_md sha256 distinguished_name dn req_extensions v3_req [ dn ] C CN ST Hubei L Wuhan O CCNU OU Chenghuan CN 127.0.0.1 [ v3_req ] basicConstraints CA:FALSE keyUsage digitalSignature, keyEncipherment extendedKeyUsage serverAuth subjectAltName alt_names [ alt_names ] IP.1 127.0.0.1 IP.2 10.131.111.120 DNS.1 localhost # DNS.2 your.domain.com重要访问地址必须出现在[ alt_names ]中否则浏览器报ERR_CERT_COMMON_NAME_INVALID。第 5 步生成 CSR证书签名请求openssl req -new -key server.key -out server.csr -config server-ext.cnf查看 CSR 内容openssl req -in server.csr -text -noout第 6 步用 CA 签发站点证书openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile server-ext.cnf -extensions v3_req验证签发关系必须输出 OKopenssl verify -CAfile ca.crt server.crt期望输出server.crt: OK确认 Issuer 是 CA 而非站点自身openssl x509 -in server.crt -noout -subject -issuer期望类似subjectCN127.0.0.1, ... issuerCNCCNU-Internal-CA, ...第 7 步生成完整证书链可选Get-Content server.crt, ca.crt | Set-Content server-fullchain.crtNginx 可使用ssl/server-fullchain.crt替代ssl/server.crt对部分客户端更友好。4 Nginx 配置编辑D:\nginx\conf\nginx.conf确保 server 块如下仅保留 443关闭 80server { listen 443 ssl; server_name 127.0.0.1; server_tokens off; # 访问控制按需调整仅本机访问示例 allow 127.0.0.1; deny all; # 证书路径相对 nginx 根目录 D:\nginx ssl_certificate ssl/server.crt; ssl_certificate_key ssl/server.key; # 或使用完整链 # ssl_certificate ssl/server-fullchain.crt; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # ... 其余 location 配置 }检查并重载cd D:\nginx nginx -t nginx -s reload若 Nginx 未运行nginx5 Windows 导入 CA 信任只需导入ca.crt不要导入server.crt到根 CA 存储。方法一PowerShell推荐当前用户无需管理员Import-Certificate -FilePath D:\nginx\ssl\ca.crt -CertStoreLocation Cert:\CurrentUser\Root本地计算机需管理员 PowerShell影响所有用户Import-Certificate -FilePath D:\nginx\ssl\ca.crt -CertStoreLocation Cert:\LocalMachine\Root方法二图形界面Win R→ 输入certmgr.msc受信任的根证书颁发机构→证书→ 右键导入选择D:\nginx\ssl\ca.crt完成向导方法三双击安装双击ca.crt→安装证书→本地计算机→受信任的根证书颁发机构浏览器说明浏览器说明Chrome / Edge使用 Windows 证书库导入系统根 CA 即可Firefox独立证书库需单独导入设置 → 隐私与安全 → 证书 → 证书颁发机构 → 导入重建 CA 后注意若重新生成了 CA必须删除旧的根 CA 条目certmgr.msc 中找旧 CN重新导入新的ca.crt重启浏览器6 验证6.1 命令行验证# 证书链验证 openssl verify -CAfile D:\nginx\ssl\ca.crt D:\nginx\ssl\server.crt # 查看证书有效期 openssl x509 -in D:\nginx\ssl\server.crt -noout -dates6.2 浏览器验证访问须在 server-ext.cnf 的 alt_names 中https://127.0.0.1/ https://10.131.111.120/检查项地址栏显示锁图标证书颁发者CCNU-Internal-CA无「您的连接不是私密连接」警告6.3 Nginx 日志Get-Content D:\nginx\logs\soil-error.log -Tail 207 一键脚本完整重建将以下内容保存为D:\nginx\ssl\setup-https.ps1在 PowerShell 中执行# setup-https.ps1 — 重建 CA 并签发站点证书 $ErrorActionPreference Stop $ssl D:\nginx\ssl $env:OPENSSL_CONF C:\Program Files\Git\usr\ssl\openssl.cnf Set-Location $ssl # 备份旧文件 $backup Join-Path $ssl backup\$(Get-Date -Format yyyyMMdd-HHmmss) New-Item -ItemType Directory -Path $backup -Force | Out-Null (ca.crt,ca.key,server.crt,server.csr) | ForEach-Object { if (Test-Path $_) { Copy-Item $_ $backup -Force } } # 1. CA openssl genrsa -out ca.key 4096 openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj /CCN/STHubei/LWuhan/OCCNU/OUChenghuan/CNCCNU-Internal-CA/emailAddresszhz5214qq.com # 2. 站点私钥若不存在 if (-not (Test-Path server.key)) { openssl genrsa -out server.key 2048 } # 3. CSR 签发依赖 server-ext.cnf openssl req -new -key server.key -out server.csr -config server-ext.cnf openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile server-ext.cnf -extensions v3_req # 4. 完整链 Get-Content server.crt, ca.crt | Set-Content server-fullchain.crt # 5. 验证 openssl verify -CAfile ca.crt server.crt Write-Host n完成请执行 Write-Host 1. Import-Certificate -FilePath $ssl\ca.crt -CertStoreLocation Cert:\CurrentUser\Root Write-Host 2. cd D:\nginx; nginx -t; nginx -s reload执行powershell -ExecutionPolicy Bypass -File D:\nginx\ssl\setup-https.ps18 站点证书续签CA 不变仅续签server.crt每年执行一次到期前 30 天cd D:\nginx\ssl $env:OPENSSL_CONF C:\Program Files\Git\usr\ssl\openssl.cnf openssl req -new -key server.key -out server.csr -config server-ext.cnf openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile server-ext.cnf -extensions v3_req openssl verify -CAfile ca.crt server.crt cd D:\nginx nginx -s reload续签站点证书不需要客户端重新导入 CA除非 CA 本身也重建了。9 新增访问地址改 SAN编辑server-ext.cnf在[ alt_names ]增加 IP 或 DNS重新执行 第 5 步 和 第 6 步nginx -s reload示例增加域名[ alt_names ] IP.1 127.0.0.1 IP.2 10.131.111.120 DNS.1 localhost DNS.2 soil.ccnu.local10 文件权限与安全文件安全级别说明ca.key 最高仅管理员可读禁止复制到客户端server.pass.key 高加密备份离线保管server.key 高Nginx 进程可读即可ca.crt 可公开分发给所有需访问的 Windows 客户端server.crt 可公开Nginx 自动发送给浏览器禁止将ca.key、server.key放入html/或任何 Web 可访问目录。11 常见问题Q1浏览器仍提示「不安全」是否导入了最新的ca.crt重建 CA 后旧 CA 无效openssl verify -CAfile ca.crt server.crt是否 OK访问地址是否在server-ext.cnf的alt_names中重启浏览器或清除 HSTSchrome://net-internals/#hstsQ2Nginx 启动失败是否误用server.pass.key带密码→ 改用server.key运行nginx -t查看具体错误确认ssl/server.crt路径相对D:\nginx存在Q3openssl.cnf 找不到$env:OPENSSL_CONF C:\Program Files\Git\usr\ssl\openssl.cnfQ4ca.key 丢失无法继续签发只能重建 CA第三节所有客户端重新导入新ca.crt。Q5需要局域网其他机器访问修改server-ext.cnf加入该机器访问用的 IP重新签发server.crt在该机器导入ca.crt修改nginx.conf的allow/deny规则或删除 IP 限制12 命令速查表# 环境 cd D:\nginx\ssl $env:OPENSSL_CONF C:\Program Files\Git\usr\ssl\openssl.cnf # 查看证书 openssl x509 -in ca.crt -text -noout openssl x509 -in server.crt -text -noout openssl verify -CAfile ca.crt server.crt # Nginx cd D:\nginx nginx -t nginx -s reload # 导入信任 Import-Certificate -FilePath D:\nginx\ssl\ca.crt -CertStoreLocation Cert:\CurrentUser\Root附录与 conf/ssl 目录的区别目录用途D:\nginx\ssl\当前方案CA 站点证书Nginx 443 使用D:\nginx\conf\ssl\历史遗留leador.crt 等与本文方案无关配置 Nginx 时使用ssl/server.crt不是conf/ssl/下的文件。