2018年11月6日,http://nginx.org/公布了两个安全公告,涉及到HTTP/2和MP4两个模块。
2018-11-06 nginx-1.14.1 stable and nginx-1.15.6 mainline versions have been released, with fixes for vulnerabilities in HTTP/2 (CVE-2018-16843, CVE-2018-16844) and the MP4 module(CVE-2018-16845).
官网对HTTP/2问题的描述为,是一个Flood攻击,支持HTTP/2的版本,只要开启了该选项,都会有多耗用内存/CPU的问题。
Two security issues were identified in nginx HTTP/2 implementation, which might cause excessive memory consumption (CVE-2018-16843) and CPU usage (CVE-2018-16844). The issues affect nginx compiled with the ngx_http_v2_module (not compiled by default) if the "http2" option of the "listen" directive is used in a configuration file. The issues affect nginx 1.9.5 - 1.15.5. The issues are fixed in nginx 1.15.6, 1.14.1.
问题1:单个连接控制报文积压未做限制
攻击场景:大量client端建立HTTP2连接后,持续请求控制报文,但是不接收处理导致服务端持续积压。
修改方案:
https://github.com/nginx/nginx/commit/8ec4146e1aad3a4fc0b19a024f8ef3516791e30c
HTTP/2: flood detection.
Fixed uncontrolled memory growth in case peer is flooding us with some frames (e.g., SETTINGS and PING) and doesn't read data. Fix is to limit the number of allocated control frames.
ngx_http_v2_get_frame(ngx_http_v2_connection_t *h2c, size_t length, frame = h2c->free_frames; if (frame) { h2c->free_frames = frame->next; …… } else if (h2c->frames < 10000) { h2c->frames++; //增加未处理的控制frames计数 …… } else { //判断是否有控制一直请求未回应(1w个),则退出连接 ngx_log_error(NGX_LOG_ERR, h2c->connection->log, 0, "http2 flood detected"); h2c->connection->error = 1; return NULL; }
问题2:空闲连接个数未做限制
攻击场景:大量客户端瞬间发起请求,然后停止发送数据,导致服务端的不传输数据的空闲连接数居高不下,影响其它客户的服务。
修改方案:
https://github.com/nginx/nginx/commit/60b93594cca9cb5d63f26e724c458ccb380ac540
HTTP/2: limit the number of idle state switches.
An attack that continuously switches HTTP/2 connection between idle and active states can result in excessive CPU usage. This is because when a connection switches to the idle state, all of its memory pool caches are freed. This change limits the maximum allowed number of idle state switches to 10 * http2_max_requests (i.e., 10000 by default). This limits possible CPU usage in one connection, and also imposes a limit on the maximum lifetime of a connection.
ngx_http_v2_idle_handler(ngx_event_t *rev) …… h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, ngx_http_v2_module); if (h2c->idle++ > 10 * h2scf->max_requests) { //限制空闲连接个数,超过阈值关闭,避免过高消耗资源 ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, "http2 flood detected"); ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR); return; } ……