nginx精准禁止特定国家或者地区IP访问和设置白名单
要求:对网站的信息,比如某个访问节点不想国内或者国外的用户使用,禁止国内或者国外或者精确到某个城市的那种情况。
解决方式:
-
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建议选择最新版本,我选的是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整体安装完就检查下模块是否都有:
五:验证是否成功
ldd ldd /usr/bin/nginx
六:修改nginx配置
模块安装成功后,还要在 Nginx 里指定数据库,在安装运行库时默认安装了两个,位于 /usr/share/GeoIP/ 目录下,一个只有 IPv4,一个包含 IPv4 和 IPv6:
数据库地址:
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不光可以屏蔽国家,还可以屏蔽身份、城市,如果有需要可以自己研究下。