匿名化nginx中的IP日志记录?

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地址.

  • 谢谢你!我已将已接受的答案更改为您的答案。 (2认同)

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)

  • 我得到`nginx:[emerg] unknown"ip.0"variable` (3认同)