mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-09 13:01:00 +01:00
MINOR: ssl/ech: add logging and sample fetches for ECH status and outer SNI
This patch adds functions to expose Encrypted Client Hello (ECH) status and outer SNI information for logging and sample fetching. Two new helper functions are introduced in ech.c: - conn_get_ech_status() places the ECH processing status string into a buffer. - conn_get_ech_outer_sni() retrieves the outer SNI value if ECH succeeded. Two new sample fetch keywords are added: - "ssl_fc_ech_status" returns the ECH status string. - "ssl_fc_ech_outer_sni" returns the outer SNI value seen during ECH. These allow ECH information to be used in HAProxy logs, ACLs, and captures.
This commit is contained in:
parent
dba4fd248a
commit
23f5cbb411
@ -6,6 +6,8 @@
|
||||
#include <openssl/ech.h>
|
||||
|
||||
int load_echkeys(SSL_CTX *ctx, char *dirname, int *loaded);
|
||||
int conn_get_ech_status(struct connection *conn, struct buffer *buf);
|
||||
int conn_get_ech_outer_sni(struct connection *conn, struct buffer *buf);
|
||||
|
||||
# endif /* USE_ECH */
|
||||
#endif /* _HAPROXY_ECH_H */
|
||||
|
||||
53
src/ech.c
53
src/ech.c
@ -74,6 +74,58 @@ end:
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Place an ECH status string into a trash buffer
|
||||
* ECH status string examples:
|
||||
* SSL_ECH_STATUS_GREASE
|
||||
* SSL_ECH_STATUS_NOT_TRIED
|
||||
* SSL_ECH_STATUS_SUCCESS
|
||||
* The status values are those defined in <openssl/ech.h>
|
||||
* as the define'd returns from `SSL_ech_get1_status()`
|
||||
*/
|
||||
int conn_get_ech_status(struct connection *conn, struct buffer *buf)
|
||||
{
|
||||
struct ssl_sock_ctx *ctx = conn_get_ssl_sock_ctx(conn);
|
||||
char *sni_ech = NULL;
|
||||
char *sni_clr = NULL;
|
||||
const char *lstr = NULL;
|
||||
|
||||
if (!ctx)
|
||||
return 0;
|
||||
#define s(x) #x
|
||||
switch (SSL_ech_get1_status(ctx->ssl, &sni_ech, &sni_clr)) {
|
||||
case SSL_ECH_STATUS_SUCCESS: lstr = s(SSL_ECH_STATUS_SUCCESS); break;
|
||||
case SSL_ECH_STATUS_NOT_TRIED: lstr = s(SSL_ECH_STATUS_NOT_TRIED); break;
|
||||
case SSL_ECH_STATUS_FAILED: lstr = s(SSL_ECH_STATUS_FAILED); break;
|
||||
case SSL_ECH_STATUS_BAD_NAME: lstr = s(SSL_ECH_STATUS_BAD_NAME); break;
|
||||
case SSL_ECH_STATUS_BAD_CALL: lstr = s(SSL_ECH_STATUS_BAD_CALL); break;
|
||||
case SSL_ECH_STATUS_GREASE: lstr = s(SSL_ECH_STATUS_GREASE); break;
|
||||
case SSL_ECH_STATUS_BACKEND: lstr = s(SSL_ECH_STATUS_BACKEND); break;
|
||||
default: lstr = ""; break;
|
||||
}
|
||||
#undef s
|
||||
chunk_printf(buf, "%s", lstr);
|
||||
OPENSSL_free(sni_ech);
|
||||
OPENSSL_free(sni_clr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If ECH succeeded, return the outer SNI value seen */
|
||||
int conn_get_ech_outer_sni(struct connection *conn, struct buffer *buf)
|
||||
{
|
||||
struct ssl_sock_ctx *ctx = conn_get_ssl_sock_ctx(conn);
|
||||
char *sni_ech = NULL;
|
||||
char *sni_clr = NULL;
|
||||
|
||||
if (!ctx)
|
||||
return 0;
|
||||
if (SSL_ech_get1_status(ctx->ssl, &sni_ech, &sni_clr)
|
||||
== SSL_ECH_STATUS_SUCCESS && sni_clr != NULL)
|
||||
chunk_printf(buf, "%s", sni_clr);
|
||||
OPENSSL_free(sni_ech);
|
||||
OPENSSL_free(sni_clr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bind_parse_ech(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
|
||||
{
|
||||
@ -97,4 +149,5 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
|
||||
|
||||
|
||||
INITCALL1(STG_REGISTER, bind_register_keywords, &bind_kws);
|
||||
|
||||
#endif
|
||||
|
||||
@ -33,6 +33,9 @@
|
||||
#include <haproxy/stconn.h>
|
||||
#include <haproxy/tools.h>
|
||||
#include <haproxy/vars.h>
|
||||
#ifdef USE_ECH
|
||||
#include <haproxy/ech.h>
|
||||
#endif
|
||||
|
||||
|
||||
/***** Below are some sample fetching functions for ACL/patterns *****/
|
||||
@ -1880,6 +1883,48 @@ smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw,
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_ECH
|
||||
static int
|
||||
smp_fetch_ssl_fc_ech_status(const struct arg *args, struct sample *smp,
|
||||
const char *kw, void *private)
|
||||
{
|
||||
struct buffer *smp_trash;
|
||||
struct connection *conn;
|
||||
|
||||
smp->flags = SMP_F_VOL_SESS | SMP_F_CONST;
|
||||
smp->data.type = SMP_T_STR;
|
||||
conn = objt_conn(smp->sess->origin);
|
||||
if (!conn)
|
||||
return 0;
|
||||
smp_trash = get_trash_chunk();
|
||||
if (conn_get_ech_status(conn, smp_trash) == 1) {
|
||||
smp->data.u.str.area = smp_trash->area;
|
||||
smp->data.u.str.data = smp_trash->data;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
smp_fetch_ssl_fc_ech_outer_sni(const struct arg *args, struct sample *smp,
|
||||
const char *kw, void *private)
|
||||
{
|
||||
struct buffer *smp_trash;
|
||||
struct connection *conn;
|
||||
|
||||
smp->flags = SMP_F_VOL_SESS | SMP_F_CONST;
|
||||
smp->data.type = SMP_T_STR;
|
||||
conn = objt_conn(smp->sess->origin);
|
||||
if (!conn)
|
||||
return 0;
|
||||
smp_trash = get_trash_chunk();
|
||||
if (conn_get_ech_outer_sni(conn, smp_trash) == 1) {
|
||||
smp->data.u.str.area = smp_trash->area;
|
||||
smp->data.u.str.data = smp_trash->data;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* binary, returns tls client hello cipher list.
|
||||
* Arguments: filter_option (0,1)
|
||||
*/
|
||||
@ -2572,6 +2617,10 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
|
||||
#endif
|
||||
|
||||
{ "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
|
||||
#ifdef USE_ECH
|
||||
{ "ssl_fc_ech_status", smp_fetch_ssl_fc_ech_status, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
|
||||
{ "ssl_fc_ech_outer_sni", smp_fetch_ssl_fc_ech_outer_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
|
||||
#endif
|
||||
{ "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, ARG1(0,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
|
||||
{ "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, ARG1(0,SINT), NULL, SMP_T_BIN, SMP_USE_L5CLI },
|
||||
{ "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, ARG1(0,SINT), NULL, SMP_T_STR, SMP_USE_L5CLI },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user