我有一个通过 nginx 访问的服务,我希望仅将发布请求列入白名单。我在 nginx 配置文件中写入了以下内容:
location / {
if ( $request_method ~ ^(POST|PUT)$ ) {
allow 127.0.0.1;
}
if ( $request_method !~ ^(GET|POST|PUT|HEAD)$ ) {
return 405;
}
}
这个配置给了我以下错误-
nginx: [emerg] "allow" directive is not allowed here
另一方面,如果我if
像这样将允许指令写出块外,它就可以起作用。
location / {
allow 127.0.0.1;
if ( $request_method !~ ^(GET|POST|PUT|HEAD)$ ) {
return 405;
}
}
我认为这意味着我不能在块allow
中使用该指令if
。我在这里做错了吗?如果没有,有没有解决方法来实现这一点?
答案1
http {
geo $allowed_post_put {
default 0;
127.0.0.1 1;
::1 1;
}
map $request_method:$allowed_post_put $return_405 {
"POST:0" 1;
"PUT:0" 1;
}
}
location / {
if ( $return_405 = 1 ) {
return 405;
}
}
http://nginx.org/en/docs/http/ngx_http_geo_module.html- geo 模块允许根据客户端 IP 地址创建变量。
http://nginx.org/en/docs/http/ngx_http_map_module.html- map 模块创建的变量的值取决于其他变量的值。
if
rewrite 模块中的指令不允许复杂的逻辑表达式,只允许单个变量比较。因此我们使用 map 模块来创建依赖于客户端 IP 和请求方法的变量。
更新型多巴胺:在生产中,与 geo/map/if hack 类似的配置对我来说工作得很好。