end*_*eit 27 ip logging nginx anonymize
为了尊重我的用户的隐私,我试图在nginx日志文件中匿名他们的IP地址.
一种方法是定义自定义日志格式,如下所示:
log_format noip '127.0.0.1 - [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" $request_time';
Run Code Online (Sandbox Code Playgroud)
这种方法有两个缺点:我无法区分两个用户,也无法使用地理位置工具.
最好的办法是"缩短"IP地址(87.12.23.55会变成87.12.23.1).
是否有可能使用nginx配置脚本来实现这一目标?
谢谢.
Mik*_*etz 35
即使已经有一个已接受的答案,解决方案似乎也没有效果.
nginx有log_format指令,其上下文为http.这意味着,log_format只能在配置文件的http {}部分内(有效)设置,而不能在服务器部分内设置!
另一方面,我们有一个if指令,它有一个服务器和位置的上下文.
所以我们不能在服务器部分中使用"if"和"log_format"(在已接受的解决方案中完成)
所以if在这里没有用,如果是邪恶的(http://wiki.nginx.org/IfIsEvil)!我们需要在http上下文中工作的东西,因为只有log_format才能以有效的方式定义,这是服务器上下文之外的唯一位置,我们的虚拟主机定义在...
幸运的是,nginx中有一个地图功能!map将一些值重新映射到新值(可在log_format指令中使用的变量中访问).好消息:这也适用于正则表达式.
因此,让我们将IPv4和IPv6地址映射到匿名地址.这必须分3步完成,因为map不能累积返回值,它只能返回字符串或变量,而不能同时返回两者的组合.
因此,首先我们在日志文件中获取我们想要的IP部分,第二个映射返回表示匿名部分的部分,第3个映射规则再次将它们映射到一起.
以下是进入http {}上下文的规则:
map $remote_addr $ip_anonym1 {
default 0.0.0;
"~(?P<ip>(\d+)\.(\d+)\.(\d+))\.\d+" $ip;
"~(?P<ip>[^:]+:[^:]+):" $ip;
}
map $remote_addr $ip_anonym2 {
default .0;
"~(?P<ip>(\d+)\.(\d+)\.(\d+))\.\d+" .0;
"~(?P<ip>[^:]+:[^:]+):" ::;
}
map $ip_anonym1$ip_anonym2 $ip_anonymized {
default 0.0.0.0;
"~(?P<ip>.*)" $ip;
}
log_format anonymized '$ip_anonymized - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log anonymized;
Run Code Online (Sandbox Code Playgroud)
将此添加到您的nginx.conf配置文件后,请记住重新加载您的nginx.如果您使用"匿名"日志格式(这是access_log指令的格式参数),您的日志文件现在应该包含anoymized IP地址.
Mic*_*kyi 17
接受的答案似乎有点臃肿.从nginx版本1.11开始,就可以这样做:
map $remote_addr $remote_addr_anon {
~(?P<ip>\d+\.\d+\.\d+)\. $ip.0;
~(?P<ip>[^:]+:[^:]+): $ip::;
default 0.0.0.0;
}
Run Code Online (Sandbox Code Playgroud)