Rootop 服务器运维与web架构

nginx通过geoip2模块实现区分城市省份的跳转

mmdblookup命令由 https://github.com/maxmind/libmaxminddb/releases 提供。
ip数据库文件从 https://dev.maxmind.com/geoip/geoip2/geolite2/ 下载 geolite2版(免费版),需要登录才能下。
过程略。

# 获取所有ip信息
[root@localhost]# mmdblookup --file /home/mmdb/GeoLite2-City.mmdb --ip 1.1.1.1
会返回一个类似json格式的数据,但并不是json。这里截取部分返回信息:
 "country": 
      {
        "geoname_id": 
          2077456 <uint32>
        "iso_code": 
          "AU" <utf8_string>
        "names": 
          {
            "de": 
              "Australien" <utf8_string>
            "en": 
              "Australia" <utf8_string>
            "es": 
              "Australia" <utf8_string>
            "fr": 
              "Australie" <utf8_string>
            "ja": 
              "オーストラリア" <utf8_string>
            "pt-BR": 
              "Austrália" <utf8_string>
            "ru": 
              "Австралия" <utf8_string>
            "zh-CN": 
              "澳大利亚" <utf8_string>
          }
      }

比如要返回iso_code值,则传递 country 和 iso_code 2个值给命令

[root@localhost]# mmdblookup --file /home/mmdb/GeoLite2-City.mmdb --ip 1.1.1.1 country iso_code

  "AU" <utf8_string>

 

# 获取国家
[root@localhost]# mmdblookup --file /home/mmdb/GeoLite2-City.mmdb --ip x.x.x.x country iso_code
# 获取城市
[root@localhost]# mmdblookup --file /home/mmdb/GeoLite2-City.mmdb --ip x.x.x.x city names en
# 获取省份
[root@localhost]# mmdblookup --file /home/mmdb/GeoLite2-City.mmdb --ip x.x.x.x subdivisions 0 names en

这些字段在nginx配置文件中同样适用。了解完返回的ip信息结构后,现在实现一个需求。
当客户端来源ip在被屏蔽的城市或者省份时,且访问的地址不是/new.html,则跳转到/new.html页面。其它的则不跳转。

# nginx配置,在http段,geoip2和map指令只能存在于http段中。
# 通过map指令实现定义要屏蔽的城市和省份名单

geoip2 /home/mmdb/GeoLite2-City.mmdb
{
	#default是为了当ip查不到信息时设置一个默认值。
	$country default=CN country iso_code;
    $city_name default=Beijing city names en;
	$province default=Shandong subdivisions 0 names en;
}

# 定义城市名单
map $city_name $allow_city
{
	default yes;
	Beijing no;
	Guangzhou no;
	Shanghai no;
	Shenzhen no;
}

# 定义省份名单
map $province $allow_province
{
	default yes;
	Shandong no;
}
	
# 在虚拟主机段
server
{
	# 拒绝国外访问
	if ( $country != "CN" )
	{
		return 403;
	}

	set $jump "0";
	# 判断是否访问的为new.html,防止出现死循环跳转。
	if ($uri != '/new.html')
	{
	  set $jump "${jump}0";
	}
	
	if ( $allow_city = "no" )
	{
	  set $jump "${jump}1";
	}
	
	if ( $allow_province = "no" )
	{
	  set $jump "${jump}1";
	}
	
	if ( $jump = "001" )
	{
		return 301 http://x.x.x.x/new.html;
	}
	
	if ( $jump = "0011" )
	{
		return 301 http://x.x.x.x/new.html;
	}
	
	# 通过浏览器响应头查看ip所属地信息
	add_header city $city_name;
	add_header province $province;
	add_header jump $jump;
}

测试,略。

注意:GeoLite2-City.mmdb这个开源的地址库,ip并不是很准确,包括会出现查不到的ip。
推测这些变量可以写到访问日志中记录,未测试。

原创文章,转载请注明。本文链接地址: https://www.rootop.org/pages/4866.html

作者:Venus

专注于 服务器运维与web架构 E-mail:venus#rootop.org

评论已关闭。