nginx需自定义log_format以满足安全审计与合规要求,应包含真实客户端ip、毫秒级时间、完整uri、状态码、上游耗时、用户标识、ua/referer及tls信息;推荐json格式输出并按路径动态启用审计日志,辅以real_ip、request_id等增强可追溯性。

在生产环境中,Nginx 默认的 combined 日志格式往往无法满足安全审计、行为分析或合规(如等保、GDPR)要求。通过 log_format 指令自定义日志格式,可精准控制记录字段,增强日志的可追溯性、完整性和机器可读性。
明确审计关键字段:不只是 $remote_addr 和 $request
合规审计通常要求日志至少包含:真实客户端 IP(防代理丢失)、请求时间(带毫秒和时区)、HTTP 方法与完整 URI、响应状态码与字节数、上游服务耗时、用户标识(如 Token 或 UID)、UA 与 Referer(用于流量来源分析),以及 TLS/协议信息(判断是否 HTTPS、TLS 版本)。仅靠默认变量远远不够,需组合使用 Nginx 内置变量并补充必要上下文。
例如,当业务部署在 CDN 或负载均衡后,$remote_addr 只是上一跳地址。应优先使用 $http_x_forwarded_for 并配合 real_ip 模块还原真实 IP;若未启用 real_ip,需在日志中同时记录 $remote_addr 和 $http_x_forwarded_for 供人工比对。
构建高信息密度且结构清晰的日志格式
推荐使用 JSON 格式输出(需确保 Nginx ≥ 1.11.8,且无特殊字符转义问题),便于 ELK、Loki 等日志系统解析;若暂不支持 JSON,可用空格+固定分隔符(如 |)提升可读性与脚本处理效率。避免使用空格作为字段分隔符——URI 中常含空格,会导致字段错位。
一个典型审计友好型格式示例:
log_format audit_json escape=json '{"time":"$time_iso8601","client":"$realip_remote_addr","xff":"$http_x_forwarded_for","host":"$host","uri":"$uri","args":"$args","method":"$request_method","status":"$status","body_bytes":"$body_bytes_sent","upstream_time":"$upstream_response_time","request_time":"$request_time","http_referrer":"$http_referer","http_user_agent":"$http_user_agent","scheme":"$scheme","server_port":"$server_port","tls_version":"$ssl_protocol","tls_cipher":"$ssl_cipher","request_id":"$request_id","uid":"$http_x_user_id"}';
说明:
-
$realip_remote_addr来自ngx_http_realip_module,是经可信代理链校验后的最终客户端 IP -
$request_id需配合map或perl_set生成唯一请求 ID(Nginx 本身不内置该变量) -
$http_x_user_id是应用层透传的用户标识(如登录态中的 UID),需前端或网关注入到请求头 -
escape=json自动转义双引号、换行等非法 JSON 字符,避免解析失败
按场景分离日志流,降低审计噪音
不是所有请求都需要全量审计字段。可通过 map 指令动态选择日志格式,或用 if + access_log off 过滤低价值请求(如健康检查、静态资源)。
例如,仅对 API 路径(/api/、/v1/)启用审计日志,其余走轻量格式:
map $uri $log_type {
~^/api/ audit_json;
~^/v\d+/ audit_json;
default combined;
}
access_log /var/log/nginx/access.log $log_type;
也可为敏感操作(如登录、支付、权限变更)单独记录到独立文件,配合日志轮转策略重点保护。
配套配置不可省略:保证日志完整性与可用性
再好的格式,若缺少基础保障,审计即失效:
- 开启
log_subrequest on—— 记录内部子请求(如 auth_request 模块触发的鉴权请求),否则无法关联认证行为 - 配置
open_log_file_cache—— 减少高频写入导致的 inode 占用与性能抖动 - 使用
rotate工具(如 logrotate)按大小+时间双维度切割,并启用copytruncate或prerotate配合kill -USR1安全重载 - 确保磁盘有足够空间与 I/O 吞吐能力;审计日志建议写入独立挂载点,避免影响主服务
自定义 audit 日志不是一次配置完就高枕无忧的事。需定期验证字段是否真实写入(如构造含特殊字符的 UA 测试转义)、比对 Nginx 时间与系统时间偏差、检查日志采集端能否稳定解析 JSON、确认敏感字段(如 token)已脱敏或未被记录。真正符合审计要求的日志,是格式、采集、存储、分析四者闭环的结果。











