Поиск по сайту:

Как использовать GeoIP с Nginx в Ubuntu 16.04


Это руководство существует для этих версий ОС

  • Ubuntu 16.04 (Xenial Xerus)
  • Ubuntu 11.04 (Natty Narwhal)

На этой странице

  1. 1 Предварительное примечание
  2. 2 Узнайте, поддерживает ли Nginx GeoIP
  3. 3 Загрузите базы данных GeoIP
  4. 4. Настройка Nginx
  5. 5 Краткий тест
  6. 6 ссылок

В этом руководстве объясняется, как использовать модуль GeoIP с nginx в Ubuntu 16.04, чтобы узнать, откуда приходят ваши посетители. Модуль GeoIP устанавливает несколько переменных, таких как $geoip_country_name, $geoip_country_code, $geoip_city и т. д., которые вы можете использовать в своих PHP-скриптах или непосредственно в конфигурации nginx, например, для предоставления контента на разных языках в зависимости от страны пользователя.

1 Предварительное примечание

Я использую веб-сайт www.example.com здесь с корнем документа /var/www/www.example.com/web/ и файлом конфигурации виртуального хоста Nginx /etc/nginx/sites-enabled/www.example.com.vhost. Я буду использовать это руководство для базовой настройки Ubuntu-Nginx.

Это руководство также совместимо с настройками ISPConfig nginx.

Примечание для пользователей Ubuntu:

Поскольку мы должны выполнять все шаги из этого руководства с привилегиями суперпользователя, мы можем либо предварить все команды в этом руководстве строкой sudo, либо стать пользователем root прямо сейчас, набрав

sudo -s

2 Узнайте, поддерживает ли Nginx GeoIP

Прежде чем мы начнем, мы должны выяснить, встроен ли модуль GeoIP в наш сервер nginx:

nginx -V
:~# nginx -V
nginx version: nginx/1.10.0 (Ubuntu)
built with OpenSSL 1.0.2g-fips 1 Mar 2016
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads

3 Загрузите базы данных GeoIP

В Debian и Ubuntu есть пакет geoip-database, который можно установить через apt, но он немного устарел и содержит только GeoIP.dat (база данных страны), а не GeoLiteCity.dat (база данных города). Поэтому мы не устанавливаем этот пакет, а загружаем свежие копии с веб-сайта GeoIP в каталог /etc/nginx/geoip:

mkdir /etc/nginx/geoip
cd /etc/nginx/geoip
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
gunzip GeoIP.dat.gz
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip GeoLiteCity.dat.gz

4 Настройте Nginx

Теперь настраиваем nginx. Откройте /etc/nginx/nginx.conf...

nano /etc/nginx/nginx.conf

... и добавьте директивы geoip_country и geoip_city в контейнер http {}:

