MINOR: ssl-sample: add ssl_fc_early_rcvd() to detect use of early data

We currently have ssl_fc_has_early() which says that early data are still
unconfirmed by a final handshake, but nothing to see if a client has been
able to use early data at all, which is a problem because such mechanisms
generally depend on multiple factors and it's hard to know when they start
to work. This new sample fetch function will indicate that some early data
were seen over that front connection, i.e. this can be used to confirm
that at some point the client was able to push some. This is essentially
a debugging tool that has no practical use case other than debugging.
This commit is contained in:
Willy Tarreau 2025-10-29 08:03:01 +01:00
parent 765d49b680
commit 18b27bfec9
2 changed files with 33 additions and 1 deletions

View file

@ -25028,6 +25028,15 @@ ssl_fc_curve : string
connection was made over an SSL/TLS transport layer. This requires
OpenSSL >= 3.0.0.
ssl_fc_early_rcvd : boolean
Returns true if early data were seen over that connection, regardless of the
fact that the handshake has since completed. It has no practical use case for
traffic processing, however it's about the only way to "see" that a client
used 0-RTT to send early data, and is sometimes useful when debugging, since
the only other alternatives are network traffic captures or logging the front
connection's flags and matching them in the code. It may also be useful to
get statistics on clients' capabilities. See also "ssl_fc_has_early".
ssl_fc_early_exporter_secret : string
Return the EARLY_EXPORTER_SECRET as an hexadecimal string for the
front connection when the incoming connection was made over an TLS 1.3
@ -25133,7 +25142,8 @@ ssl_fc_has_crt : boolean
ssl_fc_has_early : boolean
Returns true if early data were sent, and the handshake didn't complete yet.
As it has security implications, it is useful to be able to refuse those, or
wait until the handshake completes (via the "wait-for-handshake" action).
wait until the handshake completes (via the "wait-for-handshake" action). See
also "ssl_fc_early_rcvd".
ssl_fc_has_sni : boolean
This checks for the presence of a Server Name Indication TLS extension (SNI)

View file

@ -574,6 +574,27 @@ smp_fetch_ssl_fc_has_early(const struct arg *args, struct sample *smp, const cha
return 1;
}
static int
smp_fetch_ssl_fc_early_rcvd(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
SSL *ssl;
struct connection *conn;
conn = objt_conn(smp->sess->origin);
ssl = ssl_sock_get_ssl_object(conn);
if (!ssl)
return 0;
smp->flags = 0;
smp->data.type = SMP_T_BOOL;
#ifdef OPENSSL_IS_BORINGSSL
smp->data.u.sint = SSL_early_data_accepted(ssl);
#else
smp->data.u.sint = !!(conn->flags & CO_FL_EARLY_DATA);
#endif
return 1;
}
/* boolean, returns true if client cert was present */
static int
smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
@ -2515,6 +2536,7 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
#if (HA_OPENSSL_VERSION_NUMBER >= 0x3000000fL)
{ "ssl_fc_curve", smp_fetch_ssl_fc_ec, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
#endif
{ "ssl_fc_early_rcvd", smp_fetch_ssl_fc_early_rcvd, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
{ "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
{ "ssl_fc_has_early", smp_fetch_ssl_fc_has_early, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
{ "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },