]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux-h1/proxy: Add a proxy option to disable clear h2 upgrade
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 2 Jun 2020 15:33:56 +0000 (17:33 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 3 Jun 2020 08:23:39 +0000 (10:23 +0200)
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.

doc/configuration.txt
include/types/proxy.h
src/mux_h1.c
src/proxy.c

index 837862c5e2818f9fde0910fb027bbd0e44ca0257..89bbb4b339a0e42cb3a1200278feed9f1251023a 100644 (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
index 81a5a44861403b181a2d093d637bb4ed62bcbcfd..c136ecb4cb8afda6b33f63514cd675c0e394af5c 100644 (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 */
index f9048b15ed46e96febce6442bffc35bfd2c4675f..b1eebf1515549c257b39dda4cbf327db586fc5e4 100644 (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) {
index 2614325ca8f847dcbac1268cb683f432806e71f4..d5dee5d344ff99a99eb371407a756f3e85f78228 100644 (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 }
 };