Nginx实践之使用MaxMind的GeoIP2实现处理不同国家的访问

场景:
因防火墙到期,原网站接入的需要回到公网的解析,经过分析,站点只需要国内访问。于是想到了用地址过滤,目前比较火的是nginx的allow和deny,另外一种是geoip,geoip2
区别:
GeoIP用于通过IP获取地理位置信息,但精度有限,更适用于大致定位。
GeoIP已经发展到GeoIP2,文件格式从.dat变为.mmdb。
MaxMind提供免费的GeoLite数据库,但已经停止更新GeoIP格式(.dat),只维护GeoIP2格式(.mmdb)。
GeoIP可以动态加载到Nginx等软件,GeoIP2需要重新编译。
GeoLite2是GeoIP2的免费版本,准确性较差,每周更新一次。
从2019年开始,GeoLite2数据库需要注册账户和License Key才能下载。
GeoIP的优点是可以动态加载到软件中,而GeoIP2需要重新编译。

需要的软件:
Nginx+GeoIP2:

nginx-1.22.0.tar.gz
libmaxminddb-1.6.0.tar.gz
ngx_http_geoip2_module-3.4.tar.gz
GeoLite2-City_20220802.tar.gz
GeoLite2-Country_20220802.tar.gz

=====
好的,把安装libmaxminddb库和编译Nginx with GeoIP2模块的两个脚本合并起来,注意顺序如下:

#!/bin/bash

# 安装libmaxminddb依赖
wget -c https://github.com/maxmind/libmaxminddb/releases/download/1.6.0/libmaxminddb-1.6.0.tar.gz
tar -zxvf libmaxminddb-1.6.0.tar.gz 
cd libmaxminddb-1.6.0
./configure
make && make install

# 配置动态库目录
tee -a /etc/ld.so.conf.d/libc.conf <<EOF
/usr/local/lib
EOF
ldconfig

# 创建Nginx目录 
mkdir /data/app/nginx -p

# 安装Nginx依赖
yum install gcc zlib-devel pcre-devel openssl-devel -y

# 下载和解压
wget http://nginx.org/download/nginx-1.22.0.tar.gz
tar xf nginx-1.22.0.tar.gz

# 下载和解压GeoIP2模块
wget -c https://github.com/leev/ngx_http_geoip2_module/archive/refs/tags/3.4.tar.gz -O ngx_http_geoip2_module-3.4.tar.gz
tar -zxf ngx_http_geoip2_module-3.4.tar.gz

# 编译配置
cd nginx-1.22.0/
./configure --with-http_ssl_module --add-module=../ngx_http_geoip2_module-3.4

# 编译、安装 
make && make install

# 设置PATH
export PATH=/data/app/nginx/sbin:$PATH

# 检查并启动
/data/app/nginx/sbin/nginx -t
/data/app/nginx/sbin/nginx

# 检查是否启动
netstat -nltp | grep nginx

主要注意点:

  1. 首先安装libmaxminddb库依赖

  2. 再编译包含GeoIP模块的Nginx

  3. Nginx编译需要GCC和相关开发库

  4. 设置PATH并启动Nginx

================

如果Nginx已经部署运行,只需要新增GeoIP模块,可以只重新编译并替换nginx二进制文件,无需完全重新安装。

具体操作步骤可以是:

  1. 备份当前运行的nginx二进制文件,例如 mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak

  2. 下载Nginx源码,解压到指定目录

  3. 配置时只添加GeoIP模块,例如:–add-module=ngx_http_geoip2_module-3.4

  4. 编译生成的nginx二进制文件会在nginx源码的objs目录下

  5. 拷贝objs/nginx到现有nginx的sbin目录下,覆盖原有二进制

  6. 重新加载nginx,加载新的模块

  7. 用nginx -V 确认模块加载成功

这种方式可以避免重复编译其他模块以及完全重新安装配置。只需要替换新增模块的二进制文件即可轻松实现模块热加载。

=============================================================

下载对应的数据库文件:
https://www.maxmind.com/en/accounts/902941/geoip/downloads
Nginx实践之使用MaxMind的GeoIP2实现处理不同国家的访问_第1张图片
下载好之后,测试下
mmdblookup --file /usr/local/GeoIP2/GeoLite2-Country.mmdb --ip 8.8.8.8
Nginx实践之使用MaxMind的GeoIP2实现处理不同国家的访问_第2张图片

验证GeoIP模块部署环境,我们需要针对nginx相关配置文件进行如下配置

1.在 nginx.conf 中进行如下几个关键部分配置。

load_module modules/ngx_http_geoip2_module.so;


user  deploy;
worker_processes  4;




events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
     
    geoip2 /usr/local/GeoIP2/GeoLite2-Country.mmdb {
    $geoip2_country_code country names en;
    $geoip2_data_country_code country iso_code;                  # CN
    $geoip2_data_country "default=中国" source=$remote_addr country names zh-CN;  # 中国
    $geoip2_data_country_continent continent names zh-CN;        # 亚洲

    }

    map  $geoip2_data_country_code $allowed_country {
        default no;
        CN yes;
    }

    
     # 定义新的日志格式geo_access,包含原有访问信息和GeoIP信息
  log_format geo_access '$remote_addr - $remote_user [$time_local] ' 
                    '"$request" $status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" $http_x_forwarded_for $request_time '
                    '$upstream_response_time $upstream_addr $http_host '
                    '$geoip2_data_country_code';
                    



    access_log  logs/access.log  geo_access;

变量要对应的上,server模块

    server {
        listen       80;
        listen 443 ssl;
        server_name  ban.test.com;
      
      #证书
        #ssl on;
        ssl_certificate /data/app/nginx/conf/ssl/server.pem;
        ssl_certificate_key /data/app/nginx/conf/ssl/server.key; 

        access_log  logs/host.access.log  geo_access;
        location / {
            if ($allowed_country = no) {
                return 403;
            }
}
}

日志打印:
Nginx实践之使用MaxMind的GeoIP2实现处理不同国家的访问_第3张图片
tips: 范例

geoip2 /etc/maxmind/GeoLite2-Country.mmdb {
  $geoip2_data_country_code country iso_code;
}

server {
  if ($geoip2_data_country_code = CN) {
    rewrite ^ http://cn.example.com$request_uri?;
  }

  if ($geoip2_data_country_code = US) { 
    rewrite ^ http://us.example.com$request_uri?;
  }

  location / {
    proxy_pass http://default.example.com; 
  }
}

server {
...
location / {
     #本地网段白名单
     if ($allow-ip = yes ) {
           set $allowed_country yes;
     }
     #国家地区白名单
     if ($allowed_country = no) {
            return 403;
     }
     #指定国家跳转到指定域名
     if ($geoip2_data_country_code = CN) {
         return 301 https://www.domain.cn$request_uri;
     }
  }
...
}


#允许本地网段访问
    geo $allow-ip{
        default no;
        192.168.10.0/24

港澳台地区:
map $geoip2_data_country_code $CN {
    CN yes;
    TW yes;
    HK yes;
    MO yes;
    default no;       
  }

达到效果了,国内访问200.国外访问403,city模块也可以使用,具体的暂时还未用到。
总结:要修改日志格式,以及nginx的版本和模块的版本不要相差太远

你可能感兴趣的:(系统管理,nginx,运维)