[...]
http {

##
# Basic Settings
##

geoip_country /etc/nginx/geoip/GeoIP.dat; # the country IP database
geoip_city /etc/nginx/geoip/GeoLiteCity.dat; # the city IP database [...]

Директива geoip_country делает доступными следующие переменные:

  • $geoip_country_code — двухбуквенный код страны, например, RU, US.
  • $geoip_country_code3 - трехбуквенный код страны, например, RUS, США.
  • $geoip_country_name – (подробное) название страны, например, Российская Федерация, США и т. д.

Директива geoip_city предоставляет следующие переменные:

  • $geoip_city_country_code — двухбуквенный код страны, например, RU, US.
  • $geoip_city_country_code3 - трехбуквенный код страны, например, RUS, USA.
  • $geoip_city_country_name — название страны, например, Российская Федерация, США — при наличии.
  • $geoip_region — название региона (область, район, штат, провинция, федеральная земля и т.п.), например, Москва-Сити, округ Колумбия — при наличии.
  • $geoip_city — название города, например, Москва, Вашингтон, Лиссабон и т. д. — при наличии.
  • $geoip_postal_code – почтовый индекс или почтовый индекс — при наличии.
  • $geoip_city_continent_code — если доступно.
  • $geoip_latitude — широта — если доступно.
  • $geoip_longitude — долгота — если доступно.

Чтобы сделать эти переменные доступными и для ваших PHP-скриптов, мы должны установить несколько директив fastcgi_param. Лучше всего это сделать в файле /etc/nginx/fastcgi_params, где находятся другие директивы fastcgi_param:

nano /etc/nginx/fastcgi_params
[...]
### SET GEOIP Variables ###
fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code;
fastcgi_param GEOIP_COUNTRY_CODE3 $geoip_country_code3;
fastcgi_param GEOIP_COUNTRY_NAME $geoip_country_name;

fastcgi_param GEOIP_CITY_COUNTRY_CODE $geoip_city_country_code;
fastcgi_param GEOIP_CITY_COUNTRY_CODE3 $geoip_city_country_code3;
fastcgi_param GEOIP_CITY_COUNTRY_NAME $geoip_city_country_name;
fastcgi_param GEOIP_REGION $geoip_region;
fastcgi_param GEOIP_CITY $geoip_city;
fastcgi_param GEOIP_POSTAL_CODE $geoip_postal_code;
fastcgi_param GEOIP_CITY_CONTINENT_CODE $geoip_city_continent_code;
fastcgi_param GEOIP_LATITUDE $geoip_latitude;
fastcgi_param GEOIP_LONGITUDE $geoip_longitude;

(Убедитесь, что у вас есть строка include /etc/nginx/fastcgi_params; в вашем контейнере location ~ \.php${} в конфигурации вашего виртуального хоста, потому что в противном случае приведенная выше конфигурация бесполезна для вашего виртуального хоста.)

Если вы используете nginx в качестве обратного прокси-сервера и хотите передать переменные GeoIP на серверную часть, вам следует создать/отредактировать файл /etc/nginx/proxy.conf...

nano /etc/nginx/proxy.conf

... и добавьте в него следующие строки:

[...]
### SET GEOIP Variables ###
proxy_set_header GEOIP_COUNTRY_CODE $geoip_country_code;
proxy_set_header GEOIP_COUNTRY_CODE3 $geoip_country_code3;
proxy_set_header GEOIP_COUNTRY_NAME $geoip_country_name;

proxy_set_header GEOIP_CITY_COUNTRY_CODE $geoip_city_country_code;
proxy_set_header GEOIP_CITY_COUNTRY_CODE3 $geoip_city_country_code3;
proxy_set_header GEOIP_CITY_COUNTRY_NAME $geoip_city_country_name;
proxy_set_header GEOIP_REGION $geoip_region;
proxy_set_header GEOIP_CITY $geoip_city;
proxy_set_header GEOIP_POSTAL_CODE $geoip_postal_code;
proxy_set_header GEOIP_CITY_CONTINENT_CODE $geoip_city_continent_code;
proxy_set_header GEOIP_LATITUDE $geoip_latitude;
proxy_set_header GEOIP_LONGITUDE $geoip_longitude;

(Убедитесь, что вы используете строку include /etc/nginx/proxy.conf; в конфигурации прокси-сервера nginx, иначе бэкенд не сможет использовать переменные GeoIP.)

Теперь перезагрузите nginx...

systemctl reload nginx.service

... чтобы изменения вступили в силу.

Перезапустите PHP-FPM следующим образом:

systemctl restart php7.0-fpm.service

5 Короткий тест

Чтобы убедиться, что модуль GeoIP работает правильно, мы можем создать небольшой файл PHP в нашем веб-пространстве www.example.com (например, /var/www/www.example.com/web):

nano /var/www/www.example.com/web/geoiptest.php

Мы можем получить доступ к переменным GeoIP следующим образом:

$geoip_country_code = getenv(GEOIP_COUNTRY_CODE);

Или вот так:

$geoip_country_code = $_SERVER['GEOIP_COUNTRY_CODE'];
<html>
<body>
<?php

$geoip_country_code = getenv(GEOIP_COUNTRY_CODE);
/*
$geoip_country_code = $_SERVER['GEOIP_COUNTRY_CODE']; // works as well
*/
$geoip_country_code3 = getenv(GEOIP_COUNTRY_CODE3);
$geoip_country_name = getenv(GEOIP_COUNTRY_NAME);

$geoip_city_country_code = getenv(GEOIP_CITY_COUNTRY_CODE);
$geoip_city_country_code3 = getenv(GEOIP_CITY_COUNTRY_CODE3);
$geoip_city_country_name = getenv(GEOIP_CITY_COUNTRY_NAME);
$geoip_region = getenv(GEOIP_REGION);
$geoip_city = getenv(GEOIP_CITY);
$geoip_postal_code = getenv(GEOIP_POSTAL_CODE);
$geoip_city_continent_code = getenv(GEOIP_CITY_CONTINENT_CODE);
$geoip_latitude = getenv(GEOIP_LATITUDE);
$geoip_longitude = getenv(GEOIP_LONGITUDE);

echo 'country_code: '.$geoip_country_code.'<br>';
echo 'country_code3: '.$geoip_country_code3.'<br>';
echo 'country_name: '.$geoip_country_name.'<br>';

echo 'city_country_code: '.$geoip_city_country_code.'<br>';
echo 'city_country_code3: '.$geoip_city_country_code3.'<br>';
echo 'city_country_name: '.$geoip_city_country_name.'<br>';
echo 'region: '.$geoip_region.'<br>';
echo 'city: '.$geoip_city.'<br>';
echo 'postal_code: '.$geoip_postal_code.'<br>';
echo 'city_continent_code: '.$geoip_city_continent_code.'<br>';
echo 'latitude: '.$geoip_latitude.'<br>';
echo 'longitude: '.$geoip_longitude.'<br>';

?>
</body>
</html>

Вызовите этот файл в браузере (http://www.example.com/geoiptest.php), и вы должны увидеть работу GeoIP (убедитесь, что вы вызываете файл с общедоступного IP-адреса, а не с локального):

Также возможно использовать переменные GeoIP непосредственно в конфигурации nginx, например. следующее:

nano /etc/nginx/sites-enabled/www.example.com.vhost
[...]
        location / {
            index index.html index.php;
            try_files /index_$geoip_country_code.html /index.html;
        }
[...]
systemctl reload nginx.service

В этом примере, если посетитель из Германии (код страны: DE) и существует файл index_DE.html, то обслуживается этот файл, в противном случае обслуживается файл index.html по умолчанию.

Это можно использовать для предоставления контента на разных языках в зависимости от происхождения пользователей.

6 ссылок

  • nginx: http://nginx.org/
  • Вики-сайт nginx: http://wiki.nginx.org/
  • Убунту: http://www.ubuntu.com/