Nginx配置GeoIP2
背景
- GeoIP2数据库是免费的IP地理位置数据库,可以通过GeoIP2对不同地域的访问IP自定义不同的响应。GeoIP2分为收费版、免费版,其中免费版准确性要差一些,它的数据库更新频率为每两周一次。对于我这种小网站来讲已经很够用了。
- GeoIP2的前身是GeoIP,但是GeoIP已经过时了,被GeoIP2所替代。目前官网:https://www.maxmind.com/
- 搭建步骤简略:
- 安装libmaxminddb模块
- 编译安装ngx_http_geoip2_module模块
- 配置Nginx的ngx_http_geoip2_module模块
- 配置IP相关请求的处理方式
- 配置自动更新GeoIP2数据库
搭建
安装libmaxminddb模块
准备编译环境
1
2sudo apt update
sudo apt install build-essential -y通过apt安装libmaxminddb
1
2
3
4
5
6
7
8
9
10添加更新源
sudo add-apt-repository ppa:maxmind/ppa
删除更新源
sudo add-apt-repository -r ppa:maxmind/ppa
sudo apt update
sudo apt install libmaxminddb0 libmaxminddb-dev mmdb-bin
安装完成后检查安装结果
mmdblookup --version**(拓展)**libmaxminddb模块也可以通过源码安装,安装方式如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14拉取最新的源码,链接:https://github.com/maxmind/libmaxminddb/releases
wget https://github.com/maxmind/libmaxminddb/releases/download/1.3.2/libmaxminddb-1.3.2.tar.gz
tar xzvf libmaxminddb-1.3.2.tar.gz
cd libmaxminddb-1.3.2
编译安装源码,需要进入下载的源码所在文件夹中
./configure
make
make check
sudo make install
sudo ldconfig
安装完以后检查一下安装是否成功
mmdblookup --version
编译安装ngx_http_geoip2_module模块
下载ngx_http_geoip2_module的源码,下载来源路径:https://github.com/leev/ngx_http_geoip2_module/releases
1
2wget https://github.com/leev/ngx_http_geoip2_module/archive/3.3.tar.gz
tar xzvf 3.3.tar.gz下载与当前ubuntu系统中版本相同的nginx源码包
1
2
3
4
5
6查看当前nginx的版本
nginx -v
到nginx上下载对应版本的nginx源码
wget http://nginx.org/download/nginx-1.14.0.tar.gz
tar xzvf nginx-1.14.0.tar.gz编译ngx_http_geoip2_module模块。此处需要注意,一定要保持当前正在运行的nginx编译时的参数与本次编译时的参数保持一致
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16安装编译环境,随着版本迭代更新,这块可能会有变化,到时候自寻
sudo apt update
sudo apt install libpcre3-dev libssl-dev zlib1g-dev libxml2-dev libxslt1-dev libgd-dev libgeoip-dev -y
查看当前正在运行的nginx的编译参数
其中【configure arguments】后面的内容便全是参数,将其内容全部复制下来
nginx -V
进入刚下载nginx源码文件夹,进行重新编译
编译时需增加一个编译ngx_http_geoip2_module模块的参数,其路径是之前下载的ngx_http_geoip2_module文件夹路径
添加的参数为:--add-dynamic-module=/root/wu/ngx_http_geoip2_module-3.3
cd nginx-1.14.0
注意最后一定得添加ngx_http_geoip2_module-3.3得参数
./configure --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-mcUg8N/nginx-1.14.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module --add-dynamic-module=/root/dev/ngx_http_geoip2_module-3.3
make
make modules如果在configure的时候发生错误,请根据提示补装相应的依赖关系后进行重新编译。编译完成后可切换到当前nginx文件夹下的objs目录中,就可以寻找到我们想要的两个文件:【ngx_http_geoip2_module.so】和【ngx_stream_geoip2_module.so】,然后将这两个文件移动到【/usr/lib/nginx/modules】路径下
1
2
3cd objs
mv ngx_http_geoip2_module.so /usr/lib/nginx/modules
mv ngx_stream_geoip2_module.so /usr/lib/nginx/modules(拓展) 如果是通过宝塔面板编译安装的nginx,这种情况就简单一些。根据宝塔默认的安装路径,nginx的源码保存在/www/server/nginx/src,只需切换到该目录下面进行上述的编译工作即可。但这时候不要再下载nginx源码,因为宝塔的nginx编译参数都是需要在这个目录中执行的,防止意外情况发生,我们就在这个目录操作就好了。
配置nginx的ngx_http_geoip2_module模块
下载GeoIP2的相关数据库【包括GeoLite2 City和GeoLite2 County两个库】。现下GeoIP2需要注册用户才能够免费下载GeoLite2的数据库,因此先注册一个用户,之后进入【个人中心】,在左侧【GeoIP2/GeoLite2】中找到【Download File】,进去后下载【gzip】的文件。
将下载好的【GeoLite2 City】库与【GeoLite2 County】库复制到/var/GeoIP2下使用。这个存放路径可根据需要自己定,只是在配置nginx的时候,需要指定好这两个库文件的具体位置。
1
2
3
4
5
6
7
8
9
10
11提前创建好文件夹
mkdir /var/geoip2
解压下载的两个数据库的tar包
tar -xzvf GeoLite2-City.tar.gz
tar -xzvf GeoLite2-County.tar.gz
mv GeoLite2-City_20200908/GeoLite2-City.mmdb /var/geoip2/
mv GeoLite2-County_20200908/GeoLite2-County.mmdb /var/geoip2/
解压完成后,使用mmdblookup命令在库中测试一下,如果成功则直接返回该IP对应的字典信息
mmdblookup -f /var/geoip2/GeoLite2-County.mmdb -i 8.8.8.8配置nginx的配置文件【nginx.conf】,其配置文件路径根据不同的安装方式位于不同的路径之下:
apt安装:文件位于【/etc/nginx】下
宝塔面板:文件位于【/www/server/nginx/conf/】下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32在nginx.conf文件的头部引入编译的ngx_http_geoip2_module.so
load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so;
(参考)同时在其中引入ngx_http_geoip2_module模块的相关配置,配置项都配置在http项中,下面配置仅作参考
(参考)注意其对应的GeoLite2-City.mmdb文件的路径为自己存放的路径。
(参考)这个配置是一位博主给的,目前还不知道配置的含义,暂且记录。
geoip2 /var/geoip2/GeoLite2-City.mmdb {
$geoip2_data_city_continent_code continent code;
$geoip2_data_city_continent_name continent names zh-CN;
$geoip2_data_city_country_code country iso_code;
$geoip2_data_city_country_name country names zh-CN;
$geoip2_data_city_region_code subdivisions 0 iso_code;
$geoip2_data_city_region_name subdivisions 0 names zh-CN;
$geoip2_data_city_location_latitude location latitude;
$geoip2_data_city_location_longitude location longitude;
$geoip2_data_city_postal postal code;
$geoip2_data_city_city_name city names en;
}
(推荐)以下是另一位博主提供的配置方式
geoip2 /var/GeoIP2/GeoLite2-Country.mmdb {
auto_reload 60m;
$geoip2_metadata_country_build metadata build_epoch;
$geoip2_data_country_code country iso_code;
$geoip2_data_country_name country names en;
}
geoip2 /var/GeoIP2/GeoLite2-City.mmdb {
auto_reload 60m;
$geoip2_metadata_city_build metadata build_epoch;
$geoip2_data_city_name city names en;
}配置nginx的配置文件【fastcgi.conf】,用于配置将geo信息传递到php上(如果网站不是php的则可不需要配置),其配置文件路径根据不同的安装方式位于不同的路径之下:
apt安装:文件位于【/etc/nginx】下
宝塔面板:文件位于【/www/server/nginx/conf/】下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16(参考)一位博主提供的配置信息
fastcgi_param MM_CONTINENT_CODE $geoip2_data_city_continent_code;
fastcgi_param MM_CONTINENT_NAME $geoip2_data_city_continent_name;
fastcgi_param MM_COUNTRY_CODE $geoip2_data_city_country_code;
fastcgi_param MM_COUNTRY_NAME $geoip2_data_city_country_name;
fastcgi_param MM_REGION_CODE $geoip2_data_city_region_code;
fastcgi_param MM_REGION_NAME $geoip2_data_city_region_name;
fastcgi_param MM_LATITUDE $geoip2_data_city_location_latitude;
fastcgi_param MM_LONGITUDE $geoip2_data_city_location_longitude;
fastcgi_param MM_POSTAL_CODE $geoip2_data_city_postal;
fastcgi_param MM_CITY_NAME $geoip2_data_city_city_name;
(推荐)另一位博主提供的配置信息
fastcgi_param COUNTRY_CODE $geoip2_data_country_code;
fastcgi_param COUNTRY_NAME $geoip2_data_country_name;
fastcgi_param CITY_NAME $geoip2_data_city_name;安装完成后重启一下【nginx】
1
2
3
4
5
6如果没有报异常,则正常重启
sudo service nginx restart
sudo service nginx -s reload
如果报错了,则根据报错内容去修改配置文件
sudo service nginx status
配置IP相关请求的处理方式
若还拥有ISP的库,则需要在nginx.conf中配置如下:
1
2
3
4
5配置项配置在http项中
geoip2 /var/geoip2/GeoIP2-ISP.mmdb {
$geoip2_data_isp_isp isp;
$geoip2_data_isp_org organization;
}同时若网站基于php,则还需要在nginx.conf中配置如下内容以完成isp信息的读取:
1
2fastcgi_param MM_ISP $geoip2_data_isp_isp;
fastcgi_param MM_ORG $geoip2_data_isp_org;若使用cloudflare加速了自己的网站,此时默认获取的IP其实不是客户端IP,而是cloudflare的cdn服务器IP。这时候在nginx.conf中的代码需要做调整,将source指定为$HTTP_CF_CONNECTING_IP。若用了nginx反向代理,则将serouce指定为$HTTP_X_FORWARDED_FOR。此处配置以加速为例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23需注意,每处添加了一个source配置项,同时,需注意GeoIP2的数据库地址需准确
此处也只配置City的数据,还可以配置County的数据
内容配置在http配置项中
geoip2 /var/geoip2/GeoLite2-City.mmdb {
auto_reload 60m;
$geoip2_data_city_continent_code source=$HTTP_CF_CONNECTING_IP continent code;
$geoip2_data_city_continent_name source=$HTTP_CF_CONNECTING_IP continent names zh-CN;
$geoip2_data_city_country_code source=$HTTP_CF_CONNECTING_IP country iso_code;
$geoip2_data_city_country_name source=$HTTP_CF_CONNECTING_IP country names zh-CN;
$geoip2_data_city_region_code source=$HTTP_CF_CONNECTING_IP subdivisions 0 iso_code;
$geoip2_data_city_region_name source=$HTTP_CF_CONNECTING_IP subdivisions 0 names zh-CN;
$geoip2_data_city_location_latitude source=$HTTP_CF_CONNECTING_IP location latitude;
$geoip2_data_city_location_longitude source=$HTTP_CF_CONNECTING_IP location longitude;
$geoip2_data_city_postal source=$HTTP_CF_CONNECTING_IP postal code;
$geoip2_data_city_city_name source=$HTTP_CF_CONNECTING_IP city names en;
}
没有该文件的话就不用配置这一项
geoip2 /var/geoip2/GeoIP2-ISP.mmdb {
auto_reload 60m;
$geoip2_data_isp_isp source=$HTTP_CF_CONNECTING_IP isp;
$geoip2_data_isp_org source=$HTTP_CF_CONNECTING_IP organization;
}若想屏蔽某个国家的访问,则在nginx.conf中配置访问名单,配置如下:
1
2
3
4
5
6
7
8此处配置的内容会被当作变量用于网站访问的路由中
配置的内容放置于http项中
map $geoip2_data_country_code $domain_xyz_allowed_country {
default yes;
# 第一个参数是国家的简称,对应于$geoip2_data_country_code参数,
# 第二个是是否允许访问,可设置为yes/no,对应于$domain_xyz_allowed_country参数
BG no;
}在网站的配置中添加路由,用于处理是否允许指定国家IP的访问
1
2
3
4
5
6
7此处配置的内容位于server配置项中。
修改内容所在的文件是nginx网站的配置文件。
location / {
if ($domain_xyz_allowed_country = no) {
return 444; # 此处你也可以设置重定向rewrite
}
}若希望指定国家的IP访问时,能够跳转到其它的页面,则做以下配置
1
2
3
4
5
6在nginx网站的配置文件中添加路由转发
location / {
if ($geoip2_data_country_code = BG) {
rewrite ^(.*)? https://test.test.bg$request_uri redirect;
}
}
定时更新GeoIP2数据库
安装geoipupdate工具
1
2
3
4sudo apt install geoipupdate
安装完毕后检查安装是否成功
geoipupdate --version进入官网登录,找到个人账户密钥。进入个人中心,依次点击【Automatic Updates】–>【Generate new license key】,然后根据内容提示生成【账户信息】,最终得到的结果如下:
编辑配置geoipupdate的配置文件信息,配置文件位于:/etc/GeoIP.conf,配置文件信息如下:
1
2
3
4
5
6配置账户信息,该账户信息是注册用户个人独有的
AccountID 对应[Account/User ID]
LicenseKey 对应[License Key]
EditionIDs GeoLite2-Country GeoLite2-City
配置GeoIP数据库存放的路径
DatabaseDirectory /var/GeoIP2配置完成后,执行geoipupdate,看是否报错,若无报错即可
1
geoipupdate
利用cron定时执行geoipupdate命令以更新数据库信息,cron定时任务的配置文件是:/etc/crontab
1
2
3
4
5
6
7
8
9
10
11
12编辑配置文件
sudo vim /etc/crontab
在配置文件的末尾处添加以下内容:
59 13 * * 5 root /usr/bin/geoipupdate
添加完毕后,重新启动cron服务
sudo service cron restart
关于配置定时任务,也可以通过命令,然后回进入页面让添加新的任务
crontab -e
知识点
文章主要参考如下链接,感谢博主的细心总结:
https://www.azio.me/how-to-install-ngx_http_geoip2_module/
个人借鉴
配置前前后后花费数日,期间多次失败,参考无数配置教程,却一直迷失于GeoIP和GeoIP2的版本中,而后又因为nginx的静态安装和动态安装的问题,头疼不已。所幸后来推倒重来,借助于上述链接,静下心来思考和尝试,才最终成功,可见急躁可以有,但是耐心和细心不可无。配置完毕再回头,偶遇一篇博文,说到了用docker虚拟环境去测试搭建,而我却一直用真实环境在弄,不免显得有些傻逼了。
计划
- 找找nginx的配置教程和内容
- 找找docker的教程
- 寻找cron定时任务的教程