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

时间:2011-06-25 10:42:04

标签: logging nginx ip anonymize

为了尊重用户的隐私,我试图在nginx日志文件中匿名化他们的IP地址。

执行此操作的一种方法是定义自定义日志格式,如下所示:

log_format noip '127.0.0.1 - [$time_local]  '
    '"$request" $status $body_bytes_sent '
    '"$http_referer" "$http_user_agent" $request_time';

这种方法有两个缺点:我无法区分两个用户,也无法使用地理位置工具。

最好的做法是“缩短”IP地址(87.12.23.55将成为87.12.23.1)。

是否有可能使用nginx配置脚本实现此目的?

感谢。

4 个答案:

答案 0 :(得分:32)

即使已经接受了答案,解决方案似乎也无效。

nginx具有 log_format 指令,该指令具有上下文。这意味着,log_format只能在配置文件的http {}部分内(有效)设置,而不能在服务器部分内设置!

另一方面,我们有 if 指令,该指令具有服务器和位置的上下文。

所以我们不能在服务器部分中使用“if”和“log_format”(在已接受的解决方案中完成)

所以 if 在这里没有帮助,如果是邪恶的http://wiki.nginx.org/IfIsEvil)!我们需要在 http上下文中工作的东西,因为只有log_format才能以有效的方式定义,而这是服务器上下文之外唯一的位置,我们的虚拟主机被定义...

幸运的是,nginx中有一个地图功能! map将一些值重新映射到新值(可在log_format指令中使用的变量中访问)。好消息:这也适用于正则表达式。

因此,让我们将IPv4和IPv6地址映射到匿名地址。这必须分三步完成,因为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;

将此添加到您的nginx.conf配置文件后,请记得重新加载您的nginx。如果您使用的是“匿名”日志格式(这是access_log指令的格式参数),您的日志文件现在应该包含anoymized IP地址。

答案 1 :(得分:15)

接受的答案似乎有点臃肿。从nginx版本1.11开始,它可以这样做:

map $remote_addr $remote_addr_anon {
    ~(?P<ip>\d+\.\d+\.\d+)\.    $ip.0;
    ~(?P<ip>[^:]+:[^:]+):       $ip::;
    default                     0.0.0.0;
}

答案 2 :(得分:1)

我认为,一个好的和切实可行的解决方案是在旋转日志文件之前对IP进行匿名化(你应该每天都这样做)。这个任务有许多脚本可用于Apache,并且由于日志格式至少非常相似,所以它们应该开箱即用或者可以轻松调整。当然,您仍然可以将完整的IP存储24小时或更短时间,但这比让它们存放多年更好。

答案 3 :(得分:1)

这是一个基本上执行此操作的nginx模块(在日志中匿名化IP地址):https://github.com/masonicboom/ipscrub。它生成IP地址的哈希值为$ remote_addr_ipscrub。哈希盐经常循环(可配置),因此您可以在不记录用户IP地址的情况下链接请求。