要让nginx日志准确记录referer,需在log_format中显式添加$http_referer字段并启用该格式,重载配置后结合日志分析与valid_referers等配置协同防护。

要让 Nginx 日志真正反映 Referer 信息,关键不是“记录”,而是“准确记录+合理解读”。默认日志格式不包含 $http_referer,直接查日志会看到空字段或缺失值,后续分析就无从谈起。
确保日志里真有 Referer 字段
很多运维人员查了半天日志,发现 Referer 总是 "-",其实是日志格式没配对。必须显式定义并启用含 $http_referer 的 log_format:
- 在
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 不是固定 URL,它的值取决于用户怎么来的,不同场景表现差异很大:
-
"https://example.com/page.html"—— 正常跳转,来源清晰 -
"-"—— 表示请求头中根本没有 Referer 字段(如直接输入地址、书签访问、HTTPS→HTTP 跳转、部分 App 内 WebView) -
""(空字符串)—— 极少见,通常表示请求头存在但值为空,可能是异常客户端行为 -
"https://google.com/url?..."—— 搜索引擎跳转,但参数可能被截断,尤其移动端 -
"blocked"—— 实际不会出现在日志里,这是valid_referers blocked匹配时的内部标识,日志仍显示原始值
用命令快速筛查可疑 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 - 抓取特定资源路径下的异常 Referer(如盗链高发的 /images/):
awk -F'"' '$7 ~ /^\/images\// && $4 !~ /(yoursite\.com|partner\.com)/ {print $4, $7}' /var/log/nginx/access.log | head -10
结合配置反向验证日志结论
日志只是线索,最终要落到配置上才能起作用。发现异常 Referer 后,不能只加黑名单,而应优化白名单策略:
- 把日志中高频出现的合法合作域名加入
valid_referers,注意正则转义:valid_referers none *.partner-site.com ~\.trusted-domain\.org$; - 如果日志显示大量
"-"来自微信、抖音、企业微信等 App,none必须保留,否则会误拦真实用户 - 若发现某类 UA(如
python-requests、curl/8.10)频繁携带伪造 Referer,可配合map指令做 UA 级限流,绕过 Referer 依赖
Referer 是浏览器发的,不是服务器生成的,所以它本质是“线索”而非“证据”。日志里看到的值能帮你发现问题,但不能代替配置拦截;配置里写的规则再严,也挡不住 curl -e 伪造。真正有效的做法,是用日志看清流量分布,再用配置守住底线,两者缺一不可。











