chaihongjun.me

nginx搭配GeoIP数据屏蔽访问

    因为业务需求,希望网站服务器能够阻挡禁止某一地区(国家,省份,城市)的人访问到我们的业务网站,于是乎捣鼓一下午找到两个可以实施是方案。

方案一:利用新浪或者腾讯等公开的IP地址库判断用户所在地,并且做出封锁行为,大概的代码如下:

<!-- 首页上网站页面加载 -->
<script type="text/javascript" src="http://int.dpool.sina.com.cn/iplookup/iplookup.php?=js"></script> 
<!-- 接着做地区判断 并作出封锁 -->
<script>
var CityName=remote_ip_info.city;	
    if(CityName !='北京')
     {
   
      window.location.href='http://www.baidu.com/';

     }

</script>

上面的方法有几个缺陷:

  1. 需要所有页面都加载所有代码

  2. JS去做判断再做动作响应比较的慢速

  3. 只能做页面跳转等少数动作

所以,这个方案被我摒弃了,直接进入方案二:

背景介绍利用nginx+GeoIP数据库搭配,封锁指定区域访客。这里不考虑新安装nginx,而是在现有已经运行的服务器上做的新模块搭建。

参考文章:http://www.scalescale.com/tips/nginx/how-to-install-nginx-geoip-module/

1.首先安装 MaxMind C API

wget http://geolite.maxmind.com/download/geoip/api/c/GeoIP.tar.gz
tar -zxvf GeoIP.tar.gz
cd GeoIP-1.4.8
./configure
make
make install

这个是GeoIP依赖的库,接着将此库动态加载了:

echo '/usr/local/lib' > /etc/ld.so.conf.d/geoip.conf
ldconfig

检查一下是否成功:

ldconfig -v | grep GeoIP

如果成功了,则会出现下面的内容:

libGeoIPUpdate.so.0 -> libGeoIPUpdate.so.0.0.0
libGeoIP.so.1 -> libGeoIP.so.1.6.5

当然,随着软件的升级,后面的版本号会有变化,当然你也会看到其他动态加载的库。

2.第二步是下载GeoIP的数据库了,并将这两条文件引入nginx.conf的http段。服务器是查询本地的DAT数据文件里面的文件达成的。

#下载并解压城市数据
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz -O /usr/local/share/GeoIP/GeoLiteCity.dat.gz
gzip -d /usr/local/share/GeoIP/GeoLiteCity.dat.gz
#下载并解压国家数据
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz -O /usr/local/share/GeoIP/GeoIP.dat.gz
gzip -d /usr/local/share/GeoIP/GeoIP.dat.gz
http{
      # 引入数据文件 
      geoip_country /usr/local/share/GeoIP/GeoIP.dat;
      geoip_city /usr/local/share/GeoIP/GeoLiteCity.dat;
      
      ......

}

3.第三步不能遗漏,添加GeoIP的变量,因为在nginx的配置文件中会用到,如果你是用php-pfm将下面的代码同样也添加到http段内:

http{
     # 引入数据文件 
      geoip_country /usr/local/share/GeoIP/GeoIP.dat;
      geoip_city /usr/local/share/GeoIP/GeoLiteCity.dat;
      
      ......
      
      
#  将下面的代码添加到http段内容    
# Set php-fpm 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;

......

4.然后,开始真正的编译nginx增加新的GeoIP模块:(后面增加 --with-http_geoip_module)

./configure {此处是之前编译的参数} --with-http_geoip_module

然后是

make

接着就是平滑升级Nginx那套东西啦!

5.最后一步就是实际配置了,直接进入具体网站的配置文件里面添加如下,即可阻挡访问:

###chaihongjun.me.conf
             ...
 
if ($geoip_city ~ "(Chongqing|Chengdu)") {   ##重庆和成都的IP访问不了网站,直接给了个403;
            return 403;
        }
        
        
if ($geoip_reigon ~ "(01|03)") { #安徽和江西的用户无法访问了       
        
        return 403;
       } 
           ...

 }

6.然后是必要的重新加载nginx

附录 geoip_reigon  省份代码:

CN,01,”Anhui”

CN,02,”Zhejiang”

CN,03,”Jiangxi”

CN,04,”Jiangsu”

CN,05,”Jilin”

CN,06,”Qinghai”

CN,07,”Fujian”

CN,08,”Heilongjiang”

CN,09,”Henan”

CN,10,”Hebei”

CN,11,”Hunan”

CN,12,”Hubei”

CN,13,”Xinjiang”

CN,14,”Xizang”

CN,15,”Gansu”

CN,16,”Guangxi”

CN,18,”Guizhou”

CN,19,”Liaoning”

CN,20,”Nei Mongol”

CN,21,”Ningxia”

CN,22,”Beijing”

CN,23,”Shanghai”

CN,24,”Shanxi”

CN,25,”Shandong”

CN,26,”Shaanxi”

CN,28,”Tianjin”

CN,29,”Yunnan”

CN,30,”Guangdong”

CN,31,”Hainan”

CN,32,”Sichuan”

CN,33,”Chongqing”

知识共享许可协议本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。作者:chaihongjun»