mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
MEDIUM: config: set useful ALPN defaults for HTTPS and QUIC
This commit makes sure that if three is no "alpn", "npn" nor "no-alpn" setting on a "bind" line which corresponds to an HTTPS or QUIC frontend, we automatically turn on "h2,http/1.1" as an ALPN default for an HTTP listener, and "h3" for a QUIC listener. This simplifies the configuration for end users since they won't have to explicitly configure the ALPN string to enable H2, considering that at the time of writing, HTTP/1.1 represents less than 7% of the traffic on large infrastructures. The doc and regtests were updated. For more info, refer to the following thread: https://www.mail-archive.com/haproxy@formilux.org/msg43410.html
This commit is contained in:
parent
de85de69ec
commit
5003ac7fe9
@ -4875,7 +4875,7 @@ bind /<path> [, ...] [param*]
|
|||||||
bind "fd@${FD_APP1}"
|
bind "fd@${FD_APP1}"
|
||||||
|
|
||||||
listen h3_quic_proxy
|
listen h3_quic_proxy
|
||||||
bind quic4@10.0.0.1:8888 ssl crt /etc/mycrt alpn h3
|
bind quic4@10.0.0.1:8888 ssl crt /etc/mycrt
|
||||||
|
|
||||||
Note: regarding Linux's abstract namespace sockets, HAProxy uses the whole
|
Note: regarding Linux's abstract namespace sockets, HAProxy uses the whole
|
||||||
sun_path length is used for the address length. Some other programs
|
sun_path length is used for the address length. Some other programs
|
||||||
@ -14606,21 +14606,30 @@ alpn <protocols>
|
|||||||
delimited list of protocol names, for instance: "http/1.1,http/1.0" (without
|
delimited list of protocol names, for instance: "http/1.1,http/1.0" (without
|
||||||
quotes). This requires that the SSL library is built with support for TLS
|
quotes). This requires that the SSL library is built with support for TLS
|
||||||
extensions enabled (check with haproxy -vv). The ALPN extension replaces the
|
extensions enabled (check with haproxy -vv). The ALPN extension replaces the
|
||||||
initial NPN extension. ALPN is required to enable HTTP/2 on an HTTP frontend.
|
initial NPN extension. At the protocol layer, ALPN is required to enable
|
||||||
Versions of OpenSSL prior to 1.0.2 didn't support ALPN and only supposed the
|
HTTP/2 on an HTTPS frontend and HTTP/3 on a QUIC frontend. However, when such
|
||||||
now obsolete NPN extension. At the time of writing this, most browsers still
|
frontends have none of "npn", "alpn" and "no-alpn" set, a default value of
|
||||||
support both ALPN and NPN for HTTP/2 so a fallback to NPN may still work for
|
"h2,http/1.1" will be used for a regular HTTPS frontend, and "h3" for a QUIC
|
||||||
a while. But ALPN must be used whenever possible. If both HTTP/2 and HTTP/1.1
|
frontend. Versions of OpenSSL prior to 1.0.2 didn't support ALPN and only
|
||||||
are expected to be supported, both versions can be advertised, in order of
|
supposed the now obsolete NPN extension. At the time of writing this, most
|
||||||
preference, like below :
|
browsers still support both ALPN and NPN for HTTP/2 so a fallback to NPN may
|
||||||
|
still work for a while. But ALPN must be used whenever possible. Protocols
|
||||||
|
not advertised are not negotiated. For example it is possible to only accept
|
||||||
|
HTTP/2 connections with this:
|
||||||
|
|
||||||
bind :443 ssl crt pub.pem alpn h2,http/1.1
|
bind :443 ssl crt pub.pem alpn h2 # explicitly disable HTTP/1.1
|
||||||
|
|
||||||
QUIC supports only h3 and hq-interop as ALPN. h3 is for HTTP/3 and hq-interop
|
QUIC supports only h3 and hq-interop as ALPN. h3 is for HTTP/3 and hq-interop
|
||||||
is used for http/0.9 and QUIC interop runner (see https://interop.seemann.io).
|
is used for http/0.9 and QUIC interop runner (see https://interop.seemann.io).
|
||||||
Each "alpn" statement will replace a previous one. In order to remove them,
|
Each "alpn" statement will replace a previous one. In order to remove them,
|
||||||
use "no-alpn".
|
use "no-alpn".
|
||||||
|
|
||||||
|
Note that some old browsers such as Firefox 88 used to experience issues with
|
||||||
|
WebSocket over H2, and in case such a setup is encountered, it may be needed
|
||||||
|
to either explicitly disable HTTP/2 in the "alpn" string by forcing it to
|
||||||
|
"http/1.1" or "no-alpn", or to enable "h2-workaround-bogus-websocket-clients"
|
||||||
|
globally.
|
||||||
|
|
||||||
backlog <backlog>
|
backlog <backlog>
|
||||||
Sets the socket's backlog to this value. If unspecified or 0, the frontend's
|
Sets the socket's backlog to this value. If unspecified or 0, the frontend's
|
||||||
backlog is used instead, which generally defaults to the maxconn value.
|
backlog is used instead, which generally defaults to the maxconn value.
|
||||||
@ -14828,6 +14837,12 @@ crt-list <file>
|
|||||||
never match except if no other certificate matches. This way the first
|
never match except if no other certificate matches. This way the first
|
||||||
declared certificate act as a fallback.
|
declared certificate act as a fallback.
|
||||||
|
|
||||||
|
When no ALPN is set, the "bind" line's default one is used. If a "bind" line
|
||||||
|
has no "no-alpn", "alpn" nor "npn" set, a default value will be used
|
||||||
|
depending on the protocol (see "alpn" above). However if the "bind" line has
|
||||||
|
a different default, or explicitly disables ALPN using "no-alpn", it is
|
||||||
|
possible to force a specific value for a certificate.
|
||||||
|
|
||||||
crt-list file example:
|
crt-list file example:
|
||||||
cert1.pem !*
|
cert1.pem !*
|
||||||
# comment
|
# comment
|
||||||
@ -15013,7 +15028,11 @@ no-alpn
|
|||||||
Disables ALPN processing (technically speaking this sets the ALPN string to
|
Disables ALPN processing (technically speaking this sets the ALPN string to
|
||||||
an empty string that will not be advertised). It permits to cancel a previous
|
an empty string that will not be advertised). It permits to cancel a previous
|
||||||
occurrence of an "alpn" setting and to disable application protocol
|
occurrence of an "alpn" setting and to disable application protocol
|
||||||
negotiation. See also "alpn".
|
negotiation. It may also be used to prevent a listener from negotiating ALPN
|
||||||
|
with a client on an HTTPS or QUIC listener; by default, HTTPS listeners will
|
||||||
|
advertise "h2,http/1.1" and QUIC listeners will advertise "h3". See also
|
||||||
|
"alpn" bove. Note that when using "crt-list", a certificate may override the
|
||||||
|
"alpn" setting and re-enable its processing.
|
||||||
|
|
||||||
no-ca-names
|
no-ca-names
|
||||||
This setting is only available when support for OpenSSL was built in. It
|
This setting is only available when support for OpenSSL was built in. It
|
||||||
|
@ -117,7 +117,7 @@ client c1 -connect ${h1_clearfe_sock} {
|
|||||||
txreq -url "/10"
|
txreq -url "/10"
|
||||||
rxresp
|
rxresp
|
||||||
expect resp.status == 200
|
expect resp.status == 200
|
||||||
expect resp.http.x-alpn == "_"
|
expect resp.http.x-alpn == "_http/1.1"
|
||||||
expect resp.http.x-ver == "_1.1"
|
expect resp.http.x-ver == "_1.1"
|
||||||
|
|
||||||
txreq -url "/11"
|
txreq -url "/11"
|
||||||
@ -150,8 +150,8 @@ client c1 -connect ${h1_clearfe_sock} {
|
|||||||
txreq -url "/20"
|
txreq -url "/20"
|
||||||
rxresp
|
rxresp
|
||||||
expect resp.status == 200
|
expect resp.status == 200
|
||||||
expect resp.http.x-alpn == "_"
|
expect resp.http.x-alpn == "_h2"
|
||||||
expect resp.http.x-ver == "_1.1"
|
expect resp.http.x-ver == "_2.0"
|
||||||
|
|
||||||
txreq -url "/21"
|
txreq -url "/21"
|
||||||
rxresp
|
rxresp
|
||||||
@ -183,8 +183,8 @@ client c1 -connect ${h1_clearfe_sock} {
|
|||||||
txreq -url "/30"
|
txreq -url "/30"
|
||||||
rxresp
|
rxresp
|
||||||
expect resp.status == 200
|
expect resp.status == 200
|
||||||
expect resp.http.x-alpn == "_"
|
expect resp.http.x-alpn == "_h2"
|
||||||
expect resp.http.x-ver == "_1.1"
|
expect resp.http.x-ver == "_2.0"
|
||||||
|
|
||||||
txreq -url "/31"
|
txreq -url "/31"
|
||||||
rxresp
|
rxresp
|
||||||
|
@ -2937,6 +2937,30 @@ int check_config_validity()
|
|||||||
free(bind_conf->ssl_conf.alpn_str);
|
free(bind_conf->ssl_conf.alpn_str);
|
||||||
bind_conf->ssl_conf.alpn_str = NULL;
|
bind_conf->ssl_conf.alpn_str = NULL;
|
||||||
}
|
}
|
||||||
|
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
||||||
|
else if (!bind_conf->ssl_conf.alpn_str && !bind_conf->ssl_conf.npn_str &&
|
||||||
|
((bind_conf->options & BC_O_USE_SSL) || bind_conf->xprt == xprt_get(XPRT_QUIC)) &&
|
||||||
|
curproxy->mode == PR_MODE_HTTP && global.tune.bufsize >= 16384) {
|
||||||
|
|
||||||
|
/* Neither ALPN nor NPN were explicitly set nor disabled, we're
|
||||||
|
* in HTTP mode with an SSL or QUIC listener, we can enable ALPN.
|
||||||
|
* Note that it's in binary form.
|
||||||
|
*/
|
||||||
|
if (bind_conf->xprt == xprt_get(XPRT_QUIC))
|
||||||
|
bind_conf->ssl_conf.alpn_str = strdup("\002h3");
|
||||||
|
else
|
||||||
|
bind_conf->ssl_conf.alpn_str = strdup("\002h2\010http/1.1");
|
||||||
|
|
||||||
|
if (!bind_conf->ssl_conf.alpn_str) {
|
||||||
|
ha_alert("Proxy '%s': out of memory while trying to allocate a default alpn string in 'bind %s' at [%s:%d].\n",
|
||||||
|
curproxy->id, bind_conf->arg, bind_conf->file, bind_conf->line);
|
||||||
|
cfgerr++;
|
||||||
|
err_code |= ERR_FATAL | ERR_ALERT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
bind_conf->ssl_conf.alpn_len = strlen(bind_conf->ssl_conf.alpn_str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
|
if (curproxy->mode == PR_MODE_HTTP && global.tune.bufsize < 16384) {
|
||||||
#ifdef OPENSSL_NPN_NEGOTIATED
|
#ifdef OPENSSL_NPN_NEGOTIATED
|
||||||
|
Loading…
Reference in New Issue
Block a user