GEOIP2.jpg

I. 主理人序

2019年时,还是有GEOIP的;后来升级到了GEOIP2;利用NGINX的if特性,以及GEOIP2模块和GEOIP免费数据库(GeoLite2),判定来访用户国别,自动切换网站根目录;即可实现A/B站玩法;

用来绕过备案审查倒是不错的办法,中国用户访问是一个样,老外访问是一个样;博主最初的想法也只是想允许特定区域的IP访问其他根目录,而不对 Google Bot展示,后来增加了 User-Agent 的判定,方便很多,也限制了部分初学者访问;

II. 套了CDN需要获取用户真实IP

III. 下载GEOIP2数据库

参阅:GEOIP2(GeoLite2免费地理位置数据)数据库下载与自动更新

IV. 为NGINX安装GEOIP2模块(必要)

GEOIP2模块项目页https://github.com/leev/ngx_http_geoip2_module
源码下载发布页https://github.com/leev/ngx_http_geoip2_module/releases

下载并解压;

root@localhost:~/lnmp1.5# wget https://github.com/leev/ngx_http_geoip2_module/archive/refs/tags/3.3.tar.gz
root@localhost:~/lnmp1.5# tar -zxvf 3.3.tar.gz
root@localhost:~/lnmp1.5# cd ngx_http_geoip2_module-3.3
root@localhost:~/lnmp1.5/ngx_http_geoip2_module-3.3# tree
.
├── LICENSE
├── README.md
├── config
├── ngx_http_geoip2_module.c
└── ngx_stream_geoip2_module.c

模块加装安装可参阅:从 Nginx 迁移至 OpenResty(升级、源码编译、加装额外模块)

GEOIP2模块安装官方示例如下:(假设你的是nginx原版)

wget http://nginx.org/download/nginx-VERSION.tar.gz
tar zxvf nginx-VERSION.tar.gz
cd nginx-VERSION
./configure --add-dynamic-module=~/lnmp1.5/ngx_http_geoip2_module-3.3
make
make install

V. NGINX配置文件(HTTP块引用GEOIP2数据库)

配置NGINX配置文件:找到你的 域名配置文件如 /usr/local/nginx/conf/vhost/limbopro.com.conf ;在 http块 内添加(配置文件最顶部,server块上方;),其中数据库所在路径请以实际路径为准;


http {

## GEOIP2 国家

    geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
    $geoip2_Country_code country iso_code; #设置变量 获取国别代码赋予到变量
    $geoip2_Country_name country names en; #设置变量 获取国别名称赋予到变量
    }

## GEOIP2 城市

    geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb {
    $geoip2_city_code country iso_code; #设置变量 获取城市代码 赋予到变量
    $geoip2_city_name country names en; #设置变量 获取城市名称 赋予到变量
    }

## GEOIP2 国家 自治系統
    geoip2 /usr/share/GeoIP/GeoLite2-ASN.mmdb {
    $geoip2_asn_name autonomous_system_organization; #设置变量 获取ASN名称
    $geoip2_asn_code autonomous_system_number; #设置变量 获取ASN代码
    }

## GEOIP2 国家禁止
    map $geoip2_city_code $is_cn_country {
    default yes; #默认都允许,RU不允许(俄罗斯联邦)
    RU no;
    }

server { # simple reverse-proxy
    listen       80;
    server_name  domain2.com www.domain2.com;
    access_log   logs/domain2.access.log  main;

    # serve static files
    location ~ ^/(images|javascript|js|css|flash|media|static)/  {
      root    /var/www/virtual/big.server.com/htdocs;
      expires 30d;
    }

    # pass requests for dynamic content to rails/turbogears/zope, et al
    location / {
      proxy_pass      http://127.0.0.1:8080;
    }
  }
}

找到你的 域名配置文件;在 server块 内添加,找到你的网站根目录 root /path/to/root(参考如下) ,其中数据库路径请以实际路径为准;

