2019 年 8 月,Netflix 发现多个资源耗尽攻击媒介,这些攻击媒介可用于对支持 HTTP/2 通信的服务器发起拒绝服务 (DoS) 攻击。Netflix 与 Google 和 CERT/CC 进行协调以向 Internet 社区披露该信息。在 NSX Advanced Load Balancer 中加入了 4 个新参数以解决这些安全问题。
有关 DoS 建议的更多信息,请参见 HTTP/2 拒绝服务建议。
常见漏洞和暴露
以下 8 个常见漏洞和暴露 (CVE) 与 HTTP/2 拒绝服务建议相关:
CVE-2019-9511:HTTP/2 数据滴漏
CVE-2019-9512:HTTP/2 Ping 泛洪
CVE-2019-9513:HTTP/2 资源循环
CVE-2019-9514:HTTP/2 重置泛洪
CVE-2019-9515:HTTP/2 设置泛洪
CVE-2019-9516:HTTP/2 0 长度标头泄漏
CVE-2019-9517:HTTP/2 内部数据缓冲
CVE-2019-9518:HTTP/2 空帧泛洪
解决 CVE 和暴露问题
已通过新的 HTTP-application-profile
参数和其他代码解决了上述 CVE 和其他问题。可以通过 NSX Advanced Load Balancer REST API 和 NSX Advanced Load Balancer CLI 访问这 4 个参数。
max_http2_control_frames_per_connection
客户端可以通过 HTTP/2 连接发送的最大控制帧数
用于检测 ping 泛洪 (CVE-2019-9512)、重置泛洪 (CVE-2019-9514)、设置泛洪 (CVE-2019-9515) 和资源循环问题 (CVE-2019-9513)
范围:0-10,000;默认值 = 1000
0 被解释为在客户端 HTTP/2 连接上具有不限数量的控制帧
max_http2_queued_frames_to_client_per_connection
在任何给定时间,可以排队等待通过客户端 HTTP/2 连接发送的最大帧数
用于检测数据滴漏 (CVE-2019-9511) 和内部数据缓冲 (CVE-2019-9517)
范围:0-10,000;默认值 = 10000 被解释为不限数量的排队帧
还包含来自 NGINX 的修复 nginx/nginx@a987f81
max_http2_empty_data_frames_per_connection
客户端 HTTP/2 连接上的最大空数据帧数
用于检测空数据帧泛洪 (CVE-2019-9518)
-
注:
对于空标头帧,我们的当前实施关闭连接并报告如下错误:HTTP2 帧大小错误:客户端发送的 HEADERS 帧具有空标头块 (HTTP2 Frame Size Error: Client sent HEADERS frame with empty header block)。
范围:0-10,000;默认值 = 10000 被解释为不限数量的空帧
max_http2_concurrent_streams_per_connection
客户端 HTTP/2 连接上的最大并发流数
用于控制一个 HTTP/2 连接可以在任何给定时间处理的并发流
范围 1-256;默认值 = 128
-
注:
该参数与任何上述 CVE 问题无关。
当前代码检测 0 长度标头泄漏 (CVE-2019-9516)。在检测到泄漏后,将关闭流,并且 NSX Advanced Load Balancer 报告以下错误:HTTP2 协议错误:客户端发送的标头名称的长度为零 (HTTP2 Protocol Error: Client sent zero length header name)。
max_http2_requests_per_connection
该值控制可以通过客户端 HTTP/2 连接发送的最大请求数。如果该值设置为 0,这意味着可以通过 HTTP/2 客户端连接发送不限数量的请求。
max_http2_header_field
该字段控制压缩的请求标头字段的最大大小(以字节为单位)。该限制同样适用于请求标头的名称和值。范围是 1-8192 字节。默认值为 4096 字节。
http2_initial_window_size
该字段控制 HTTP/2 流中的初始流控制的窗口大小。该字段的值范围是 64-32768 KB。该字段的默认值为 64 KB。
CLI 配置示例
[admin:th-controller-3]: > show applicationprofile applicationprofile-22 +----------------------------------------------------+---------------------------------------------------------+ | Field | Value | +----------------------------------------------------+---------------------------------------------------------+ | uuid | applicationprofile-8cd83b63-9ef8-4ce3-b498-2d173a09ed7c | | name | applicationprofile-22 | | type | APPLICATION_PROFILE_TYPE_HTTP | | http_profile | | | connection_multiplexing_enabled | True | | xff_enabled | False | | xff_alternate_name | X-Forwarded-For | | ssl_everywhere_enabled | False | | hsts_enabled | False | | hsts_max_age | 365 | | secure_cookie_enabled | False | | httponly_enabled | False | | http_to_https | False | | server_side_redirect_to_https | False | | x_forwarded_proto_enabled | False | | spdy_enabled | False | | spdy_fwd_proxy_mode | False | | post_accept_timeout | 30000 milliseconds | | client_header_timeout | 10000 milliseconds | | client_body_timeout | 30000 milliseconds | | keepalive_timeout | 30000 milliseconds | | client_max_header_size | 12 kb | | client_max_request_size | 48 kb | | client_max_body_size | 0 kb | | max_rps_unknown_uri | 0 | | max_rps_cip | 0 | | max_rps_uri | 0 | | max_rps_cip_uri | 0 | | ssl_client_certificate_mode | SSL_CLIENT_CERTIFICATE_NONE | | websockets_enabled | True | | max_rps_unknown_cip | 0 | | max_bad_rps_cip | 0 | | max_bad_rps_uri | 0 | | max_bad_rps_cip_uri | 0 | | keepalive_header | False | | use_app_keepalive_timeout | False | | allow_dots_in_header_name | False | | disable_keepalive_posts_msie6 | True | | enable_request_body_buffering | False | | enable_fire_and_forget | False | | max_response_headers_size | 48 kb | | http2_enabled | True | | respond_with_100_continue | True | | hsts_subdomains_enabled | True | | enable_request_body_metrics | False | | fwd_close_hdr_for_bound_connections | True | | max_keepalive_requests | 100 | | disable_sni_hostname_check | False | | max_http2_control_frames_per_connection | 1000 | | max_http2_queued_frames_to_client_per_connection | 1000 | | max_http2_empty_data_frames_per_connection | 1000 | | max_http2_concurrent_streams_per_connection | 128 | | reset_conn_http_on_ssl_port | False | | preserve_client_ip | False | | preserve_client_port | False | | tenant_ref | admin | +----------------------------------------------------+---------------------------------------------------------+ [admin:th-controller-3]: > [admin:th-controller-3]: applicationprofile> configure applicationprofile applicationprofile-22 [admin:th-controller-3]: applicationprofile> http_profile [admin:th-controller-3]: applicationprofile:http_profile> max_http2_control_frames_per_connection 2000 Overwriting the previously entered value for max_http2_control_frames_per_connection [admin:th-controller-3]: applicationprofile:http_profile> max_http2_queued_frames_to_client_per_connection 2000 Overwriting the previously entered value for max_http2_queued_frames_to_client_per_connection [admin:th-controller-3]: applicationprofile:http_profile> max_http2_empty_data_frames_per_connection 2000 Overwriting the previously entered value for max_http2_empty_data_frames_per_connection [admin:th-controller-3]: applicationprofile:http_profile> max_http2_concurrent_streams_per_connection 256 Overwriting the previously entered value for max_http2_concurrent_streams_per_connection [admin:th-controller-3]: applicationprofile:http_profile> save [admin:th-controller-3]: applicationprofile> save [admin:th-controller-3]: > show applicationprofile applicationprofile-22 +----------------------------------------------------+---------------------------------------------------------+ | Field | Value | +----------------------------------------------------+---------------------------------------------------------+ | uuid | applicationprofile-8cd83b63-9ef8-4ce3-b498-2d173a09ed7c | | name | applicationprofile-22 | | type | APPLICATION_PROFILE_TYPE_HTTP | | http_profile | | | connection_multiplexing_enabled | True | | xff_enabled | False | | xff_alternate_name | X-Forwarded-For | | ssl_everywhere_enabled | False | | hsts_enabled | False | | hsts_max_age | 365 | | secure_cookie_enabled | False | | httponly_enabled | False | | http_to_https | False | | server_side_redirect_to_https | False | | x_forwarded_proto_enabled | False | | spdy_enabled | False | | spdy_fwd_proxy_mode | False | | post_accept_timeout | 30000 milliseconds | | client_header_timeout | 10000 milliseconds | | client_body_timeout | 30000 milliseconds | | keepalive_timeout | 30000 milliseconds | | client_max_header_size | 12 kb | | client_max_request_size | 48 kb | | client_max_body_size | 0 kb | | max_rps_unknown_uri | 0 | | max_rps_cip | 0 | | max_rps_uri | 0 | | max_rps_cip_uri | 0 | | ssl_client_certificate_mode | SSL_CLIENT_CERTIFICATE_NONE | | websockets_enabled | True | | max_rps_unknown_cip | 0 | | max_bad_rps_cip | 0 | | max_bad_rps_uri | 0 | | max_bad_rps_cip_uri | 0 | | keepalive_header | False | | use_app_keepalive_timeout | False | | allow_dots_in_header_name | False | | disable_keepalive_posts_msie6 | True | | enable_request_body_buffering | False | | enable_fire_and_forget | False | | max_response_headers_size | 48 kb | | http2_enabled | True | | respond_with_100_continue | True | | hsts_subdomains_enabled | True | | enable_request_body_metrics | False | | fwd_close_hdr_for_bound_connections | True | | max_keepalive_requests | 100 | | disable_sni_hostname_check | False | | max_http2_control_frames_per_connection | 2000 | | max_http2_queued_frames_to_client_per_connection | 2000 | | max_http2_empty_data_frames_per_connection | 2000 | | max_http2_concurrent_streams_per_connection | 256 | | reset_conn_http_on_ssl_port | False | | preserve_client_ip | False | | preserve_client_port | False | | tenant_ref | admin | +----------------------------------------------------+---------------------------------------------------------+ [admin:th-controller-3]: >