PCI DSS 4.0 服务器合规配置实战

PCI DSS 4.0 合规配置的落点,是把支付卡数据环境里的每一台服务器都变成可验证的技术控制点:网络分段、传输加密、日志留存、访问认证四项缺一不可。本文给出一套可直接执行的服务器侧加固方案,覆盖 nftables 分区隔离、Nginx 强制 TLS 1.2 以上、日志中卡号掩码、auditd 命令审计与 12 个月留存,并附逐项自查命令。

适用场景

以下场景适合直接套用本文配置:

  • 自建或托管服务器上运行电商下单、支付回调、订单查询等涉及卡号流转的业务;
  • 企业正在做 PCI DSS 4.0 首次评估,或从 3.2.1 迁移到 4.0,需要补齐技术证据;
  • 支付服务商要求商户提供服务器侧配置截图与扫描报告,但运维尚未形成固定基线;
  • 使用 SAQ D 自评问卷的商户,需要自行证明要求 1、2、4、8、10 的落实情况。

不适合的场景:仅做展示型官网、不接触任何卡号或授权数据的站点,属于 SAQ A 范畴,无需按本文全量实施,可按要求 4 与要求 6 做最小化处理。

前置条件

  • 操作系统:CentOS 7+/Rocky Linux 9/Ubuntu 22.04,内核 4.18 以上,已启用 nftables(nft --version 可执行);
  • Web 服务:Nginx 1.20 以上,配置目录 /etc/nginx/conf.d/ 可写;
  • 审计组件:auditd 与 rsyslog 已安装,systemctl status auditd 为 active;
  • 权限:具备 root 或 sudo 权限,改动前已完成快照或配置备份;
  • 证书:已有受信任 CA 签发的服务器证书,私钥权限为 600,属主 root。

原理说明

PCI DSS 4.0 共 12 项要求,其中与服务器配置强相关的有 5 项,实施时按「隔离—收敛—加密—留痕—验证」的顺序推进,避免反复返工:

  • 要求 1(网络分段):CDE 与办公网、测试网之间必须有强制访问控制,分段不是靠 VLAN 划一下就完事,必须在主机层用防火墙规则兜底;
  • 要求 2(安全配置):关闭默认账户、默认口令、非必要服务,所有变更需有基线文档;
  • 要求 4(传输加密):持卡人数据经开放网络传输时必须加密,4.0 明确弃用 TLS 1.0/1.1、SSLv3,弱套件一并禁用;
  • 要求 8(身份认证):所有进入 CDE 的访问必须唯一标识,远程管理强制多因素;
  • 要求 10(日志与监控):留存不少于 12 个月,其中最近 3 个月 可即时查询,日志需防篡改。

关键在于:这五项之间存在依赖。没有网络分段,日志里会混入大量非 CDE 流量,审计范围失控;没有统一时间源,跨主机日志无法对齐,事件回溯会失败。因此下文步骤按依赖顺序排列。

操作步骤

步骤一:用 nftables 建立 CDE 分区隔离

假设 CDE 网段为 10.20.0.0/24,管理跳板机为 10.10.5.8,仅放行 443 对外与跳板机 SSH。先备份现有规则,再写入独立表,避免与既有 iptables 规则冲突。

# 备份
nft list ruleset > /root/nft-backup-$(date +%F).rules

# 新建独立表 pci,仅处理 CDE 入向
cat > /etc/nftables/pci-cde.nft <<'EOF'
table inet pci {
  set cde_hosts { type ipv4_addr; flags interval; elements = { 10.20.0.0/24 } }
  set mgmt_hosts { type ipv4_addr; elements = { 10.10.5.8 } }

  chain input {
    type filter hook input priority 0; policy drop;

    ct state established,related accept
    iif lo accept

    # 仅管理跳板机可 SSH
    ip saddr @mgmt_hosts tcp dport 22 ct state new accept

    # 对外仅放行 443
    tcp dport 443 ct state new accept

    # ICMP 限速,便于排障但防滥用
    ip protocol icmp limit rate 10/second accept

    # 其余全部丢弃并记录,日志前缀供 rsyslog 分流
    log prefix "PCI-DROP: " level warn limit rate 5/minute
  }
}
EOF

nft -f /etc/nftables/pci-cde.nft
systemctl enable nftables && nft list table inet pci

规则中 policy drop 是分段生效的前提,ct state established,related 必须前置,否则已建立的业务连接会被切断。生产环境建议先在维护窗口用 nft -c -f 做语法检查。

步骤二:Nginx 强制 TLS 1.2 以上并收敛密码套件

要求 4 明确禁止 TLS 1.0/1.1。将以下配置写入 /etc/nginx/conf.d/tls-pci.conf,在 server 块中 include:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
ssl_session_tickets off;

# OCSP 装订,减少吊销状态查询延迟
ssl_stapling on;
ssl_stapling_verify on;
resolver 223.5.5.5 119.29.29.29 valid=300s;

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

参数说明:ssl_prefer_server_ciphers off 让客户端优先选择,配合仅保留 ECDHE + AEAD 套件,可在兼容性与强度间取得平衡;ssl_session_tickets off 关闭会话票据,避免票据密钥长期不轮换带来的前向安全性问题。

步骤三:访问日志中掩码卡号

要求 3.3 规定显示卡号时最多保留前 6 位与后 4 位。若业务把卡号放在 URL 或请求体并被 Nginx 记录,必须做掩码,否则日志本身就成了敏感数据存储。

# /etc/nginx/nginx.conf 的 http 块
log_format pci_json escape=json
  '{"time":"$time_iso8601","remote_addr":"$remote_addr",'
  '"method":"$request_method","uri":"$uri",'
  '"status":$status,"bytes":$body_bytes_sent,'
  '"rt":$request_time,"ua":"$http_user_agent"}';

