如何使用GeoIP与Nginx在Ubuntu 16.04

本教程解释如何在Ubuntu 16.04上使用nginx的GeoIP模块,以了解您的访问者来自哪里。 GeoIP模块设置多重...

本教程将介绍如何在Ubuntu 16.04上使用带有nginx的GeoIP模块,以了解访问者的来源。 GeoIP模块设置多个变量,如$ geoip_country_name$ geoip_country_code$ geoip_city等,您可以在PHP脚本中使用,或直接在nginx配置中使用,例如,根据用户的国家/地区提供不同语言的内容。

1初步说明

我正在使用网站www.example.com ,其中包含文件根/var/www/www.example.com/web/和Nginx vhost配置文件/etc/nginx/sites-enabled/www.example.com。虚拟主机 我将使用本教程进行基本的Ubuntu-Nginx设置。 https://www.howtoing.com/tutorial/installing-nginx-with-php7-fpm-and-mysql-on-ubuntu-16.04-lts-lemp/

此教程与ISPConfig nginx设置兼容。

Ubuntu用户注意事项:

因为我们必须使用root权限运行本教程的所有步骤,所以我们可以使用字符串sudo在本教程中添加所有命令,也可以通过键入来成为root

sudo -s

2了解Nginx是否支持GeoIP

在我们开始之前,我们必须确定GeoIP模块是否内置在我们的nginx服务器中:

nginx -V

root@server1:~# 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上,有一个可以通过apt安装的geoip 数据库 ,但是它有点过时,只包含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_countrygeoip_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 - 两个字母的国家代码,例如RUUS
  • $ geoip_country_code3 - 三个字母的国家/地区代码,例如, 美国 RUS
  • $ geoip_country_name - 国家的(详细)名称,例如俄罗斯联邦美国等。

geoip_city指令提供以下变量:

  • $ geoip_city_country_code - 两个字母的国家/地区代码,例如RUUS
  • $ geoip_city_country_code3 - 三个字母的国家/地区代码,例如RUSUSA
  • $ geoip_city_country_name - 国家的名称,例如俄罗斯联邦美国 - 如果可用。
  • $ geoip_region - 区域名称(省,地区,州,省,联邦土地等),例如, 莫斯科市DC (如果有的话)。
  • $ 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;

(请确保您的虚拟机配置中包含/ etc / nginx / fastcgi_params;在您的位置〜\ .php $ {}容器中,否则上述配置对您的vhost无效。)

如果您使用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;

(确保您的nginx代理配置中使用包含/etc/nginx/proxy.conf的行,否则后台不能使用GeoIP变量。)

现在重新加载nginx ...

systemctl reload nginx.service

...使更改生效。

重新启动PHP-FPM如下:

systemctl restart php7.0-fpm.service

5短测

要了解GeoIP模块是否正常工作,我们可以在www.example.com网络空间中创建一个小型PHP文件(例如/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地址(而不是本地IP地址调用文件)

GeoIP测试

还可以直接在nginx配置中使用GeoIP变量,例如:

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文件。

这可以用于根据用户的来源为不同语言的内容提供服务。