为 Nginx Ingress 中的特定位置设置 limit_req
Set limit_req for specific location in Nginx Ingress
我正在尝试为 Kubernetes ingress-nginx 中的特定路径设置速率限制选项 limit_req
以防止 brute-forcing 身份验证。
我已经使用 ConfigMap 定义了 limit_req_zone
:
http-snippet: |
limit_req_zone $the_real_ip zone=authentication_ratelimit:10m rate=1r/s;
接下来,我将使用注释添加自定义位置块:
nginx.ingress.kubernetes.io/configuration-snippet: |
location ~* "^/authenticate$" {
limit_req zone=authentication_ratelimit nodelay;
more_set_headers "x-test: matched";
}
这会产生 nginx.conf:
server {
# - - 8< - -
location / {
# - - 8< - -
location ~* "^/authenticate$" {
limit_req zone=authentication_ratelimit nodelay;
more_set_headers "x-test: matched";
}
proxy_pass http://upstream_balancer;
proxy_redirect off;
}
结果是 /authenticate
总是 returns HTTP 503(x-test header)。来自入口访问日志的消息:
<ip> - [<ip>] - - [04/Jan/2019:15:22:07 +0000] "POST /authenticate HTTP/2.0" 503 197 "-" "curl/7.54.0" 172 0.000 [-] - - - - 1a63c9825c9795be1378b2547e29992d
我怀疑这可能是因为嵌套位置块和 proxy_pass
之间存在冲突(但这只是一个大胆的猜测)。
我还尝试过哪些其他选项?
- 使用
server-snippet
注解而不是configuration-snippet
- /authenticate
returns 404因为proxy_pass
没有配置
- 使用
nginx.ingress.kubernetes.io/limit-rpm
注释 - 强制对整个应用程序进行速率限制,这不是我想要的。
问题是为什么自定义位置块以 503 响应?我该如何调试呢?增加 nginx 日志记录级别会提供有关 503 的更多详细信息吗?
或者更一般的问题:我可以在 ingress-nginx 中注入自定义位置块吗?
这可以通过使用地图和 Requests with an empty key value are not accounted.
这个事实来完成
http-snippets: |
map $uri $with_limit_req {
default 0;
"~*^/authenticate$" 1;
}
map $with_limit_req $auth_limit_req_key {
default '';
'1' $binary_remote_addr; # the limit key
}
limit_req_zone $auth_limit_req_key zone=authentication_ratelimit:10m rate=1r/s;
并使用注释添加自定义位置块:
nginx.ingress.kubernetes.io/configuration-snippet: |
limit_req zone=authentication_ratelimit nodelay;
或者如果你使用来自 nginxinc 的入口
nginx.org/location-snippets:
limit_req zone=authentication_ratelimit nodelay;
在这种情况下,请检查是否需要在地图级别对请求进行速率限制处理。
我的意见:最好在应用级别限制请求,就像在入口级别设置速率限制一样,这取决于入口的数量 pods。
我正在尝试为 Kubernetes ingress-nginx 中的特定路径设置速率限制选项 limit_req
以防止 brute-forcing 身份验证。
我已经使用 ConfigMap 定义了 limit_req_zone
:
http-snippet: |
limit_req_zone $the_real_ip zone=authentication_ratelimit:10m rate=1r/s;
接下来,我将使用注释添加自定义位置块:
nginx.ingress.kubernetes.io/configuration-snippet: |
location ~* "^/authenticate$" {
limit_req zone=authentication_ratelimit nodelay;
more_set_headers "x-test: matched";
}
这会产生 nginx.conf:
server {
# - - 8< - -
location / {
# - - 8< - -
location ~* "^/authenticate$" {
limit_req zone=authentication_ratelimit nodelay;
more_set_headers "x-test: matched";
}
proxy_pass http://upstream_balancer;
proxy_redirect off;
}
结果是 /authenticate
总是 returns HTTP 503(x-test header)。来自入口访问日志的消息:
<ip> - [<ip>] - - [04/Jan/2019:15:22:07 +0000] "POST /authenticate HTTP/2.0" 503 197 "-" "curl/7.54.0" 172 0.000 [-] - - - - 1a63c9825c9795be1378b2547e29992d
我怀疑这可能是因为嵌套位置块和 proxy_pass
之间存在冲突(但这只是一个大胆的猜测)。
我还尝试过哪些其他选项?
- 使用
server-snippet
注解而不是configuration-snippet
-/authenticate
returns 404因为proxy_pass
没有配置 - 使用
nginx.ingress.kubernetes.io/limit-rpm
注释 - 强制对整个应用程序进行速率限制,这不是我想要的。
问题是为什么自定义位置块以 503 响应?我该如何调试呢?增加 nginx 日志记录级别会提供有关 503 的更多详细信息吗? 或者更一般的问题:我可以在 ingress-nginx 中注入自定义位置块吗?
这可以通过使用地图和 Requests with an empty key value are not accounted.
这个事实来完成http-snippets: |
map $uri $with_limit_req {
default 0;
"~*^/authenticate$" 1;
}
map $with_limit_req $auth_limit_req_key {
default '';
'1' $binary_remote_addr; # the limit key
}
limit_req_zone $auth_limit_req_key zone=authentication_ratelimit:10m rate=1r/s;
并使用注释添加自定义位置块:
nginx.ingress.kubernetes.io/configuration-snippet: |
limit_req zone=authentication_ratelimit nodelay;
或者如果你使用来自 nginxinc 的入口
nginx.org/location-snippets:
limit_req zone=authentication_ratelimit nodelay;
在这种情况下,请检查是否需要在地图级别对请求进行速率限制处理。
我的意见:最好在应用级别限制请求,就像在入口级别设置速率限制一样,这取决于入口的数量 pods。