From: Thomas Prückl Date: Wed, 27 Apr 2022 11:04:54 +0000 (+0200) Subject: MINOR: ssl: add a new global option "tune.ssl.hard-maxrecord" X-Git-Tag: v2.6-dev8~55 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=10243938db38044a2977eedf806c79412fd8c9a4;p=thirdparty%2Fhaproxy.git MINOR: ssl: add a new global option "tune.ssl.hard-maxrecord" Low footprint client machines may not have enough memory to download a complete 16KB TLS record at once. With the new option the maximum record size can be defined on the server side. Note: Before limiting the the record size on the server side, a client should consider using the TLS Maximum Fragment Length Negotiation Extension defined in RFC6066. This patch fixes GitHub issue #1679. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 4f7fc4afb4..aa422f0f5e 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -1118,9 +1118,10 @@ The following keywords are supported in the "global" section : - tune.sndbuf.client - tune.sndbuf.server - tune.ssl.cachesize + - tune.ssl.force-private-cache + - tune.ssl.hard-maxrecord - tune.ssl.keylog - tune.ssl.lifetime - - tune.ssl.force-private-cache - tune.ssl.maxrecord - tune.ssl.default-dh-param - tune.ssl.ssl-ctx-cache-size @@ -2903,6 +2904,12 @@ tune.ssl.force-private-cache this case, adding a first layer of hash-based load balancing before the SSL layer might limit the impact of the lack of session sharing. +tune.ssl.hard-maxrecord + Sets the maximum amount of bytes passed to SSL_write() at any time. Default + value 0 means there is no limit. In contrast to tune.ssl.maxrecord this + settings will not be adjusted dynamically. Smaller records may decrease + throughput, but may be required when dealing with low-footprint clients. + tune.ssl.keylog { on | off } This option activates the logging of the TLS keys. It should be used with care as it will consume more memory per SSL session and could decrease @@ -2950,18 +2957,19 @@ tune.ssl.lifetime being used for too long. tune.ssl.maxrecord - Sets the maximum amount of bytes passed to SSL_write() at a time. Default - value 0 means there is no limit. Over SSL/TLS, the client can decipher the - data only once it has received a full record. With large records, it means - that clients might have to download up to 16kB of data before starting to - process them. Limiting the value can improve page load times on browsers - located over high latency or low bandwidth networks. It is suggested to find - optimal values which fit into 1 or 2 TCP segments (generally 1448 bytes over - Ethernet with TCP timestamps enabled, or 1460 when timestamps are disabled), - keeping in mind that SSL/TLS add some overhead. Typical values of 1419 and - 2859 gave good results during tests. Use "strace -e trace=write" to find the - best value. HAProxy will automatically switch to this setting after an idle - stream has been detected (see tune.idletimer above). + Sets the maximum amount of bytes passed to SSL_write() at the beginning of + the data transfer. Default value 0 means there is no limit. Over SSL/TLS, + the client can decipher the data only once it has received a full record. + With large records, it means that clients might have to download up to 16kB + of data before starting to process them. Limiting the value can improve page + load times on browsers located over high latency or low bandwidth networks. + It is suggested to find optimal values which fit into 1 or 2 TCP segments + (generally 1448 bytes over Ethernet with TCP timestamps enabled, or 1460 when + timestamps are disabled), keeping in mind that SSL/TLS add some overhead. + Typical values of 1419 and 2859 gave good results during tests. Use + "strace -e trace=write" to find the best value. HAProxy will automatically + switch to this setting after an idle stream has been detected (see + tune.idletimer above). See also tune.ssl.hard-maxrecord. tune.ssl.default-dh-param Sets the maximum size of the Diffie-Hellman parameters used for generating diff --git a/include/haproxy/ssl_sock-t.h b/include/haproxy/ssl_sock-t.h index fab8decbff..b404defdb2 100644 --- a/include/haproxy/ssl_sock-t.h +++ b/include/haproxy/ssl_sock-t.h @@ -275,6 +275,7 @@ struct global_ssl { int private_cache; /* Force to use a private session cache even if nbproc > 1 */ unsigned int life_time; /* SSL session lifetime in seconds */ unsigned int max_record; /* SSL max record size */ + unsigned int hard_max_record; /* SSL max record size hard limit */ unsigned int default_dh_param; /* SSL maximum DH parameter size */ int ctx_cache; /* max number of entries in the ssl_ctx cache. */ int capture_buffer_size; /* Size of the capture buffer. */ diff --git a/src/cfgparse-ssl.c b/src/cfgparse-ssl.c index 831a3ca5e1..7acd135ddc 100644 --- a/src/cfgparse-ssl.c +++ b/src/cfgparse-ssl.c @@ -268,6 +268,8 @@ static int ssl_parse_global_int(char **args, int section_type, struct proxy *cur target = &global.tune.sslcachesize; else if (strcmp(args[0], "tune.ssl.maxrecord") == 0) target = (int *)&global_ssl.max_record; + else if (strcmp(args[0], "tune.ssl.hard-maxrecord") == 0) + target = (int *)&global_ssl.hard_max_record; else if (strcmp(args[0], "tune.ssl.ssl-ctx-cache-size") == 0) target = &global_ssl.ctx_cache; else if (strcmp(args[0], "maxsslconn") == 0) @@ -1942,6 +1944,7 @@ static struct cfg_kw_list cfg_kws = {ILH, { { CFG_GLOBAL, "tune.ssl.force-private-cache", ssl_parse_global_private_cache }, { CFG_GLOBAL, "tune.ssl.lifetime", ssl_parse_global_lifetime }, { CFG_GLOBAL, "tune.ssl.maxrecord", ssl_parse_global_int }, + { CFG_GLOBAL, "tune.ssl.hard-maxrecord", ssl_parse_global_int }, { CFG_GLOBAL, "tune.ssl.ssl-ctx-cache-size", ssl_parse_global_int }, { CFG_GLOBAL, "tune.ssl.capture-cipherlist-size", ssl_parse_global_capture_buffer }, { CFG_GLOBAL, "tune.ssl.capture-buffer-size", ssl_parse_global_capture_buffer }, diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 19e41fd877..f88f2415ed 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -122,6 +122,7 @@ struct global_ssl global_ssl = { #ifdef DEFAULT_SSL_MAX_RECORD .max_record = DEFAULT_SSL_MAX_RECORD, #endif + .hard_max_record = 0, .default_dh_param = SSL_DEFAULT_DH_PARAM, .ctx_cache = DEFAULT_SSL_CTX_CACHE, .capture_buffer_size = 0, @@ -6568,6 +6569,9 @@ static size_t ssl_sock_from_buf(struct connection *conn, void *xprt_ctx, const s if (try > count) try = count; + if (global_ssl.hard_max_record && try > global_ssl.hard_max_record) + try = global_ssl.hard_max_record; + if (!(flags & CO_SFL_STREAMER) && !(ctx->xprt_st & SSL_SOCK_SEND_UNLIMITED) && global_ssl.max_record && try > global_ssl.max_record) {