map 指令的用法参阅:Module ngx_http_map_module
# 以下示例为当用户的客户端 $http_user_agent 值匹配到 `Opera Mini` 时,则 $mobile 的值被赋予为 1;
# $http_user_agent 为nginx 内置变量;返回当前发请求用户 的 User-Agent 值;
# ~ 为区分大小写的正则匹配
# ~* 不区分大小写的正则匹配
# 更多匹配示例搜索 location 正则匹配

map $http_user_agent $mobile {
    default       0;
    "~Opera Mini" 1;
}

VI. A/B站玩法

server
{
...

add_header CITY-CODE $geoip2_city_code;
add_header CITY-NAMES $geoip2_city_name;
add_header autonomous_system_organization $geoip2_asn_name;
add_header autonomous_system_number $geoip2_asn_code;

## GEOIP2 判定与网站根目录切换
set $rootpath /home/wwwroot/typecho/; # 正常网站的网站根目录
if ($is_cn_country = no) {
set $rootpath /home/wwwroot/bak/; # 如果你的IP为俄罗斯联邦IP则你会访问到非正常网站根目录

...
}

VII. 禁止某个国家用户访问

如果你不想给俄罗斯人访问站点:

if ($geoip2_Country_code = RU){
return 403;
}

更多国家:

if ($geoip2_Country_code = (RU|US|UK)){
return 403;
}

VIII. 根据国别对用户进行限速

请求频率限制官方配置及参数说明参阅:Module ngx_http_limit_req_module连接数限制官方配置及参数说明参阅:Module ngx_http_limit_conn_module

何为请求频率:CTRL+F5 知道吗?HTTP请求;GET、POST、HEAD... 参阅 HTTP 请求方法

何为连接数(连接数量):即在数据传输中建立的TCP连接的数量,在下载大文件(静态资源:如ZIP/MP3)时则为长连接,会有较长耗时;如果此时下载未完成,则占用一个连接数;如下示例中我们设置的是 limit_conn one 1; 比较适用于网络较好的环境,图片资源等都是毫秒级别加载;一般在生产环境中我们会设为一个较大的数值;

我们先配置 http 块;

##连接数限制
limit_conn_zone $binary_remote_addr zone=one:50m; #以客户端请求IP为测量变量
limit_conn_log_level notice; #日志级别 notice
limit_conn_status 503; #超出返回错误代码 503;可设置为任意 HTTP 代码

##刷新频率限制
limit_req_zone  $binary_remote_addr zone=two:50m rate=1r/s; #请求频率1个/每秒
limit_req_log_level notice; #日志级别 notice
limit_req_status 503; #超出返回错误代码 503;可设置为任意 HTTP 代码

注意 zone=one以及zone=two;将会在 server 块配置时会引用,是用于存储键值

在 server 或 location 块进行配置 或 if in location 生效:配置如下

## GEOIP2 静态资源下载限速
location ~ .*\.(epub|zip|woff2|mp4|mp3|pdf|mobi|epub|azw3)?$
{

set $max_rate 512k; #赋值最大下载速度 512K/s
if ($geoip2_Country_code ~* ^(HK|US|KR|JP|TW|SG|MO)$){ #如果不是在列的各国IP则
set $max_rate 128k; #重新对速率进行赋值
}

limit_req zone=two burst=1; #缓冲1个请求 
limit_conn one 1; #1个连接数
limit_rate_after 1m; #在下载达到1兆时开始限速
limit_rate "$max_rate"; #对限速速度进行赋值
access_log off;

} 

IX. 根据 User-Agent 切换网站根目录

在 server 块内 if 块进行配置

## GEOIP2 判定与网站根目录切换
set $rootpath /home/wwwroot/typecho/;
if ($is_cn_country = no) {
set $rootpath /home/wwwroot/bak/;
}

if ($http_user_agent ~* "limbopro" ) {
set $rootpath /home/wwwroot/bak/;
}

X. 附注

1.Nginx Geoip2 处理不同国家 (或城市) 的访问
2.Nginx中if语句中的判断条件
3.ngx_http_geoip2_module 源码;
4.Restricting Access by Geographical Location

最后修改:2022 年 11 月 29 日 12 : 25 PM