关于nginx的keep-alive配置的安全性分析

基本概念

最近关注了一下nginx的keep-alive配置,其实看看这块对性能和502 Bad Request的影响。 简单来说,keep-alive主要涉及出入口两块配置,包含三个参数(这个模型基本是通用的):

两块配置是外围调进来的配置、调用出去(upstream)的配置。 三个参数是保留多少长连接(keepalive,针对upstream)、长连接的超时时间(keepalive_timeout)、长连接的最多处理请求数(keepalive_requests)。

关于参数的详细说明,可以参考nginx的官方文档. ngx_http_core_modulengx_http_upstream_module

默认参数值

对于nginx/nginx-ingress来说,这些参数的默认值如下。

对于调用进来的情况:

  • keepalive_timeout: 通过keep-alive参数设置(注意这是设置的keepalive_timeout),表示超时时间,默认75s,我们项目目前设置300s
  • keepalive_requests: 通过keep-alive-requests参数设置,表示最多处理请求数,默认100

对于调用出去的情况:

  • keepalive:通过upstream-keepalive-connections参数设置,表示和upstream保持多少个长连接,默认32
  • keepalive_timeout:通过upstream-keepalive-timeout参数设置,表示超时时间,默认60s
  • keepalive_requests:通过upstream-keepalive-requests参数设置,表示最多处理请求数,默认100

备注:nginx-ingress官网显示keepalive默认320、keepalive_requests默认10000。 是因为后来进行了默认值调整 而我们用的版本是之前的,没有这个修改。

对于tomcat来说,这些参数的默认值如下。具体见tomcat官方文档中的参数配置

  • keepAliveTimeout 默认60s
  • maxKeepAliveRequests 默认100个请求

keep-alive的安全性

这里的安全性不是指安全漏洞,而是说如何避免向一个已关闭的连接发送请求,从而造成502的问题。

下面这个两个文件已经说得比较详细了,可以参考一下。

总体来说,要求对于A调用B的情况:

  • A的idle超时(调用出去)要少于B的idle超时(调用进来)
  • A的最大请求数(调用出去)要少于B的最大请求数(调用进来)

通俗点,举个例子:

如果场景是nginx -> tomcat的情况,如果tomcat保持默认,那么nginx的idle超时要小于60s,最大请求数要小于100。
如果场景是nginx -> ingress -> tomcat的情况,需要确保两块连接都符合上述要求。

按照当前的配置,不少配置还是存在隐患的。

无论是tomcat对接ingress还是nginx-ingress,默认值都可能有问题,需要把调出的超时和最大请求数稍微调小。
还有类似的插件,例如nginx_upstream_check_module有个类似的参数check_keepalive_requests,默认是1,也是要注意配套的,否则可能有探测失败的情况。