Nginx服务器中配置GeoIP模块来拦截指定国家IP
最近有一个网站项目需求:需要屏蔽国内的方问请求。花时间研究了一下这方面的资料。目前找到的最佳方法就是使用Nginx的GeoIP模块来实现地区的识别。然后配置相关国家的ISO名称,禁止访问即可。记录一下相关过程。
编译GeoIP组件
maxmind提供的免费版数据库已经可以满足需求,在使用数据库前,需要先编译GeoIP组件:
wgethttp://geolite.maxmind.com/download/geoip/api/c/GeoIP-1.4.8.tar.gz ./configure make makeinstall
下载IP库
从maxmind下载IP数据包并解压。这个是国家的ip数据包:
wgethttp://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz gunzipGeoIP.dat.gz
这个是城市的ip数据包:
wgethttp://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz gunzipGeoLiteCity.dat.gz
执行完上面的命令后,会得到GeoIP.dat和GeoLiteCity.dat文件。将这两个文件复制到Nginx的conf目录。
编译Nginx
nginx默认不编译这个模块,需要开启--with-http_geoip_module编译选项。
模块依赖MaxMindGeoIP库。
配置Nginx
接下来就需要配置Nginx,首先需要在Nginx配置文件中的http区块中加载GeoIP的数据包:
geoip_countryGeoIP.dat; geoip_cityGeoLiteCity.dat;
禁止国家访问
只需要在网站的Nginx配置中加入下面的示例的代码:
if($geoip_country_code=CN){ denyall; }
上面的配置表示只要是国内的IP,就拒绝访问。
GeoIP组件配置项参考
GeoIP中跟国家相关的变量:
$geoip_country_code#两位字符的英文国家码。如:CN,US $geoip_country_code3#三位字符的英文国家码。如:CHN,USA $geoip_country_name#国家英文全称。如:China,UnitedStates
GeoIP中跟国家下级区域相关的变量:
$geoip_city_country_code#也是两位字符的英文国家码。 $geoip_city_country_code3#上同 $geoip_city_country_name#上同. $geoip_region#这个经测试是两位数的数字,如杭州是02,上海是23。但是没有搜到相关资料,希望知道的朋友留言告之。 $geoip_city#城市的英文名称。如:Hangzhou $geoip_postal_code#城市的邮政编码。经测试,国内这字段为空 $geoip_city_continent_code#不知什么用途,国内好像都是AS $geoip_latitude#纬度 $geoip_longitude#经度
在php中测试GeoIP
首先需要在fastcgi_params或fastcgi.conf中引入GeoIP的属性:
fastcgi_paramGEOIP_COUNTRY_CODE$geoip_country_code; fastcgi_paramGEOIP_COUNTRY_CODE3$geoip_country_code3; fastcgi_paramGEOIP_COUNTRY_NAME$geoip_country_name; fastcgi_paramGEOIP_CITY_COUNTRY_CODE$geoip_city_country_code; fastcgi_paramGEOIP_CITY_COUNTRY_CODE3$geoip_city_country_code3; fastcgi_paramGEOIP_CITY_COUNTRY_NAME$geoip_city_country_name; fastcgi_paramGEOIP_REGION$geoip_region; fastcgi_paramGEOIP_CITY$geoip_city; fastcgi_paramGEOIP_POSTAL_CODE$geoip_postal_code; fastcgi_paramGEOIP_CITY_CONTINENT_CODE$geoip_city_continent_code; fastcgi_paramGEOIP_LATITUDE$geoip_latitude; fastcgi_paramGEOIP_LONGITUDE$geoip_longitude;
然后在web目录中增加一个php文件,代码如下:
<?php $geoip_country_code=getenv(GEOIP_COUNTRY_CODE); $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/>';
访问php文件,就会显示你当前所在IP的相关地理信息。
php也提供了GeoIP模块,需要手动编译。也需要加载GeoIP库。效率上应该还是不如Nginx的方式。
常用指令总结
1.geoip_countrydatabase;
默认值: —
上下文: http
指定数据库,用于根据客户端IP地址得到其所在国家。使用这个数据库时,配置中可用下列变量:
(1)$geoip_country_code
双字符国家代码,比如“RU”,“US”。
(2)$geoip_country_code3
三字符国家代码,比如“RUS”,“USA”。
(3)$geoip_country_name
国家名称,比如“RussianFederation”,“UnitedStates”。
2.geoip_citydatabase;
默认值: —
上下文: http
指定数据库,用于根据客户端IP地址得到其所在的国家、行政区和城市。使用这个数据库时,配置中可用下列变量:
(1)$geoip_city_country_code
双字符国家代码,比如“RU”,“US”。
(2)$geoip_city_country_code3
三字符国家代码,比如“RUS”,“USA”。
(3)$geoip_city_country_name
国家名称,比如“RussianFederation”,“UnitedStates”。
(4)$geoip_region
国家行政区名(行政区、直辖区、州、省、联邦管辖区,诸如此类),比如“MoscowCity”,“DC”。
(5)$geoip_city
城市名称,比如“Moscow”,“Washington”。
(6)$geoip_postal_code
邮编。
3.geoip_proxyaddress|CIDR;
默认值: —
上下文: http
这个指令出现在版本1.3.0和1.2.1.
定义可信地址。如果请求来自可信地址,nginx将使用其“X-Forwarded-For”头来获得地址。
4.geoip_proxy_recursiveon|off;
默认值:
geoip_proxy_recursiveoff;
上下文: http