NGINX 处理不同地区或国家、ASN 的访问

发布于 2024-07-10  412 次阅读


以 Debian + 宝塔(aaPanel)为例。

背景

最近搞了一个 Galgame 记录站,但是考虑到不同地区的法律问题,需要针对受限地区返回 40x 等状态码阻止这些地区的用户访问。比如日本地区正常访问,欧美地区返回 403。

方法一:借助 CDN

收费的就不说了,以 Cloudflare 为例,设定位置位于「站点配置」-->「安全性」-->「WAF」-->「自定义规则」,具体参考下图。

点击「创建规则」,然后参考下图根据自己的实际需求设置即可。

这个方法呢,有一个好处,就是地区判断相对更准确,毕竟 CDN 公司有专人负责维护 IP 库。但是相对的也有坏处,这个主要针对中国大陆地区来说的,一是免费的速度慢,影响访问体验,二是收费的需要实名备案等一系列手续,说不定一套流程下来站点都没法上线。

方法二:借助 GeoIP 类模块本地判断

这里推荐使用 GeoIP2 模块,因为使用的是 mmdb 格式的数据库,与 Clash 使用的为同一文件,获取方便且相对准确。

①安装 GeoIP2 的依赖

使用命令 apt install libmaxminddb-dev 安装。

②编译安装 NGINX

打开宝塔面板依次进入「应用商店」-->「NGINX」-->「安装」-->「编译安装」-->「添加自定义模块」,具体参考下图。

名称的描述就根据自己的需要去填写了,「模块参数」填写 --add-module=/www/server/nginx/src/ngx_http_geoip2_module ,「前置脚本」填写 git clone https://github.com/leev/ngx_http_geoip2_module.git ,具体参考下图。

设定完毕后依次点击「确认/提交」,然后等待编译安装完成即可。

③下载 mmdb 格式数据库

这里推荐:
Loyalsoldier 版本(包含 ASN 版本)
Hackl0us 版本(无 ASN 版本)
上面两个根据自己喜好下载就行,注意是 .mmdb 文件,不要下错了,下载后放到 NGINX 有读取权限的目录。

④配置使用 NGINX

首先,在 NGINX 的主配置文件的 http{} 部分加入以下配置(具体根据自己实际情况调整)

//地区或国家
http{
  geoip2 /www/server/nginx/geoip/Country.mmdb {
    $geoip2_country_code country iso_code;
  }
  map $geoip2_country_code $is_jp_country {
    default no;
    JP yes;
  }
}

//ASN
http{
  geoip2 /www/wwwroot/nginx/geoip/GeoLite2-ASN.mmdb {
    $geoip2_asn_code autonomous_system_number;
  }
  map $geoip2_asn_code $is_host_asn {
    default 0;
    ~^(6666|8888)$ 1;
  }
}

然后在需要区分地区或国家、ASN 的站点添加以下配置(具体根据自己实际情况调整)

//地区或国家
location / {
  if ($is_jp_country = yes) {
    return 403;
  }
}

//ASN
location / {
  if ($is_host_asn) {
    return 403;
  }
}

⑤补充说明

这个方法优点就不说了,缺点倒是很明显,需要自己维护,但是解决倒也简单,写个更新脚本扔 cron 就行,毕竟就是单纯地下载替换文件,也没啥技术含量。