当业务系统对外提供服务时,Nginx通常处于流量入口位置,它产生的访问日志与错误日志记录了每一次请求的关键轨迹。在网络安全等级保护、ISO27001以及各类行业监管办法中,Web服务器的日志都被列为安全审计的核心证据。如果仅采用默认配置让Nginx自己写文件,往往无法满足合规条款中关于完整性、可追溯性与保密性的要求。我们需要从日志格式定义、文件保护机制、集中收集与留存策略几个层面重新设计。

合规驱动的日志字段采集规范
绝大多数合规标准首先关心的是“记了什么”。Nginx默认的combined格式只包含远程地址、用户、时间、请求行、状态码、字节数和来源页,这在很多审计场景下是不够的。比如等保二级以上要求能够关联到具体自然人的网络行为,如果前端经过负载均衡或CDN,那么$remote_addr拿到的只是代理IP,必须借助$http_x_forwarded_for或real_ip模块还原客户端真实地址,否则事后追溯会出现断点。
另外,涉及个人信息的查询接口常常把参数拼在URL里,例如/api/user?phone=13800000000。若原样记录到日志,就构成了敏感信息明文存储。合规做法是在日志格式中使用map指令对特定参数做掩码,或者在上游网关完成脱敏。下面给出一个自定义日志格式示例,它补充了真实IP、上游响应时间以及请求体长度,并规避了直接暴露查询串中的手机号。
log_format audit '$real_client_ip - $remote_user [$time_local] '
'"$request_method $uri $server_protocol" '
'$status $body_bytes_sent '
'rt=$request_time urt=$upstream_response_time '
'ua="$http_user_agent"';
map $request_uri $masked_uri {
default $request_uri;
~^(/api/user?phone=)d+(&.*)?$ '$1********$2';
}
# 在server块中引用
access_log /var/log/nginx/audit.log audit;
这种字段级改造虽然增加了少许配置复杂度,但能让日志既满足取证需要,又符合最小必要原则。从实践看,审计人员最反感的正是“要么啥都没记,要么把密码都写下来了”的极端情况,平衡点是只保留身份、时间、对象、结果、耗时五要素。
日志文件的权限控制与防篡改机制
合规条款中反复出现“保证审计记录不被删除、修改或覆盖”,这意味着Nginx日志文件不能由运行Worker的普通账号随意改写。常见误区是把日志目录设成777,或者让nginx用户同时拥有对日志的删除权限。正确思路是:Nginx主进程以root启动后丢弃权限,Worker以低权用户运行,而日志目录仅对专用日志用户可写,且文件属性加上append-only标志。
在Linux环境下,可以通过chattr +a命令给日志文件加仅追加属性,即使攻击者拿到nginx账户也无法清空历史。配合logrotate时,必须让轮换脚本在创建新文件后重新设置属性,否则旧保护会失效。下面的脚本片段演示了轮换后修复属性的过程。
#!/bin/bash # 由logrotate的postrotate调用 mv /var/log/nginx/audit.log /var/log/nginx/audit.log.1 kill -USR1 $(cat /var/run/nginx.pid) chown logwriter:logwriter /var/log/nginx/audit.log chmod 640 /var/log/nginx/audit.log chattr +a /var/log/nginx/audit.log
除了本地属性,还应启用文件完整性校验,例如用auditd监控日志路径的write和unlink系统调用,一旦有异常删除尝试就触发告警。对于等保三级系统,这种主动防御比单纯靠权限更稳妥,因为权限可能被误配或提权绕过,而审计 daemon 在内核层记录了行为。
集中存储与长期留存策略
单台机器上的日志再安全,也扛不住磁盘损坏或主机沦陷。合规一般要求审计数据集中保管且留存不少于六个月,因此必须建立转发通道。相较于让Nginx直接写远程,更推荐用syslog或filebeat把本地日志推到日志平台,这样即使本机被擦除,中心库仍有副本。
在传输环节要启用TLS避免日志被中间人窃取,因为访问日志中可能含内部接口路径。集中后还需做索引分离:把含敏感字段的索引设成受限访问,普通运维搜不到明文。下面是用filebeat输出到加密Kafka的简化配置,体现脱敏与加密两个合规点。
filebeat.inputs:
- type: log
paths:
- /var/log/nginx/audit.log
processors:
- dissect:
tokenizer: '%{ip} - %{user} [%{time}] "%{method} %{uri} %{proto}" %{status} %{size} rt=%{rt}'
- drop_fields:
fields: ["uri"]
output.kafka:
hosts: ["kafka.internal.ipipp.com:9093"]
topic: nginx_audit
ssl.enabled: true
ssl.certificate: /etc/filebeat/client.crt
ssl.key: /etc/filebeat/client.key
留存周期方面,冷数据可转对象存储并加密归档,但检索链路要保留。许多公司栽在“存了但找不着”,监管检查时调不出三年前某次入侵的日志,同样算不合格。建议用生命周期管理策略自动从热集群沉降到廉价存储,同时维护元数据目录,确保合规 auditor 能在两小时内定位到指定时间窗的全部记录。