nginx编译支持ngx_http_geoip2_module

3 阅读3分钟

使用nginx做负载均衡时,有时候我们会需要根据不同国家或者地区进行处理。
nginx官方自带ngx_http_geoip的支持,我们可以通过Linux发行版的包管理来快速安装,但是现阶段ngx_http_geoip已不再更新和获取支持,其数据库可能过期,因此使用ngx_http_geoip2是一个更好的选择。

对比

下面是 ngx_http_geoipngx_http_geoip2的对比

特性ngx_http_geoip(旧版)ngx_http_geoip2 (新版)
数据库格式使用MaxMind 的 .dat (GeoIP Legacy) 格式使用 MaxMind 的 .mmdb (GeoIP2) 格式
数据库支持仅支持已停止更新的GeoIP Legacy 数据库支持当前维护的 GeoLite2/GeoIP2 数据库
配置语法较简单但功能有限更灵活,支持自定义变量名
数据精度相对较低更高精度的地理位置数据
维护状态已过时,不推荐新项目使用活跃维护,推荐使用

目前想使用ngx_http_geoip2只能通过编译nginxngx_http_geoip2_ngx_module来使用,下面介绍详细编译步骤。

获取源码

image.png

  • 获取geolite2数据库: 前往MaxMind官方获取或者使用github上他人共享的数据库

环境部署

本文以ubuntu22.04操作系统为例,实际编译时应该请根据发行版特定软件包名来获取gcc编译器和指定库。

  • 安装gcc、make、pcre、zlib及ssl,这些都是nginx编译时需要的工具和库
apt update && apt install gcc make libpcre3-dev zlib1g-dev libssl-dev -y
  • 安装maxmind库及其ip数据库
apt install software-properties-common -y
add-apt-repository ppa:maxmind/ppa && apt update
apt install libmaxminddb0 libmaxminddb-dev mmdb-bin -y

编译

将源码解压后执行:

cd  /src/nginx-1.28.0
./configure \
    --prefix=/etc/nginx \
    --sbin-path=/usr/sbin/nginx \
    --modules-path=/usr/lib/nginx/modules \
    --conf-path=/etc/nginx/nginx.conf \
    --error-log-path=/var/log/nginx/error.log \
    --http-log-path=/var/log/nginx/access.log \
    --pid-path=/var/run/nginx.pid \
    --lock-path=/var/run/nginx.lock \
    --with-http_ssl_module \                 
    --with-http_v2_module \                  
    --with-http_realip_module \              
    --with-http_addition_module \            
    --with-http_sub_module \                 
    --with-http_gunzip_module \              
    --with-http_gzip_static_module \         
    --with-http_auth_request_module \        
    --with-http_random_index_module \        
    --with-http_secure_link_module \         
    --with-http_slice_module \               
    --with-http_stub_status_module \         
    --with-stream \                          
    --with-stream_ssl_module \               
    --with-stream_realip_module \            
    --with-threads \
    --with-file-aio \
    --with-http_ssl_module \                 
    --with-cc-opt='-O2 -g'  \
    --add-module=/src/ngx_http_geoip2_module-3.4    
make && make install
  • --add-module=/src/ngx_http_geoip2_module-3.4 替换为ngx_http_geoip2_module的实际目录。
  • 上面--with启用了nginx常用的模块,实际请根据自己的情况增删。

至此一个带有ngx_http_geoip2模块的nginx就编译好了

配置

下面介绍一个常用配置:

worker_processes  auto;

events {
    worker_connections  1024;
}

http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;
    # 这边配置geoip数据库
    geoip2 /etc/nginx/geoip/GeoLite2-Country.mmdb {
        $geoip2_country_code country iso_code;
    }
    
    # 这边映射国家值
    map $geoip2_country_code $is_cn {
        default 0;
        CN      1;
    }
    
    ...
    
    # 定义可信的代理服务器 IP 范围
    # 将 `172.20.0.0/16` 这个私有网络段标记为可信代理
    # 当请求来自这个 IP 段的服务器时,Nginx 会认为它是代理服务器
    geoip2_proxy 172.20.0.0/16;
    # 启用递归搜索真实客户端 IP
    # 在 `X-Forwarded-For` 头中从右向左搜索第一个不属于可信代理的 IP
    geoip2_proxy_recursive on;
    # 如果nginx部署在容器中或者经由其他反向代理服务器代理,上面两个选项必须配置,或则无法获取客户端ip

    server {
        listen 80;
        # 禁止中国地区用户访问
        if ($is_cn = 0) {
            return 403 ;
        }

        location / {
            ...
        }
    }
}

附录

以上编译步骤我也编写了Dockerfile方便大家直接使用:
github.com/kezhengjie/…