mirror of
http://git.haproxy.org/git/haproxy.git
synced 2026-02-04 09:03:40 +02:00
MINOR: ssl: allow to disable certificate compression
This option allows to disable the certificate compression (RFC 8879) using OpenSSL >= 3.2.0. This feature is known to permit some denial of services by causing extra memory allocations of approximately 22MiB and extra CPU work per connection with OpenSSL versions affected by CVE-2025-66199. ( https://openssl-library.org/news/vulnerabilities/index.html#CVE-2025-66199 ) Setting this to "off" permits to mitigate the problem. Must be backported to every stable branches.
This commit is contained in:
@@ -1983,6 +1983,7 @@ The following keywords are supported in the "global" section :
|
||||
- tune.ssl.cachesize
|
||||
- tune.ssl.capture-buffer-size
|
||||
- tune.ssl.capture-cipherlist-size (deprecated)
|
||||
- tune.ssl.certificate-compression
|
||||
- tune.ssl.default-dh-param
|
||||
- tune.ssl.force-private-cache
|
||||
- tune.ssl.hard-maxrecord
|
||||
@@ -5310,6 +5311,22 @@ tune.ssl.capture-cipherlist-size <number> (deprecated)
|
||||
formats. If the value is 0 (default value) the capture is disabled,
|
||||
otherwise a buffer is allocated for each SSL/TLS connection.
|
||||
|
||||
tune.ssl.certificate-compression { auto | off }
|
||||
This setting allows to configure the certificate compression support which is
|
||||
an extension (RFC 8879) to TLS 1.3.
|
||||
|
||||
When set to "auto" it uses the default value of the TLS library.
|
||||
|
||||
With "off" it tries to explicitely disable the support of the feature.
|
||||
HAProxy won't try to send compressed certificates anymore nor accept
|
||||
compressed certificates.
|
||||
|
||||
Configures both backend and frontend sides.
|
||||
|
||||
This keyword is supported by OpenSSL >= 3.2.0.
|
||||
|
||||
The default value is auto.
|
||||
|
||||
tune.ssl.default-dh-param <number>
|
||||
Sets the maximum size of the Diffie-Hellman parameters used for generating
|
||||
the ephemeral/temporary Diffie-Hellman key in case of DHE key exchange. The
|
||||
|
||||
@@ -338,6 +338,8 @@ struct global_ssl {
|
||||
int renegotiate; /* Renegotiate mode (SSL_RENEGOTIATE_ flag) */
|
||||
char **passphrase_cmd;
|
||||
int passphrase_cmd_args_cnt;
|
||||
|
||||
unsigned int certificate_compression:1; /* allow to explicitely disable certificate compression */
|
||||
};
|
||||
|
||||
/* The order here matters for picking a default context,
|
||||
|
||||
@@ -496,6 +496,36 @@ static int ssl_parse_global_keylog(char **args, int section_type, struct proxy *
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Allow to explicitely disable certificate compression when set to "off" */
|
||||
#ifdef SSL_OP_NO_RX_CERTIFICATE_COMPRESSION
|
||||
static int ssl_parse_certificate_compression(char **args, int section_type, struct proxy *curpx,
|
||||
const struct proxy *defpx, const char *file, int line,
|
||||
char **err)
|
||||
{
|
||||
if (too_many_args(1, args, err, NULL))
|
||||
return -1;
|
||||
|
||||
if (strcmp(args[1], "auto") == 0)
|
||||
global_ssl.certificate_compression = 1;
|
||||
else if (strcmp(args[1], "off") == 0)
|
||||
global_ssl.certificate_compression = 0;
|
||||
else {
|
||||
memprintf(err, "'%s' expects either 'on' or 'off' but got '%s'.", args[0], args[1]); return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int ssl_parse_certificate_compression(char **args, int section_type, struct proxy *curpx,
|
||||
const struct proxy *defpx, const char *file, int line,
|
||||
char **err)
|
||||
{
|
||||
memprintf(err, "'%s' is not supported by your TLS library. "
|
||||
"It is known to work only with OpenSSL >= 3.2.0.", args[0]);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* parse "ssl.force-private-cache".
|
||||
* Returns <0 on alert, >0 on warning, 0 on success.
|
||||
*/
|
||||
@@ -2759,6 +2789,7 @@ static struct cfg_kw_list cfg_kws = {ILH, {
|
||||
{ CFG_GLOBAL, "ssl-security-level", ssl_parse_security_level },
|
||||
{ CFG_GLOBAL, "ssl-skip-self-issued-ca", ssl_parse_skip_self_issued_ca },
|
||||
{ CFG_GLOBAL, "tune.ssl.cachesize", ssl_parse_global_int },
|
||||
{ CFG_GLOBAL, "tune.ssl.certificate-compression", ssl_parse_certificate_compression },
|
||||
{ CFG_GLOBAL, "tune.ssl.default-dh-param", ssl_parse_global_default_dh },
|
||||
{ CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache },
|
||||
{ CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime },
|
||||
|
||||
@@ -152,6 +152,9 @@ struct global_ssl global_ssl = {
|
||||
#endif
|
||||
#ifdef HAVE_ACME
|
||||
.acme_scheduler = 1,
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_RX_CERTIFICATE_COMPRESSION
|
||||
.certificate_compression = 1,
|
||||
#endif
|
||||
.renegotiate = SSL_RENEGOTIATE_DFLT,
|
||||
.passphrase_cmd = NULL,
|
||||
@@ -4079,6 +4082,11 @@ ssl_sock_initial_ctx(struct bind_conf *bind_conf)
|
||||
options |= SSL_OP_NO_RENEGOTIATION;
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_RX_CERTIFICATE_COMPRESSION
|
||||
if (global_ssl.certificate_compression == 0)
|
||||
options |= SSL_OP_NO_RX_CERTIFICATE_COMPRESSION | SSL_OP_NO_TX_CERTIFICATE_COMPRESSION;
|
||||
#endif
|
||||
|
||||
SSL_CTX_set_options(ctx, options);
|
||||
|
||||
#ifdef SSL_MODE_ASYNC
|
||||
@@ -5132,6 +5140,11 @@ static int ssl_sock_prepare_srv_ssl_ctx(const struct server *srv, SSL_CTX *ctx)
|
||||
options &= ~SSL_OP_NO_RENEGOTIATION;
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_RX_CERTIFICATE_COMPRESSION
|
||||
if (global_ssl.certificate_compression == 0)
|
||||
options |= SSL_OP_NO_RX_CERTIFICATE_COMPRESSION | SSL_OP_NO_TX_CERTIFICATE_COMPRESSION;
|
||||
#endif
|
||||
|
||||
SSL_CTX_set_options(ctx, options);
|
||||
|
||||
#ifdef SSL_MODE_ASYNC
|
||||
|
||||
Reference in New Issue
Block a user