Nginx HTTPS安全配置最佳实践

13 人参与

在一次为金融类 SaaS 项目上线的过程中,团队在审计报告里看到“TLS 配置过于宽松”这条警示,顿时意识到即便 Nginx 能跑出 99.99% 的可用性,安全链路的细节仍是最容易被忽视的破口。

证书文件的安全落地

证书与私钥最好放在 /etc/nginx/ssl 之类的专属目录,并且只让 root 拥有读取权限。即便是自动化脚本,也应在 chmod 600 之后再执行 Nginx 重启,防止因权限过宽导致服务启动失败。

# 创建目录并限制权限
sudo mkdir -p /etc/nginx/ssl
sudo chown root:root /etc/nginx/ssl
sudo chmod 700 /etc/nginx/ssl

# 移动证书并统一命名
sudo mv /tmp/domain.crt /etc/nginx/ssl/domain.crt
sudo mv /tmp/domain.key /etc/nginx/ssl/domain.key
sudo chmod 600 /etc/nginx/ssl/*.key

TLS 协议与密码套件的硬化

禁用 TLS 1.0/1.1 已成业界共识,Nginx 配置里只保留 TLS 1.2 与 TLS 1.3,可兼顾兼容性与前沿安全。密码套件的挑选则应围绕“前向保密”和“性能平衡”。下面的列表是基于 SSL Labs 推荐的高分组合:

  • ECDHE‑RSA‑AES128‑GCM‑SHA256
  • ECDHE‑ECDSA‑AES128‑GCM‑SHA256
  • ECDHE‑RSA‑AES256‑GCM‑SHA384
  • ECDHE‑ECDSA‑AES256‑GCM‑SHA384

在 Nginx 配置段落加入 ssl_prefer_server_ciphers on;,确保服务器端的套件顺序优先于客户端协商,进一步压缩攻击面。

安全响应头与 HSTS

除去加密本身,浏览器层面的强制 HTTPS 也不可或缺。add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; 能让主流浏览器在一年内自动升级所有请求,彻底杜绝降级攻击。对于 API 子域,记得在同一配置块里加入 add_header X-Content-Type-Options nosniff;add_header X-Frame-Options DENY;,进一步限制 MIME 嗅探和点击劫持。

持续监测与自动化更新

配置完毕后,nginx -t 检查语法,随后用 systemctl reload nginx 平滑生效。建议把 openssl s_client -connect $host:443 -servername $host 的输出写进 CI 脚本,每日比对证书有效期与协议列表,若发现即将过期或出现弱协议,即触发自动化的 Certbot/lego 更新流程。这样即使在高并发的交易时段,也能确保加密层始终保持“最新、最安全”。

细节决定安全,别让一行遗漏的 ssl_protocols 成了审计报告里的红字。

参与讨论

13 条评论
  • 反物质园丁

    ssl_protocols只保留1.2和1.3会不会影响老设备访问啊?

  • 疾风行者

    之前配置时忘记改私钥权限,结果nginx起不来折腾半天

  • 双子机智

    HSTS那个max-age设一年会不会太长了点

  • 旧日行囊

    这个密码套件列表实测过吗?兼容性如何

  • 超弦说书人

    建议加上ssl_session_cache的配置说明

  • 鬼灯谣

    金融项目确实该这么严格,我们上次审计就被扣分了

  • HoloMatrix

    直接chmod 600最省事,别搞什么644

  • 夜话鬼话

    有谁试过在docker里部署这个配置?

  • 雪满山中

    响应头配置很实用,已收藏

  • 瓦匠曹

    证书自动更新用acme.sh也挺香的

  • 灵魂出窍

    这些配置在低配服务器上会不会影响性能?

  • 数字游牧

    TLS1.3确实快很多,推荐升级

  • 爱吃糖的蜗牛

    弱弱问下ssl_prefer_server_ciphers这个参数必须加吗?