要求:对网站的信息,比如某个访问节点不想国内或者国外的用户使用,禁止国内或者国外或者精确到某个城市的那种情况。

解决方式:

  • 1.Cloudfalre来实现禁止特定国家的ip访问,比较简单,但是需要money!!!
  • 2.nginx,直接使用geoip模块,现在我们使用最新的ngx_http_geoip2,该模块可以精确到国家、省、市等一级的IP,并且全部由Nginx执行识别和阻止访问,但是Nginx编译起来比较费事。

最终解决方式,使用nginx的geoip模块:

部署操作:

一:安装geoip2扩展依赖

安装 libmaxminddb 库,这个是用来读取ip数据文件的。

yum install libmaxminddb-devel -y

如果没有yum源直接使用源码编译

下载 https://github.com/maxmind/libmaxminddb/releases/download/1.3.2/libmaxminddb-1.3.2.tar.gz 解压依次执行:

./configure
make
make install
echo /usr/local/lib  >> /etc/ld.so.conf.d/local.conf
ldconfig

即可。

二:下载ngx_http_geoip2_module

git clone https://github.com/leev/ngx_http_geoip2_module.git

注意要是没有git的话就自己在网上下了然后直接拖到服务器上也行,不过注意格式。

三:查看模块的完整性

查看模块的完整性,将下载好的模块放到指定目录下,方便nginx编译时指定路径,我是放到/usr/local/src/下面的。

nginx 指定目录 设置白名单 nginx配置ip白名单_nginx

四:编译nginx并检查模块是否安装成功

nginx建议选择最新版本,我选的是1.18。

注意:在编译时,我们只要加上--add-module=/usr/local/src/ngx_http_geoip2_module这个参数或者命令就行了,注意一定要加上额,不加等于没有geoip模块,就更没有这个功能了,为了简化,具体的nginx编译参数我就不写了,如下。

./configure --add-module=/usr/local/ngx_http_geoip2_module --user=www --group=www --prefix=......................................

之后的功能make && make install 等照常规流程来就行了,如果是之前已经安装过nginx只是后来想添加上geoip这个模块执行make后就不需要执行make install命令。

nginx整体安装完就检查下模块是否都有:

nginx 指定目录 设置白名单 nginx配置ip白名单_git_02

五:验证是否成功

ldd ldd /usr/bin/nginx

nginx 指定目录 设置白名单 nginx配置ip白名单_git_03

六:修改nginx配置

模块安装成功后,还要在 Nginx 里指定数据库,在安装运行库时默认安装了两个,位于 /usr/share/GeoIP/ 目录下,一个只有 IPv4,一个包含 IPv4 和 IPv6:

nginx 指定目录 设置白名单 nginx配置ip白名单_Nginx_04


数据库地址:

wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz

百度云链接 提取码:6666
之后使用gunzip解压这两个库文件。

修改nginx配置文件,因为geoip2和geoip是不一样的,我们可以在 http 段增加国家代码的map映射:

在http端中添加如下代码:

geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
$geoip2_data_country_code country iso_code;
}
map $geoip2_data_country_code $allowed_country {
 default yes;
 CN no;
 }

#geoIP的白名单
geo $remote_addr $ip_whitelist {
    default 0;
    include ip.conf;
}

站点的server段里面加一下代码拒绝所有不是国内ip:

if ($ip_whitelist = 1) {
       break;
    }

   if ($allowed_country = yes) 
   { return 403; }

这里显示的是允许国内的ip访问,国外直接返回403。
在 conf 下新建一个 ip.conf 作为 Geoip 的白名单,支持 ip 段,内容和格式为:

8.8.8.8 1;
8.8.8.8/24 1;

这样就配置好了 nginx, 并且通过 GeoIP 限制了国家和城市的访问,并且支持白名单。

七:测试
在国内可以访问网站,在国外访问失败。

如此测试,是成功了的,如果是相反的,禁止国内访问, 那么server段里if ($allowed_country = yes) { return 403; }的yes改成no即可。

总结:

由于 IP 广播泛滥,所以 GeoIP 并不是那么准确,如果觉得 GeoIP 库太旧了,需要自行到官网下载最新版,将上述配置的路径改一下即可。

GeoIP不光可以屏蔽国家,还可以屏蔽身份、城市,如果有需要可以自己研究下。

参考: 文章1 文章2

自强不息,厚德载物。