由于if
nginx 中语句的工作方式(没有嵌套,没有多重条件)我无法找到将这两个功能结合起来的方法:
- 使用 nginx地理模块我有一个允许的 IP 列表
- 在我的文件系统上,如果我
touch appname
在某个目录中,应用程序会自动进入 503 维护模式。
这是我想要做的,但是 nginx 不允许:
location / {
if (-f /var/www/maintmode/appname && $allowed_ip = no) {
return 503;
}
try_files $uri;
}
如果上述操作在 nginx 中可行,则 Geo 模块中允许的 ip 列表中的任何人都可以绕过 503 并正常使用站点。然后,当验证应用程序rm appname
从 maint 目录运行后,503 维护模式结束。
这种方法的好处是touch
通过单个文件启用/禁用维护模式,而无需修改conf和重新加载nginx。
关于如何让这样的事情发挥作用,有什么想法吗?
答案1
如果你已经在使用 geo 你应该有类似这样的内容:
geo $client {
default not_allowed;
10.0.0.0/8 allowed;
}
因此,/var/www/maintmode/appname
您可以使用:
location / {
if (-f /var/www/maintmode/$client) {
return 503;
}
try_files $uri $uri/;
}
如果文件/var/www/maintmode/not_allowed
存在,则页面进入维护模式,但允许列表中的 IP 地址除外。
答案2
因此,感谢 HD 提供的提示,下面是我解决这个问题的方法:
利用 Geo 文档中的这一事实:当未指定默认值时,默认值将为空字符串。
geo $allowed_client {
10.0.0.0/8 allowed;
}
server {
...
set $appname app1;
location / {
$maintmode "${appname}${allowed_client}"
if (-f /var/www/maintmode/$maintmode) {
return 503;
}
try_files $uri $uri/;
}
}
所以我仍然可以touch app1
在维护目录中关闭特定的应用程序,因为如果我们有一个有效的 IP $maintmode = app1allowed
,它将跳过 503。所有其他 IP 都将$maintmode = app1
落入 503。谢谢 HD!