Nginx + OpenSSL 自签名证书配置:优劣总结

Nginx + OpenSSL 自签名证书配置:优劣总结
本文基于当前的实际做法用 OpenSSL 生成 RSA 私钥与 CSR再自签server.crtNginx 仅监听 443证书放在D:\nginx\ssl\下。1 当前方案概览openssl genrsa -des3 -out server.pass.key 2048 # 生成带密码私钥 openssl rsa -in server.pass.key -out server.key # 导出无密码私钥给 Nginx 用 openssl req -new -key server.pass.key -out server.csr -subj ... openssl x509 -req -days 365 -in server.csr -signkey server.pass.key -out server.crt # Nginx listen 443 ssl; ssl_certificate ssl/server.crt; ssl_certificate_key ssl/server.key;本质上是本地/内网 HTTPS证书自己给自己签不依赖公网 CA。2 优势2.1 零成本、零依赖上手快不需要购买商业证书不需要域名备案、DNS 验证不需要对接 Let’s Encrypt 等公网 ACME 服务一条命令链就能跑通 HTTPS适合开发、测试、离线内网环境对你这种调查离线部署、GeoWebCache 瓦片 本地 API的场景很合适服务器可能根本不上公网。2.2 完全自主可控私钥、证书、有效期都在自己手里不依赖第三方 CA 的可用性证书过期后自己重签即可流程固定、可脚本化2.3 传输层加密仍然有效即使用自签名证书HTTPS 依然会对 HTTP 明文传输做 TLS 加密防窃听局域网嗅探防篡改中间人若没信任你的 CA浏览器会告警对「内网也要加密、但不需要公网信任」的需求加密能力是到位的。2.4 仅开 443攻击面更小去掉 80 端口后不会有人误用http://明文访问少一个监听端口防火墙规则更简单符合「只提供加密入口」的安全取向2.5 与现有 Nginx 结构契合证书放在D:\nginx\ssl\配置里写相对路径即可ssl_certificate ssl/server.crt; ssl_certificate_key ssl/server.key;路径清晰和html/、logs/同级运维时不容易搞混conf/ssl/里那套旧证书。3 劣势与风险3.1 浏览器默认不信任 → 用户体验差自签名证书不在系统/浏览器信任链里访问时会看到「您的连接不是私密连接」NET::ERR_CERT_AUTHORITY_INVALID每次新环境都要点「高级 → 继续访问」或手动导入server.crt/ca.crt到「受信任的根证书颁发机构」对开发自己用还行给领导、外单位用户演示时第一印象往往不太好——安全是有了信任感没了。3.2 你用的是「自签站点证书」不是「CA 签发」第 4 步用的是openssl x509-req-signkeyserver.pass.key-outserver.crt这是CSR 和证书用同一把私钥自签和ca.crt那套根 CA没有形成签发关系。结果是ca.crt和server.crt各玩各的导入ca.crt并不能自动信任server.crt要信任只能单独导入server.crt或改成用 CA 签发openssl x509-req-days365-inserver.csr-CAca.crt-CAkeyca.key-CAcreateserial-outserver.crt很多团队以为「有 CA 就万事大吉」结果配置方式不对CA 白建了。3.3 私钥管理有坑文件问题server.pass.key有密码适合存档Nginx 不能直接读server.key无密码Nginx 能启动但泄露即完蛋两者都在磁盘上权限若过宽等于裸奔更稳妥的做法server.pass.key加密备份平时锁起来server.key仅 Nginx 进程可读生产环境考虑 HSM、Windows 证书存储等3.4 证书信息容易和访问方式不一致你当前server.crt的 CN 是127.0.0.1Nginx 的server_name也是127.0.0.1本机访问没问题。但若有人用以下方式访问会额外报错https://10.x.x.x/→ CN 不匹配https://localhost/→ SAN 未包含 localhost用域名访问 → 域名不在证书里现代浏览器对CN SAN主题备用名称要求很严内网 IP、多域名场景最好在 CSR 阶段就把 SAN 配好。3.5 运维成本被「隐藏」了事项自签名方案续期到期前手动重签、替换、reload多节点每台都要分发证书或各自签一份吊销几乎没有成熟的 CRL/OCSP 体系审计很难证明「谁签的、何时签的、为何信任」Let’s Encrypt 90 天自动续期、商业 CA 有审计链——这些自签都要自己扛。3.6 仅 443 也有副作用无法做标准的80 → 443自动跳转你已关掉 80用户习惯性输入http://会直接连不上部分客户端、健康检查默认探测 80需要改探测逻辑如果目标是「强制 HTTPS」常见做法是80 只做 301 跳转443 承载业务你现在的策略是更激进彻底不要 80适合明确只提供 HTTPS 入口的场景。3.7 加密 ≠ 身份认证自签名只能保证「有人加密了通道」不能证明「对面一定是你的官方服务器」。内网若存在恶意节点攻击者可以自己生成另一套自签证书做中间人用户若习惯性点「继续访问」照样中招要真正建立信任需要统一的内部 CA 客户端预装根证书。4 和常见方案对比方案适用场景信任成本复杂度自签站点证书你当前本机开发、单机内网需手动信任免费低内部 CA 签发企业内网、多服务装一次根 CA 即可免费中Let’s Encrypt有公网域名的生产环境浏览器自动信任免费中商业 OV/EV 证书对外正式业务自动信任付费低使用侧对你这种离线土壤调查系统内部 CA 签发通常是自签的「进阶版」上公网再考虑 Let’s Encrypt。5 什么时候适合用这套方案适合本地开发、联调纯内网、离线部署临时演示、POC对「浏览器红字警告」有心理预期且可接受不太适合面向公众的正式网站多用户、多终端、不想逐个导入证书需要合规审计等保、行业规范常要求可信 CA 或规范化的 PKI多域名、多 IP、移动端 App 内嵌 WebView证书校验更严格6 若要改进优先级建议改用ca.crt签发server.crt客户端只信任一次根 CACSR 里补全 SANIP、域名、localhostserver.key收紧文件权限server.pass.key离线保管写续期脚本到期前 30 天自动提醒若需兼容习惯输入http://的用户可单独加 80 端口只做 301 跳转7 一句话总结这套配置的优势是便宜、快、离线可用、能加密劣势是不被默认信任、运维全靠自己、CA 和站点证书若没串起来等于白搭。对内网离线系统它是 pragmatic务实的选择对正式对外服务它是过渡方案不是终点。