使用nginx做负载均衡时,有时候我们会需要根据不同国家或者地区进行处理。
nginx官方自带ngx_http_geoip的支持,我们可以通过Linux发行版的包管理来快速安装,但是现阶段ngx_http_geoip已不再更新和获取支持,其数据库可能过期,因此使用ngx_http_geoip2是一个更好的选择。
对比
下面是 ngx_http_geoip和ngx_http_geoip2的对比
| 特性 | ngx_http_geoip(旧版) | ngx_http_geoip2 (新版) |
|---|---|---|
| 数据库格式 | 使用MaxMind 的 .dat (GeoIP Legacy) 格式 | 使用 MaxMind 的 .mmdb (GeoIP2) 格式 |
| 数据库支持 | 仅支持已停止更新的GeoIP Legacy 数据库 | 支持当前维护的 GeoLite2/GeoIP2 数据库 |
| 配置语法 | 较简单但功能有限 | 更灵活,支持自定义变量名 |
| 数据精度 | 相对较低 | 更高精度的地理位置数据 |
| 维护状态 | 已过时,不推荐新项目使用 | 活跃维护,推荐使用 |
目前想使用ngx_http_geoip2只能通过编译nginx和ngx_http_geoip2_ngx_module来使用,下面介绍详细编译步骤。
获取源码
-
前往nginx官网 nginx.org/en/download… 获取nginx源码包,本文以
stable版的1.28.0为例: -
前往github获取ngx_http_geoip2源码github.com/leev/ngx_ht…:
- 获取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/…