Анонимизировать IP вход в nginx? - PullRequest
24 голосов
/ 25 июня 2011

Чтобы уважать конфиденциальность моих пользователей, я пытаюсь анонимизировать их IP-адреса в лог-файлах nginx.

Один из способов сделать это - определить собственный формат журнала, например:

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 ]

32 голосов
/ 03 января 2015

Даже если уже принят принятый ответ, решение кажется недействительным.

nginx имеет директиву log_format , которая имеет контекст http . Это означает, что log_format может быть (допустимо) установлен только в секции http {} файла конфигурации, а НЕ в секциях сервера!

С другой стороны, у нас есть директива if , которая имеет контекст сервера и местоположения .

Таким образом, мы НЕ можем использовать «if» и «log_format» в разделе сервера (что делается в рамках принятого решения)

Так что , если здесь не поможет, также , если это зло (http://wiki.nginx.org/IfIsEvil)! Нам нужно что-то, что работает в http context , потому что только там 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;

После добавления этого в файл конфигурации nginx.conf не забудьте перезагрузить nginx. Ваши файлы журналов теперь должны содержать анонимные IP-адреса, если вы используете «анонимный» формат журнала (это параметр формата директивы access_log).

15 голосов
/ 31 июля 2017

Принятый ответ кажется немного раздутым. Начиная с nginx версии 1.11, это можно сделать так:

map $remote_addr $remote_addr_anon {
    ~(?P<ip>\d+\.\d+\.\d+)\.    $ip.0;
    ~(?P<ip>[^:]+:[^:]+):       $ip::;
    default                     0.0.0.0;
}
1 голос
/ 31 марта 2018

Вот модуль nginx, который в основном делает это (анонимизирует IP-адреса в ваших журналах): https://github.com/masonicboom/ipscrub. Он генерирует хэш IP-адреса как $ remote_addr_ipscrub.Время от времени циклы хеш-соли (настраиваемые) позволяют связывать запросы, не регистрируя IP-адреса пользователей.

1 голос
/ 21 сентября 2011

Я думаю, хорошим и практичным решением является анонимизация IP-адреса перед ротацией файлов журналов (что вы должны делать ежедневно). Существует множество сценариев для этой задачи, доступных для Apache, и, поскольку формат журнала, по крайней мере, очень похож, они должны работать "из коробки" или быть легко настраиваемыми. Конечно, вы сохраняете полный IP-адрес в течение 24 часов или меньше, но это лучше, чем хранить его годами.

...