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.
This commit is contained in:
Christopher Faulet 2020-06-02 17:33:56 +02:00
parent f187ce68b1
commit 89aed32bff
4 changed files with 25 additions and 3 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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) {

View File

@ -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 }
};