nginx无法直接哈希客户端ip,需先通过realip模块还原真实ip(如set_real_ip_from、real_ip_header),再用map指令提取ip片段或借助lua模块(如resty.md5)生成md5哈希并截取前8位写入日志。

直接记录客户端 IP 的哈希值,Nginx 原生不支持(如没有内置 $remote_addr_hash 变量),但可通过组合方案实现:用 map 指令对 $remote_addr 或 $realip_remote_addr 做哈希映射,再写入日志。关键前提是先确保真实 IP 已正确识别(尤其在有 CDN 或代理时)。
确保真实 IP 可用是前提
若前端有代理,$remote_addr 是代理 IP,不能直接哈希。必须先启用 realip 模块还原真实 IP:
- 在
http或server块中添加:set_real_ip_from 192.168.0.0/16;(填你可信代理段)real_ip_header X-Forwarded-For; - 确认日志格式中使用
$realip_remote_addr,它会在还原成功时生效,失败时自动回退为$remote_addr
用 map 指令生成哈希值
Nginx 不提供 MD5/SHA 等加密哈希,但可用内置的简单哈希函数(如取模、截断、异或)模拟“指纹化”。常用做法是取 IP 最后一段或做数值运算:
- 在
http块顶部添加:map $realip_remote_addr $ip_hash_simple {<br> default "-";<br> ~(?<octet>\d+)$ "$octet";<br>}</octet>
——提取 IPv4 最后一个八位组作为简易哈希标识 - 更稳定的方式(兼容 IPv4/IPv6):
map $realip_remote_addr $ip_hash_mod {<br> default 0;<br> ~^(\d+)\.(\d+)\.(\d+)\.(\d+)$ "$(($1 + $2 * 3 + $3 * 5 + $4 * 7) % 100)";<br>}
(注意:Nginx 的 map 不支持算术表达式,此为示意;实际需用 Lua 或外部模块实现复杂计算)
推荐务实方案:用 Lua 脚本计算哈希
若需真正哈希(如 MD5),需启用 ngx_http_lua_module(Windows 下需自行编译或选用含 Lua 的发行版):
- 在
http块中定义变量:lua_shared_dict ip_hash_cache 10m; - 在
server或location中用set_by_lua_block:set_by_lua_block $ip_md5 {<br> local md5 = require "resty.md5"<br> local hash = md5:new()<br> hash:update(ngx.var.realip_remote_addr)<br> ngx.var.ip_md5 = hash:final():sub(1,8) -- 取前8位缩短 - 更新日志格式:
log_format main '$remote_addr — $realip_remote_addr — $ip_md5 — $request';
验证与调试建议
避免日志混乱,上线前务必测试:
- 临时加一条调试日志:
log_format debug '$remote_addr | $realip_remote_addr | $ip_md5 | $http_x_forwarded_for'; - 用 curl 模拟多层代理请求:
curl -H "X-Forwarded-For: 203.0.113.45, 192.168.10.20" http://your-site/api/test - 检查 access.log 输出是否符合预期:真实 IP 是否还原、哈希值是否稳定、空值是否被合理兜底











