30

为了尊重我的用户的隐私,我试图在 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

4 回答 4

42

即使已经有一个公认的答案,该解决方案似乎也无效。

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

另一方面,我们有一个if指令,它有一个server 和 location 的上下文

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

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

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

因此,让我们将 IPv4 和 IPv6 地址映射到匿名地址。这必须分 3 步完成,因为 map 不能累积返回值,它只能返回字符串或变量,而不是两者的组合。

因此,首先我们在日志文件中获取我们想要拥有的 IP 部分,第二个映射返回象征匿名部分的部分,第三个映射规则再次将它们映射在一起。

以下是进入 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 指令的格式参数),您的日志文件现在应该包含匿名 IP 地址。

于 2015-01-02T23:14:24.863 回答
18

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

map $remote_addr $remote_addr_anon {
    ~(?P<ip>\d+\.\d+\.\d+)\.    $ip.0;
    ~(?P<ip>[^:]+:[^:]+):       $ip::;
    default                     0.0.0.0;
}
于 2017-07-30T22:40:58.253 回答
2

这是一个 nginx 模块,它基本上可以做到这一点(在您的日志中匿名 IP 地址):<a href="https://github.com/masonicboom/ipscrub" rel="nofollow noreferrer">https://github.com/共济会繁荣/ipscrub。它生成 IP 地址的哈希值作为 $remote_addr_ipscrub。哈希盐每隔一段时间循环一次(可配置),因此您可以在不记录用户 IP 地址的情况下链接请求。

于 2018-03-31T19:20:12.733 回答
0

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

于 2011-09-21T19:32:00.300 回答