From: Christopher Faulet Date: Tue, 2 Jun 2020 15:33:56 +0000 (+0200) Subject: MINOR: mux-h1/proxy: Add a proxy option to disable clear h2 upgrade X-Git-Tag: v2.2-dev9~159 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=89aed32bfffb5f6f51bdab3e7bd5efc44a9927a1;p=thirdparty%2Fhaproxy.git MINOR: mux-h1/proxy: Add a proxy option to disable clear h2 upgrade By default, HAProxy is able to implicitly upgrade an H1 client connection to an H2 connection if the first request it receives from a given HTTP connection matches the HTTP/2 connection preface. This way, it is possible to support H1 and H2 clients on a non-SSL connections. It could be a problem if for any reason, the H2 upgrade is not acceptable. "option disable-h2-upgrade" may now be used to disable it, per proxy. The main puprose of this option is to let an admin to totally disable the H2 support for security reasons. Recently, a critical issue in the HPACK decoder was fixed, forcing everyone to upgrade their HAProxy version to fix the bug. It is possible to disable H2 for SSL connections, but not on clear ones. This option would have been a viable workaround. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 837862c5e2..89bbb4b339 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -2797,6 +2797,7 @@ option allbackups (*) X - X X option checkcache (*) X - X X option clitcpka (*) X X X - option contstats (*) X X X - +option disable-h2-upgrade (*) X X X - option dontlog-normal (*) X X X - option dontlognull (*) X X X - -- keyword -------------------------- defaults - frontend - listen -- backend - @@ -7196,6 +7197,25 @@ option contstats not enabled by default, as it can cause a lot of wakeups for very large session counts and cause a small performance drop. +option disable-h2-upgrade +no option disable-h2-upgrade + Enable or disable the implicit HTTP/2 upgrade from an HTTP/1.x client + connection. + May be used in sections : defaults | frontend | listen | backend + yes | yes | yes | no + Arguments : none + + By default, HAProxy is able to implicitly upgrade an HTTP/1.x client + connection to an HTTP/2 connection if the first request it receives from a + given HTTP connection matches the HTTP/2 connection preface (i.e. the string + "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"). This way, it is possible to support + HTTP/1.x and HTTP/2 clients on a non-SSL connections. This option must be used to + disable the implicit upgrade. Note this implicit upgrade is only supported + for HTTP proxies, thus this option too. Note also it is possible to force the + HTTP/2 on clear connections by specifying "proto h2" on the bind line. + + If this option has been enabled in a "defaults" section, it can be disabled + in a specific instance by prepending the "no" keyword before it. option dontlog-normal no option dontlog-normal diff --git a/include/types/proxy.h b/include/types/proxy.h index 81a5a44861..c136ecb4cb 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -146,8 +146,7 @@ enum PR_SRV_STATE_FILE { #define PR_O2_H1_ADJ_BUGCLI 0x00008000 /* adjust the case of h1 headers of the response for bogus clients */ #define PR_O2_H1_ADJ_BUGSRV 0x00004000 /* adjust the case of h1 headers of the request for bogus servers */ - -/* unused: 0x00010000 */ +#define PR_O2_NO_H2_UPGRADE 0x00010000 /* disable the implicit H2 upgrades from H1 client connections */ #define PR_O2_NODELAY 0x00020000 /* fully interactive mode, never delay outgoing data */ #define PR_O2_USE_PXHDR 0x00040000 /* use Proxy-Connection for proxy requests */ diff --git a/src/mux_h1.c b/src/mux_h1.c index f9048b15ed..b1eebf1515 100644 --- a/src/mux_h1.c +++ b/src/mux_h1.c @@ -1184,7 +1184,9 @@ static size_t h1_process_headers(struct h1s *h1s, struct h1m *h1m, struct htx *h TRACE_ENTER(H1_EV_RX_DATA|H1_EV_RX_HDRS, h1s->h1c->conn, h1s,, (size_t[]){max}); - if (!(h1s->flags & H1S_F_NOT_FIRST) && !(h1m->flags & H1_MF_RESP)) { + if (!(h1s->h1c->px->options2 & PR_O2_NO_H2_UPGRADE) && /* H2 upgrade supported by the proxy */ + !(h1s->flags & H1S_F_NOT_FIRST) && /* It is the first transaction */ + !(h1m->flags & H1_MF_RESP)) { /* It is a request */ /* Try to match H2 preface before parsing the request headers. */ ret = b_isteq(buf, 0, b_data(buf), ist(H2_CONN_PREFACE)); if (ret > 0) { diff --git a/src/proxy.c b/src/proxy.c index 2614325ca8..d5dee5d344 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -113,6 +113,7 @@ const struct cfg_opt cfg_opts2[] = {"h1-case-adjust-bogus-client", PR_O2_H1_ADJ_BUGCLI, PR_CAP_FE, 0, PR_MODE_HTTP }, {"h1-case-adjust-bogus-server", PR_O2_H1_ADJ_BUGSRV, PR_CAP_BE, 0, PR_MODE_HTTP }, + {"disable-h2-upgrade", PR_O2_NO_H2_UPGRADE, PR_CAP_FE, 0, PR_MODE_HTTP }, { NULL, 0, 0, 0 } };