直接禁用tlsv1.0是pci-dss合规最刚性门槛,nginx中必须将ssl_protocols明确设为tlsv1.2 tlsv1.3,删除tlsv1.0及tlsv1.1;同时需配置合规cipher套件、强制secure/httponly/samesite cookie、启用hsts与x-content-type-options。

直接禁用 TLSv1.0 是 PCI-DSS 合规最刚性、最不可妥协的门槛;其他配置失效,只要它还在,扫描就必然报“不合规”。
ssl_protocols 必须显式剔除 TLSv1.0
PCI-DSS 自 2018 年 6 月 30 日起明确禁止 TLSv1.0,所有扫描工具(如 myssl.com、Qualys SSL Labs)都会直接拒绝该协议版本。Nginx 默认不启用 TLSv1.0,但很多线上配置仍保留着过时模板:
-
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;—— 这里的TLSv1就是 TLSv1.0,必须删掉 - 正确写法只有:
ssl_protocols TLSv1.2 TLSv1.3;(TLSv1.3推荐启用,但非强制;TLSv1.1已被主流扫描器标记为弱协议,建议一并移除) - 修改后务必执行
nginx -t校验语法,再nginx -s reload生效;仅重启服务不保证配置热加载成功
ssl_ciphers 要匹配 PCI-DSS 的加密套件要求
不是“够强就行”,而是必须满足 PCI-DSS 明确列出的前向保密(PFS)和密钥交换算法要求。常见错误是照抄网上“高兼容性”配置,结果引入 RSA 密钥交换或 SHA1 签名套件:
- 必须使用
ECDHE或DHE密钥交换(保证 PFS),禁用SSL_RSA类套件 - 推荐配置(经 PCI-DSS 扫描验证通过):
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384"; - 避免使用
AES128以下强度、SHA256以下哈希、或含RC4/MD5的套件——这些在扫描中会触发“弱加密”告警 - 设置
ssl_prefer_server_ciphers on;,防止客户端协商降级
Cookie 安全属性必须由 Nginx 统一注入,不能依赖后端
PCI-DSS 要求会话 Cookie 具备 Secure、HttpOnly、SameSite=Strict(或 Lax),而很多 Java/Node.js 应用只在服务端设了 Secure,却没处理反向代理场景下的协议感知问题:
- 后端生成的
Set-Cookie头在 HTTP→HTTPS 跳转时可能丢失Secure,必须由 Nginx 强制补全:add_header Set-Cookie "JSESSIONID=$sessionid; Path=/; HttpOnly; Secure; SameSite=Lax" always; -
always参数关键:否则 Nginx 默认只对 2xx 响应加 Header,302 跳转或 4xx 错误响应中的 Cookie 就漏了安全属性 - 若应用需 JS 读取某类 Cookie(如登录态刷新),不能全局禁用
HttpOnly,应拆分 Cookie:敏感会话 ID 设HttpOnly,前端控制类 Cookie 单独命名并豁免
HSTS 和 X-Content-Type-Options 是扫描高频扣分项
这两项虽不直接涉及支付数据加密,但属于 PCI-DSS “保护传输中数据”的延伸要求,多数合规扫描平台(如 Tenable、Nessus)已将其纳入检查清单:
-
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;——max-age至少 1 年,includeSubDomains必须开启,否则子域名 HTTPS 不受保护 -
add_header X-Content-Type-Options "nosniff" always;—— 防止浏览器 MIME 类型嗅探导致 XSS,漏配会被判“内容类型不安全” - 注意:
add_header不继承,每个server块都得单独写;若用了location覆盖,需在对应块内重写,否则失效
真正卡住 PCI-DSS 扫描的,往往不是复杂逻辑,而是某个 ssl_protocols 行里多了一个空格、某个 add_header 缺了 always、或某台边缘 Nginx 漏掉了 HSTS。合规不是一次性配置,而是所有入口节点的配置一致性校验。











