]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: ssl/ocsp: counters for OCSP stapling
authorWilliam Lallemand <wlallemand@haproxy.com>
Mon, 23 Dec 2024 10:06:17 +0000 (11:06 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Mon, 23 Dec 2024 10:23:00 +0000 (11:23 +0100)
Add 2 counters in the SSL stats module for OCSP stapling.

- ssl_ocsp_staple is the number of OCSP response successfully stapled
  with the handshake
- ssl_failed_ocsp_stapled is the number of OCSP response that we
  couldn't staple, it could be because of an error or because the
  response is expired.

These counters are incremented in the OCSP stapling callback, so if no
OCSP was configured they won't never increase. Also they are only
working in frontends.

This was discussed in github issue #2822.

include/haproxy/ssl_sock-t.h
src/ssl_ocsp.c
src/ssl_sock.c

index 410a789a164856e518c33db6f92702b3acd8e325..2c7f73b3b17c96df64e0ef73c74eac6d0062288e 100644 (file)
@@ -331,6 +331,8 @@ struct ssl_counters {
        long long sess;
        long long reused_sess;
        long long failed_handshake;
+       long long ocsp_staple;
+       long long failed_ocsp_staple;
 };
 
 #endif /* USE_OPENSSL */
index 73f16668942d832c9c864937526b2a76a836e28e..44c86f39831bebd9f7219e63704fa6e3bdf39c87 100644 (file)
@@ -99,6 +99,10 @@ int ssl_sock_get_ocsp_arg_kt_index(int evp_keytype)
  */
 int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
 {
+       struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
+       struct listener *li;
+       struct ssl_counters *counters = NULL;
+       struct ssl_counters *counters_px = NULL;
        struct certificate_ocsp *ocsp;
        struct ocsp_cbk_arg *ocsp_arg;
        char *ssl_buf;
@@ -111,6 +115,12 @@ int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
        if (!ctx)
                goto error;
 
+       if (obj_type(conn->target) == OBJ_TYPE_LISTENER) {
+               li = __objt_listener(conn->target);
+               counters = EXTRA_COUNTERS_GET(li->extra_counters, &ssl_stats_module);
+               counters_px = EXTRA_COUNTERS_GET(li->bind_conf->frontend->extra_counters_fe, &ssl_stats_module);
+       }
+
        ocsp_arg = SSL_CTX_get_ex_data(ctx, ocsp_ex_index);
        if (!ocsp_arg)
                goto error;
@@ -150,9 +160,21 @@ int ssl_sock_ocsp_stapling_cbk(SSL *ssl, void *arg)
        memcpy(ssl_buf, ocsp->response.area, ocsp->response.data);
        SSL_set_tlsext_status_ocsp_resp(ssl, (unsigned char*)ssl_buf, ocsp->response.data);
 
+       if (counters) {
+               HA_ATOMIC_INC(&counters->ocsp_staple);
+               HA_ATOMIC_INC(&counters_px->ocsp_staple);
+       }
+
        return SSL_TLSEXT_ERR_OK;
 
+
 error:
+
+       if (counters) {
+               HA_ATOMIC_INC(&counters->failed_ocsp_staple);
+               HA_ATOMIC_INC(&counters_px->failed_ocsp_staple);
+       }
+
        return SSL_TLSEXT_ERR_NOACK;
 }
 
index 45d34b246c440f099be733c7026ed9693c95a2ff..23316c2e5c6a36cb0771256cee6527ac3a60cfea 100644 (file)
@@ -156,6 +156,8 @@ enum {
        SSL_ST_SESS,
        SSL_ST_REUSED_SESS,
        SSL_ST_FAILED_HANDSHAKE,
+       SSL_ST_OCSP_STAPLE,
+       SSL_ST_FAILED_OCSP_STAPLE,
 
        SSL_ST_STATS_COUNT /* must be the last member of the enum */
 };
@@ -167,6 +169,10 @@ static struct stat_col ssl_stats[] = {
                                      .desc = "Total number of ssl sessions reused" },
        [SSL_ST_FAILED_HANDSHAKE] = { .name = "ssl_failed_handshake",
                                      .desc = "Total number of failed handshake" },
+       [SSL_ST_OCSP_STAPLE]      = { .name = "ssl_ocsp_staple",
+                                     .desc = "Total number of stapled OCSP responses" },
+       [SSL_ST_FAILED_OCSP_STAPLE] = { .name = "ssl_failed_ocsp_staple",
+                                     .desc = "Total number of failed OCSP stapling (expired or error)" },
 };
 
 static struct ssl_counters ssl_counters;
@@ -189,6 +195,13 @@ static int ssl_fill_stats(void *data, struct field *stats, unsigned int *selecte
                case SSL_ST_FAILED_HANDSHAKE:
                        metric = mkf_u64(FN_COUNTER, counters->failed_handshake);
                        break;
+               case SSL_ST_OCSP_STAPLE:
+                       metric = mkf_u64(FN_COUNTER, counters->ocsp_staple);
+                       break;
+               case SSL_ST_FAILED_OCSP_STAPLE:
+                       metric = mkf_u64(FN_COUNTER, counters->failed_ocsp_staple);
+                       break;
+
                default:
                        /* not used for frontends. If a specific metric
                         * is requested, return an error. Otherwise continue.