需用ngx_http_geoip2_module配合GeoLite2数据库识别国家代码,通过map指令定义目标国白名单,再在HTTP server中用return 301实现匹配国家的HTTPS强制跳转,非目标国用户保持原协议访问。

要实现基于 GeoIP 的国家维度 HTTPS 强制跳转,核心是:识别访问者所在国家 → 判断是否在目标国家列表中 → 对匹配国家用户自动 301 重定向到 HTTPS 版本(若当前为 HTTP)→ 同时确保非目标国家用户不受影响。Nginx 本身不内置 GeoIP 地理库,需依赖 ngx_http_geoip2_module(推荐)或旧版 ngx_http_geoip_module,并配合 MaxMind 的 GeoLite2 数据库。
准备 GeoIP2 数据库与模块支持
Nginx 默认不包含 GeoIP2 支持,需重新编译或使用已集成该模块的发行版(如 Ubuntu 的 nginx-extras)。推荐使用 geoip2 模块(支持 GeoLite2 格式,更新及时、精度高):
- 下载 GeoLite2 Country 数据库(免费版):https://www.php.cn/link/c4620e8a4aaa1f62e739608c2a866f9f,解压后获取
GeoLite2-Country.mmdb - 将
.mmdb文件放入服务器目录(如/usr/share/GeoIP/GeoLite2-Country.mmdb) - 确认 Nginx 已加载
ngx_http_geoip2_module(执行nginx -V 2>&1 | grep -o with-http-geoip2-module,有输出即支持)
配置 GeoIP2 变量映射国家代码
在 http 块中加载数据库并定义变量,用于后续条件判断:
http {
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
$geoip2_data_country_code source=$remote_addr country iso_code;
# 可选:记录国家名便于调试
# $geoip2_data_country_name country names en;
}
}该配置将客户端真实 IP($remote_addr)对应的 ISO 国家码(如 CN、US、JP)存入变量 $geoip2_data_country_code。注意:若使用 CDN 或反向代理,需用 $http_x_forwarded_for 并确保可信代理头已设置 real_ip 指令。
按国家条件强制跳转 HTTPS
在对应 server 块(监听 HTTP 的 80 端口)中,使用 map 构建白名单,并结合 return 301 实现精准跳转:
map $geoip2_data_country_code $should_force_https {
default 0;
CN 1; # 中国用户强制 HTTPS
KR 1; # 韩国用户也强制
JP 1; # 日本用户同理
}
<p>server {
listen 80;
server_name example.com;</p><pre class="brush:php;toolbar:false;"># 若国家匹配且当前协议为 HTTP,则 301 跳转到 HTTPS
if ($should_force_https = 1) {
return 301 https://$server_name$request_uri;
}
# 其他逻辑(如静态资源服务、默认响应等)
root /var/www/html;
index index.html;}
说明:
• 使用 map 而非多个 if 是更高效、更安全的做法(避免重复解析);
• $server_name 保证跳转域名与请求一致;
• $request_uri 保留原始路径和查询参数;
• 不匹配国家的请求(如 US、DE)会继续走 HTTP 流程,不受干扰。
HTTPS server 块保持独立且正常工作
确保已有 HTTPS server 正常响应,无需额外 GeoIP 判断(跳转由 HTTP server 完成):
server {
listen 443 ssl http2;
server_name example.com;
<pre class="brush:php;toolbar:false;">ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
root /var/www/html;
index index.html;
# 其他 SSL 优化、HSTS 等可在此添加}
注意:若需对 HTTPS 请求也做国家差异化处理(如不同国家展示不同首页),可在该 server 内继续使用 $geoip2_data_country_code 变量,配合 try_files 或 rewrite 实现。


















