Геопозиционирование IP-адреса

Начнём с того, что определить точное местоположение IP-адреса (то есть — устройства, которому присвоен этот адрес) в принципе невозможно. IP-адреса не имеют никакой географической привязки даже с точностью до страны.

Геопозиционирование IP-адресов осуществляется на основании геобаз, то есть баз данных, в которые занесена информация о расположении. Официальной геобазы не существует, все существующие геобазы поддерживаются различными коммерческими и некоммерчекими организациями, иногда и использованием откровенно шпионских приёмов сбора данных. Наиболее достоверные и солидные геобазы поддерживает компания MaxMind, геобазы этой компании используются в подавляющем большинстве случаев.  Данные о географическом положении адресов MaxMind получает непосредственно от владельцев автономных систем, а если владелец AS такую информацию не предоставил, то в качестве местоположения указывается адрес регистрации самой AS по официальным данным региональных регистратур. Компания предлагает два вида баз — платные GeoIP и бесплатные GeoLite, бесплатные отличаются меньшей точностью и оперативностью обновления, но вполне пригодны для использования.

Для получения геобазы GeoLite необходимо вначале зарегистрироваться на сайте MaxMind. Найти страницу регистрации на сайте maxmind.com не так просто, поэтому оставлю здесь прямую ссылку: https://www.maxmind.com/en/geolite2/signup?lang=en. После регистрации зайдите в личный кабинет и там вы сможете загрузить базы через браузер или получить лицензионный ключ для автоматической загрузки с помощью программы geoipupdate. Обратите внимание, что лицензионный ключ надо скопировать и сохранить сразу после его генерации, после закрытия страницы увидеть ключ повторно уже не получится. Существуют три геобазы: GeoLite2-Country, содержащая информацию только о государственной принадлежности адреса, она имеет меньший объём и требует меньше ресурсов для использования, GeoLite2-City, которая содержит также информацию о регионе и населённом пункте и GeoLite2-ASN, содержащая информацию о номерах автономных систем и наименованиях провайдеров, которую, в принципе, можно получить с помощью сервиса whois, однако использование базы упрощает этот процесс. При использовании базы GeoLite2-City использовать базу GeoLite2-Country не требуется. Обновление баз GeoLite2 происходит по вторникам.

Теперь о том, для чего можно использовать геоданные. Прежде всего — для ограничения доступа из стран, посетители из которых нежелательны для сайта.  Например, для русскоязычного сайта, для которого китайская аудитория не является целевой, есть смысл запретить доступ из Китая, потому, что китайские сети очень активно используются для взлома сайтов. Также с помощью геоданных можно выбирать региональную версию и язык сайта, только надо обязательно оставить посетителю возможность выбрать региональную версию и язык самостоятельно.  А ещё геоданные полезны для сбора статистики посещаемости сайта.

Подключение геобаз. К сожалению, модуль php_geoip работает только с первой версией геобаз, которая не поддерживается с 2018 года, поэтому устанавливать его не нужно. Подключать геобазы будем непосредственно в nginx и получать данные через переменные окружения. Для nginx есть модуль mod_http_geoip для первой версии и mod_http_geoip2 — для второй версии геобазы, нам потребуется установить и подключить в конфигурацию второй.

Собственно подключение базы делается в nginx.conf так, отдельно подключам базу городов и отдельно — базу ASN:

geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb {
auto_reload 12h;
$geoip2_country_name country names en;
$geoip2_country_code default=?? country iso_code;
$geoip2_city default=?? city names en;
$geoip2_city_ru default=?? city names ru;
$geoip2_country_name_ru country names ru;
}

geoip2 /usr/share/GeoIP/GeoLite2-ASN.mmdb {
auto_reload 12h;
$geoip2_asnum autonomous_system_number;
$geoip2_asorg autonomous_system_organization;
}

Рассмотрим значение параметров:

  • geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb — версия и расположения файла геобазы
  • auto_reload — устанавливаем период перечитывания баз с диска. Поскольку базы обновляются раз в неделю, даже 12-часовой интервал представляется слишком коротким.
  • $geoip2_country_name — переменная, в которую будем сохранять название страны. Имя назначаем сами, так же, как и имена всех последующих переменных, главное — потом не забыть какое имя назначили.
  • $geoip2_country_code — помещаем ALPHA2 код страны. Параметр default указывает на то, что окажется в переменной, в случае, если в базе не будет найден код страны для IP-адреса
  • $geoip2_city — туда помещается название города
  • $geoip2_city_ru, $geoip2_country_name_ru — то же самое, но данные на русском языке
  • $geoip2_asnum —  помещаем номер автономной системы
  • $geoip2_asorg — а сюда — название провайдера.

База содержит и другую информацию, но большого практического смысла в ней нет.

Теперь настраиваем запись лога так, чтобы туда в конец строки писались данные из геобазы:

 log_format log '$remote_addr $host - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" - $geoip2_city, $geoip2_country_code, AS$geoip2_asnum $geoip2_asorg ';

Теперь осталось установить переменные окружения, которые будут доступны для процессов, запускаемых через fastcgi:

fastcgi_param GEOIP2_CITY $geoip2_city;
fastcgi_param GEOIP2_CITY_RU $geoip2_city_ru;
fastcgi_param GEOIP2_COUNTRY_CODE $geoip2_country_code;
fastcgi_param GEOIP2_COUNTRY_NAME $geoip2_country_name;
fastcgi_param GEOIP2_COUNTRY_NAME_RU $geoip2_country_name_ru;
fastcgi_param GEOIP2_ASNUM $geoip2_asnum;
fastcgi_param GEOIP2_ASORG $geoip2_asorg;

Всё. Теперь данные GeoIP будут записываться в лог и будут доступны через переменные окружения.