要让 nginx 的 access_log 真实可靠记录 referer,需显式定义含 $http_referer 的 log_format(如 main),并在 access_log 中引用;理解其值为客户端发送、非总完整 url;用 awk 等命令高效分析;可结合 map 指令按 referer 动态分流日志。

要让 Nginx 的 access_log 真实、可靠地记录接口调用来源的 Referer,关键不是加一个字段就完事,而是确保它被正确采集、准确呈现、并能用于后续分析或控制。
确保日志格式包含 $http_referer 字段
默认的 log_format combined 或某些精简版配置里并不包含 $http_referer,直接查日志会看到大量 "-"。必须显式定义并启用含该变量的日志格式:
- 在
http块中添加或修改:log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"'; - 确认
access_log指令明确使用了这个格式,例如:access_log /var/log/nginx/access.log main; - 执行
nginx -s reload生效(避免restart中断服务)
理解 Referer 字段的真实含义和常见值
$http_referer 是客户端主动发送的请求头,Nginx 原样记录,但它的内容高度依赖访问场景,并非总是一个完整 URL:
对设计或页面进行 WCAG 2.1 AA 无障碍审计。触发关键词:“audit accessibility”、 “check a11y”、 “is this accessible?” 或在审查设计时使用。
-
正常跳转:如
"https://example.com/page.html" -
无 Referer:显示为
"-"—— 这很常见,包括直接输入地址、书签访问、HTTPS → HTTP 跳转、部分 App 内 WebView、CSP strict-origin-when-cross-origin 等 -
空字符串:
""(极少,多为异常或伪造请求) -
搜索引擎跳转:如
"https://www.google.com/url?...",参数常被截断,尤其移动端 -
注意:
"blocked"不会出现在日志中,它是valid_referers内部匹配标识,日志仍保留原始值
用命令快速定位 Referer 相关问题
别手动翻日志,用 Linux 工具高效筛查:
- 统计 Top 20 来源域名(去掉协议和路径):
awk -F'"' '{print $4}' /var/log/nginx/access.log | grep -v '^-$' | awk -F/ '{print $3}' | sort | uniq -c | sort -nr | head -20 - 查空 Referer 请求里高频 User-Agent(识别爬虫或自动化工具):
awk -F'"' '$4 == "-" {print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head - 抓盗链高发路径(如
/api/v1/data)下的异常来源:awk -F'"' '$7 ~ /^\/api\/v1\/data/ && $4 !~ /(yourdomain\.com|trusted\.site)/ {print $4, $7}' /var/log/nginx/access.log | head -10
按 Referer 动态分流日志(进阶用法)
若需对不同来源做独立归档(如合作方、第三方平台、爬虫),可结合 map 指令实现:
- 在
http块中定义映射:map $http_referer $referer_log {<br> ~*partner\.com$ "partner";<br> ~*api\.thirdparty\.org$ "thirdparty";<br> default "other";<br>} - 在
server或location中按变量写入不同文件:access_log /var/log/nginx/referer_partner.log main if=$referer_log; # 需配合 log_format 和目录权限 - 预建日志目录、赋权(如
chown nginx:nginx /var/log/nginx/),再配logrotate统一轮转










