NGINX 自定义 403 错误页面遇到的坑

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


背景

起因是我在针对部分地区返回 403 状态码的时候遇到的,直接返回 NGINX 的 403 页面别人也不知道啥情况,总得在 403 页面给别人一个解释。

以下内容以我自己的实际需求为例,主要是自己遇到的问题以及对应的解决方式,并非通用的解决方式,涉及 NGINX if 判断、对 403 地区内特殊设备放行、WordPress 伪静态。

自定义页面

先在 NGINX 的主配置 http{} 部分添加以下配置:

http {
  fastcgi_intercept_errors on;
}

然后在 NGINX 的站点配置中添加以下配置:

error_page 403 /403.html;

# Is CN Area
location /
{
  set $areaflag 0;
  if ($is_cn_country = yes) {
    set $areaflag "${areaflag}1";
  }
  if ($http_user_agent ~ ^((?!whitelist).)*$) {
    set $areaflag "${areaflag}2";
  }
  if ($areaflag = "012") {
    return 403;
  }
}

然后发现添加后无法保存😅。行呗,和 NGINX 的伪静态撞了,那就修改伪静态和原伪静态合并一下:

location /
{
  set $areaflag 0;
  if ($is_cn_country = yes) {
    set $areaflag "${areaflag}1";
  }
  if ($http_user_agent ~ ^((?!whitelist).)*$) {
    set $areaflag "${areaflag}2";
  }
  if ($areaflag = "012") {
    return 403;
  }
  if ($areaflag = "012") {
    try_files $uri $uri/ /index.php?$args;
  }
}
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

保存成功😁,Firefox 启动!

然后伪静态失效了、同时自定义的 403 页面也没生效😡。

那么为什么呢,因为 NGINX 的 if 不是真 if

那还能咋办,继续改呗,也就个人博客能这么玩

修改站点配置文件,添加以下配置:

error_page 403 /403.html;

# Is CN Area
set $areaflag 0;
if ($is_cn_country = yes) {
  set $areaflag "${areaflag}1";
}
if ($http_user_agent ~ ^((?!whitelist).)*$) {
  set $areaflag "${areaflag}2";
}

这里由于 if 的问题,在站点配置里,只做地区与白名单判断并将结果写入变量,实际分流通过伪静态执行:

location /
{
  try_files $uri $uri/ /index.php?$args;
  if ($areaflag = "012") {
    return 403;
  }
}
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

保存成功😁,Firefox 启动!

这里伪静态正常了,WordPress 能正常访问了,特殊地区也能正常 403 了,特殊地区内的白名单设备也能正常访问网页了,但是自定义的 403 页面还是没生效😡。

经过多方查找资料,推测可能为自定义的页面也被 403 了,所以间接导致自定义错误页面没生效,那继续改伪静态

location /
{
  try_files $uri $uri/ /index.php?$args;
  if ($areaflag = "012") {
    return 403;
  }
  location /403.html {   
    allow all;
  }
}
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

保存成功😁,Firefox 启动!

好了,现在所有都正常了,伪静态正常,WordPress 能正常访问,特殊地区也能正常 403,特殊地区内的白名单设备能正常访问网页,自定义的 403 页面能伴随 403 状态码同时生效。