应通过 location 匹配目标路径、map 标记并配合独立 log_format 记录 $args,而非直接依赖 $args;$args 仅含原始未解码 query 字符串,需结合 $uri 解耦路径与参数,再经后处理解码还原语义。
在独立日志列中完整剥离并审计特定路径背后的 Query 参数,关键不是直接依赖 $args 变量本身,而是通过 Nginx 配置将 $args 与路径($request_uri 或 $uri)解耦后结构化记录,并配合日志格式与条件过滤实现精准审计。
$args 是 Nginx 内置变量,仅包含请求 URL 中问号 ? 后的原始查询字符串(如 a=1&b=2&c=test%20data),不含路径、协议或 fragment。它不解析参数,也不自动解码,因此不能直接用于“剥离”——需配合 $uri 和自定义 log_format 提取目标路径下的全部 query。
$uri 给出标准化的路径(如 /api/v1/user),不含 query 和重写前的原始路径$request_uri 包含完整原始 URI(含 query),但可能含未解码字符和重复参数/report/export 路径的所有 query,应先用 location 匹配该路径,再在该块内记录 $args
在 http 或 server 块中定义专用 log_format,为 query 字段预留独立列(如第 8 列),避免与路径混杂:
log_format audit_log '$remote_addr - $remote_user [$time_local] ' '"$request_method $uri $http_version" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" "$args"';access_log /var/log/nginx/export-audit.log audit_log if=$export_path;
再配合 map 指令标记目标路径:
map $uri $export_path { /report/export 1; /report/export/csv 1; /report/export/pdf 1; default 0;}
这样只有匹配路径的请求才会写入 export-audit.log,且 $args 独立成列,便于后续用 awk/grep/ELK 提取分析。
$args 默认是未解码的 raw string,审计需还原可读性:
log_format 中的 $arg_xxx 变量提取单个已解码参数(如 $arg_token、$arg_since),适合已知键名的场景urllib.parse.parse_qs(args_str, keep_blank_values=True) 得到字典结构?id=1&id=2)会被 $args 原样保留,但 $arg_id 只返回第一个值;需靠原始 $args 列 + 解析逻辑捕获全量直接在 access_log 中写 $args 易导致日志膨胀或敏感信息泄露:
$args,尤其含 token、auth、pwd 等字段时,应先用 map 或 if 过滤路径再记录$args 不包含空格解码后的值(%20 仍是 %20),如需纯文本,必须后处理解码$query_string,与 $args 等价,无需额外声明;旧版本请坚持用 $args
$uri 已更新,但 $args 仍为原始值——确保审计逻辑基于 rewrite 后的路径判断,而非原始 $request_uri