nginx 配置geoip 屏蔽地区城市,实现判断国家IP跳转 Linux教程 nginx&apache 安全防御



Apache增加GeoIP模块:

yum -y install mod_geoip


安装 MaxMind 的 GeoIP 库
MaxMind 提供了免费的 IP 地域数据库(GeoIP.dat),不过这个数据库文件是二进制的,需要用 GeoIP 库来读取,所以除了要下载 GeoIP.dat 文件外(见下一步),还需要安装能读取这个文件的库。

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

刚才安装的库自动安装到 /usr/local/lib 下,所以这个目录需要加到动态链接配置里面以便运行相关程序的时候能自动绑定到这个 GeoIP 库:

echo '/usr/local/lib' > /etc/ld.so.conf.d/geoip.conf
ldconfig
下载 IP 数据库
MaxMind 提供了免费的 IP 地域数据库,这个数据库是二进制的,不能用文本编辑器打开,需要上面的 GeoIP 库来读取:
# wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
# gunzip GeoIP.dat.gz
这个是城市的ip数据包:
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip GeoLiteCity.dat.gz

执行完上面的命令后,会得到 GeoIP.dat 和 GeoLiteCity.dat 文件。

将这两个文件复制到 Nginx 的 conf 目录。


步骤    ./configure  --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-ipv6 --with-http_sub_module --with-http_flv_module --user=www --group=www --with-http_gzip_static_module --with-http_geoip_module

 

相应的省份代码:

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”

 

安装 Nginx

因为要用到 http_geoip_module 模块,系统自带的 nginx 一般不带这个模块,所以要下载 nginx 源代码后自行编译:

# wget http://nginx.org/download/nginx-0.9.6.tar.gz
# tar zxvf nginx-0.9.6.tar.gz
# cd nginx-0.9.6
# ./configure --without-http_empty_gif_module --with-poll_module \
--with-http_stub_status_module --with-http_ssl_module \
--with-http_geoip_module
# make; make install


配置 Nginx
最后是配置 nginx,在相关地方加上如下的配置就可以了:

# vi /etc/nginx/nginx.conf
...
geoip_country /home/vpsee/GeoIP.dat;

fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code;
fastcgi_param GEOIP_COUNTRY_CODE3 $geoip_country_code3;
fastcgi_param GEOIP_COUNTRY_NAME $geoip_country_name;
...

 if ($geoip_country_code = CN) {
    root /home/vpsee/cn/;
 }


这样,当来自中国的 IP 访问网站后就自动访问到预定的 /home/vpsee/cn 页面。关于 Nginx + GeoIP 还有很多有用的用法,比如做个简单的 CDN,来自中国的访问自动解析到国内服务器、来自美国的访问自动转向到美国服务器等。MaxMind 还提供了全球各个城市的 IP 信息,还可以下载城市 IP 数据库来针对不同城市做处理。


编译 Nginx

nginx默认不编译这个模块,需要开启--with-http_geoip_module编译选项。

模块依赖MaxMind GeoIP库。


配置 Nginx

接下来就需要配置 Nginx,首先需要在 Nginx 配置文件中的 http 区块中加载 GeoIP 的数据包:

#geoip
geoip_country /data/site/shell/GeoIP.dat;
geoip_city /data/site/shell/GeoLiteCity.dat;

禁止国家访问

只需要在网站的 Nginx 配置中加入下面的示例的代码:

if ($geoip_country_code = CN) {

  deny all;

}

上面的配置表示只要是国内的 IP,就拒绝访问。


GeoIP 组件配置项参考


GeoIP 中跟国家相关的变量:

$geoip_country_code #两位字符的英文国家码。如:CN, US

$geoip_country_code3 #三位字符的英文国家码。如:CHN, USA

$geoip_country_name #国家英文全称。如:China, United States

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 的属性:

# GeoIP
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;

然后在 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_country database;

默认值: —

上下文: http

指定数据库,用于根据客户端IP地址得到其所在国家。 使用这个数据库时,配置中可用下列变量:

(1)$geoip_country_code

双字符国家代码,比如 “RU”,“US”。

(2)$geoip_country_code3

三字符国家代码,比如 “RUS”,“USA”。

(3)$geoip_country_name

国家名称,比如 “Russian Federation”,“United States”。


2.geoip_city database;

默认值: —

上下文: http

指定数据库,用于根据客户端IP地址得到其所在的国家、行政区和城市。 使用这个数据库时,配置中可用下列变量:

(1)$geoip_city_country_code

双字符国家代码,比如 “RU”,“US”。

(2)$geoip_city_country_code3

三字符国家代码,比如 “RUS”,“USA”。

(3)$geoip_city_country_name

国家名称,比如 “Russian Federation”,“United States”。

(4)$geoip_region

国家行政区名(行政区、直辖区、州、省、联邦管辖区,诸如此类),比如 “Moscow City”,“DC”。

(5)$geoip_city

城市名称,比如 “Moscow”,“Washington”。

(6)$geoip_postal_code

邮编。


3.geoip_proxy address | CIDR;

默认值: —

上下文: http

这个指令出现在版本 1.3.0 和 1.2.1.

定义可信地址。 如果请求来自可信地址,nginx将使用其“X-Forwarded-For”头来获得地址。


4.geoip_proxy_recursive on | off;

默认值: 

geoip_proxy_recursive off;


5.案例说明:

 http {

.............

    geoip_city     GeoLiteCity.dat;
    upstream    wangtong {
        server 59.151.X.X;
    }
    upstream    dianxin {
        server 75.125.X.X;
    }
    upstream    USA {
        server www.google.cn;
    }

............

    }

    server {

      .......

       location / {
               if ($geoip_region ~ "(01|02|03|04|06|07|11|13|14|15|16|21|23|29|30|31|32|33)") {
                proxy_pass 
http://dianxin$request_uri;
                }
                if ($geoip_region ~ "(05|08|09|10|12|17|18|19|20|24|25|26)") {
                proxy_pass 
http://wangtong$request_uri;
                }
                if ($geoip_city_country_code ~ "US") {
                proxy_pass 
http://USA$request_uri;
                }

        }

    ........

    }


下面我来解释一下
if ($geoip_region ~ "(01|02|03|04|06|07|11|13|14|15|16|21|23|29|30|31|32|33)")
 
这些数字代表的是中国省份地区~~
表如下:
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"
 
GeoLiteCity.dat 更多变量请看 wiki 我这里只用到两个变量一个是$geoip_region  一个是$geoip_city_country   第一个是 地区,第二个变量是国家只取 两个字母简写!


签名:这个人很懒,什么也没有留下!
最新回复 (0)
返回