NGINX:Cloudflare的IP地理定位和 "嵌套 "的条件

542 阅读3分钟

在Cloudflare提供的其他功能中,它可以添加一个带有国家值的特殊标题,即访问者来自哪里。

作为一个乌克兰人,我想禁止所有来自俄罗斯的访问者,但是。

  1. 将所有来自俄罗斯IP的访问者重定向到另一个网站域名 -russki-voenny-korabl-idi-nahuy.com
  2. 在此期间,我想过滤请求,让来自Yandex搜索系统的请求不受影响,所以它将继续在其搜索结果中返回RTFM博客的俄罗斯听觉。

Cloudflare IP地理定位和NGINX

这里最简单的部分是通过Cloudflare的头来配置过滤器。

首先,启用CF-IPCountry头。

进入你的Cloudflare仪表板>网络,激活该选项,即使在其基本计划中也是免费的。

然后,在你的NGINX的虚拟主机配置中,在server {} 块中使用 proxy_set_header来创建一个变量$http_cf_ipcountry

...
proxy_set_header CF-IPCountry $http_cf_ipcountry;
...

NGINX和 "嵌套" if

而第二部分则更有趣。

因此,我们需要检查两个条件。

  1. 访客是否来自俄罗斯
  2. 是普通访客,还是Yandex搜索机器人?

在NGINX中,我们不能使用真正的嵌套条件与if ,例如。

...
    if ($country_allowed = no) {
        if ($http_user_agent !~* (YandexBot) ) {
            rewrite ^ https://russki-voenny-korabl-idi-nahuy.com break;
        }
    }
...

但我们在这里可以做的是,使用变量和专用的if

让我们检查一下。

启用一个VPN,并检查你现在在哪里,例如使用www.iplocation.net服务。

GB- 大不列颠。

nginx.conf ,你也可以为access_log ,启用一个扩展的日志格式,以看到更多的信息,并检查$http_cf_ipcountry 和一个新的变量$visitor 的值,我们将在下面添加。

...
    log_format  main_ext '$time_local client: $remote_addr fwd_for: $http_x_forwarded_for '
                         'status: $status user_agent: "$http_user_agent" '
                         'server: "$server_name" country: $http_cf_ipcountry visitor: $visitor';
...

接下来,创建条件并运行测试。测试成功后,我们将把条件改为RU地区和 "如果不等于 "Yandex (见服务器日志中的Yandex机器人)。

所以。

  1. CF-IPCountry 头部创建一个名为$http_cf_ipcountry 的变量。
  2. 在第一个if条件中,检查$http_cf_ipcountry 的值:现在,检查GB,并创建一个变量$visitor ,它将保持一个值rus,如果区域==CA
  3. 在第二个if 条件中,检查User-Agent ,如果它==Firefox,则在$visitor 变量中添加另一个值--"重定向"。
  4. 在第三个if 条件中,检查$visitor 变量的值,如果它等于rusredirect字符串,那么做一个rewriterusski-voenny-korabl-idi-nahuy.com域名。

另外,你可以将 rewrite_log参数设置为on,并将error_log 设置为通知级别,这样你就可以检查重写是否按预期工作。

这就是我在测试期间的配置情况。

...
    rewrite_log on;
    access_log /var/log/nginx/rtfm.co.ua-access-ext.log main_ext;
    error_log /var/log/nginx/rtfm.co.ua-error.log notice;
...
    proxy_set_header CF-IPCountry $http_cf_ipcountry;
    
    if ($http_cf_ipcountry = GB) {
        set $visitor rus;
    }
    
    if ($http_user_agent ~* (Firefox) ) {
        set $visitor "${visitor}redirect";
    }
    
    if ($visitor = "rusredirect") {
        rewrite ^ https://russki-voenny-korabl-idi-nahuy.com break;
    }
...

检查配置文件并重新加载nginx

root@rtfm-do-production-d10:~# nginx -t

nginx:配置文件/etc/nginx/nginx.conf的语法是确定的。

nginx:配置文件/etc/nginx/nginx.conf测试成功。

root@rtfm-do-production-d10:~# systemctl reload nginx

用Firefox浏览器进入博客。

access_log。

root@rtfm-do-production-d10:~# tail -f /var/log/nginx/rtfm.co.ua-access-ext.log | grep GB

02/Apr/2022:06:22:29 +0000 client: 162.158.91.190 fwd_for: 146.70.46.20,146.70.46.20 status: 302 user_agent: "Mozilla/5.0 (X11; Linux x86_64; rv:98.0) Gecko/20100101 Firefox/98.0" server: "rtfm.co.ua" country: GB visitor: rusredirect

error_log。

root@rtfm-do-production-d10:~# tail -f /var/log/nginx/rtfm.co.ua-error.log | grep 'rewritten redirect' 。

2022/04/02 06:22:29 [notice] 21018#21018: *33766595重写重定向:"russki-voenny-korabl-idi-nahuy.com", client: 162.158.91.190, server: rtfm.co.ua, request: "GET / HTTP/1.1", host: "rtfm.co.ua"

user_agent: "Firefox" ,得到了一个来自country: GB 的访问者,并得到了一个redirect: "https://russki-voenny-korabl-idi-nahuy.com" - "It works!" (c)。

现在,把条件改为最终版本,用RU地区和YandexforUser-Agent

  • 设置区域。if ($http_cf_ipcountry = RU)
  • 并将~* (Firefox) 改为不等式,即!~* (Yandex) -if ($http_user_agent !~* (Yandex) )
...
    proxy_set_header CF-IPCountry $http_cf_ipcountry;
    
    if ($http_cf_ipcountry = RU) {
        set $visitor rus;
    }

    if ($http_user_agent !~* (Yandex) ) {
        set $visitor "${visitor}redirect";
    }

    if ($visitor = "rusredirect") {
        rewrite_log on;
        rewrite ^ https://russki-voenny-korabl-idi-nahuy.com break;
    }
...

完成了。

类似的帖子

The postNGINX: IP Geolocation by Cloudflare and "nested" if conditionsfirst appeared onRTFM: Linux, DevOps, and system administration.