# 注意:不记录 $request_uri 与 $args,避免查询串中的卡号落盘
access_log /var/log/nginx/pci_access.log pci_json;

应用层还需在写入数据库前对卡号做截断,Nginx 只能削减日志侧的暴露面。验证方式:grep -Eo '[0-9]{13,19}' /var/log/nginx/pci_access.log 应无输出。

步骤四:auditd 审计关键文件与提权行为

cat > /etc/audit/rules.d/pci.rules <<'EOF'
# 监控支付业务配置与证书私钥
-w /etc/nginx/conf.d/ -p wa -k pci_nginx_conf
-w /etc/ssl/private/ -p rwa -k pci_tls_key
-w /etc/passwd -p wa -k pci_identity
-w /etc/sudoers -p wa -k pci_privilege

# 记录提权与账户变更
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=4294967295 -k pci_root_exec
-a always,exit -F arch=b64 -S setuid -S setgid -k pci_setuid
EOF

augenrules --load
auditctl -l | grep pci_

auid!=4294967295 用于排除系统启动阶段的进程,避免日志被无意义记录刷满。-k 后的关键字是后续检索的唯一抓手,命名需统一加 pci_ 前缀。

步骤五:配置 12 个月日志留存

# /etc/logrotate.d/pci-nginx
/var/log/nginx/pci_access.log {
    daily
    rotate 372
    dateext
    dateformat -%Y%m%d
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        /usr/bin/kill -USR1 $(cat /run/nginx.pid) 2>/dev/null || true
    endscript
}

rotate 372 对应 12 个月按日切割(含余量),delaycompress 保证当天日志仍可直接读取,满足「最近 3 个月可即时查询」。若磁盘容量有限,可将 90 天前的归档同步到对象存储并设置合规保留策略,本地只留索引。

步骤六:远程管理强制多因素

# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
KbdInteractiveAuthentication yes
MaxAuthTries 3
ClientAliveInterval 300
AllowUsers ops@pci

# 配合 TOTP 二次验证
apt install -y libpam-google-authenticator
google-authenticator -t -d -f -r 3 -R 30 -w 3

AuthenticationMethods publickey,keyboard-interactive 要求私钥与动态口令同时通过,单靠密码或单靠密钥都不满足要求 8.4 对 CDE 访问的多因素规定。

配置验证

逐项执行以下命令,输出即评估时的技术证据:

# 1. TLS 协议与套件
openssl s_client -connect shop.example.com:443 -tls1_1 </dev/null 2>&1 | grep -i "alert\|Protocol"
nmap --script ssl-enum-ciphers -p 443 shop.example.com

# 2. 分段是否生效(从非授权网段发起)
nmap -Pn -p 22,3306,6379 10.20.0.11

# 3. 日志是否含完整卡号
grep -Eo '[0-9]{13,19}' /var/log/nginx/pci_access.log | head

# 4. 审计规则是否加载
auditctl -l | grep -c pci_

# 5. 留存策略
logrotate -d /etc/logrotate.d/pci-nginx 2>&1 | grep rotate

# 6. 多因素是否生效(应提示需要 keyboard-interactive)
ssh -o PreferredAuthentications=password ops@pci@10.20.0.11

判定标准:openssl 对 TLS 1.1 握手应返回失败;nmap 对 22/3306/6379 应全部 filtered;卡号 grep 无输出;审计规则条数应等于规则文件中的 -k 数量;logrotate -d 输出中 rotate 值为 372。

常见问题

FAQ 1:PCI DSS 4.0 与 3.2.1 在服务器配置上差别有多大?

差异集中在三处。一是要求 8.4.2 把多因素从「远程访问」扩展到「所有进入 CDE 的访问」,包括运维堡垒机与非交互式接口;二是要求 6.4.3 与 11.6.1 新增对支付页面脚本的管理与篡改检测,前端需引入 CSP 与完整性校验;三是要求 12.3.1 允许用「定制化方法」替代传统控制,但必须做目标风险分析并留存文档。原有 TLS、日志、分段的技术要求基本延续,迁移成本主要在多因素覆盖范围与前端脚本监控。

FAQ 2:日志要求留存 12 个月,本地磁盘扛不住怎么办?

合规只要求「可查询、防篡改」,并未要求全部留在本地。可行做法是本地保留 90 天热数据,90 天以上压缩归档至开启对象锁(WORM)的对象存储,本地仅保留归档索引与校验值。评估时需演示从归档中检索某日日志的完整过程,并在文档中说明保留策略、访问控制与完整性校验方式。注意归档桶必须开启版本控制与删除保护,否则「防篡改」不成立。

FAQ 3:只有一台云服务器,还需要做网络分段吗?

需要,但形式不同。单机环境可用 nftables 在主机内划分区域,把数据库端口只绑定 127.0.0.1,应用与数据库之间通过回环通信,对外仅暴露 443。若使用云厂商安全组,需在评估材料中同时提供安全组规则与主机防火墙规则,证明两层都存在默认拒绝策略。

总结

PCI DSS 4.0 的服务器侧合规不是一次性配置,而是一条可持续验证的链条:nftables 划定边界,Nginx 收敛协议与套件,日志脱敏与审计规则提供证据,logrotate 与归档保证 12 个月可查,多因素把住入口。五项配置之间存在顺序依赖,建议按本文步骤推进,每完成一步立即执行对应验证命令并截图存档,形成评估时的证据包。后续变更需同步更新基线文档,否则下一次评估会因「配置漂移」被判定不符合。