GeoIP средствами Nginx

nginx logo

Часто при разработке сайтов появляется необходимость определения местоположения пользователя. Например, таким образом можно выдавать различные версии сайта для аудитории из разных стран. Также можно использовать данную возможность для балансировки нагрузки и назначать пользователю тот сервер, который находится ближе всего. Для реализации данной функции можно воспользоваться средствами Nginx, прикрутив к нему одну из доступных в сети баз данных по GeoIP.

Конфигурация Nginx

В состав Nginx входит модуль Geo, который позволяет выставлять переменные в зависимости от попадания ip в определенный диапазон. Сконфигурируем данный модуль на определение города и страны пользователя добавив следующий код в секцию http:

geo $country {
    ranges; 
    default ETC; 
    include geo-country.conf;
}
geo $city {
    ranges; 
    default ETC; 
    include geo-city.conf;
}

ETC - значение, которое будет установлено по-умолчанию, если ip на попадет не в один диапазон адресов. Теперь у нас в распоряжении 2 переменные, которые мы можем, например, передать GET-параметром на бек-енд:

location / {
    proxy_pass http://127.0.0.1:8080/?city=$city&country=$country;
}

База Данных GeoIP

В конфигурации выше подключаются файлы geo-country.conf и geo-city.conf. Данные файлы содержат наборы диапазонов адресов и некоторые значения им соответствующие. Такого рода данные можно получить в одной из Баз Данных GeoIP. В данном примере я буду использовать ipgeobase. По ссылке вы можете скачать актуальную базу данных GeoIP. Далее остается только правильно обработать данные и получить конфигурационные файлы Nginx корректного формата. Для этих целей я написал два небольших скрипта: парсинг БД городов и парсинг БД стран. На вход данным скриптам подается БД из ipgeobase, а на выходе получаем готовые файлы geo-country.conf и geo-city.conf. Стоит учесть что из БД получаются только диапазоны для Москвы и Санкт-Петербурга. Чтобы получить конфигурационный файл для других городов необходимо модифицировать скрипт.