diff --git a/include/fluent-bit/flb_input.h b/include/fluent-bit/flb_input.h index fc01d0e9dd4..1965e30c97d 100644 --- a/include/fluent-bit/flb_input.h +++ b/include/fluent-bit/flb_input.h @@ -446,6 +446,7 @@ struct flb_input_instance { /* TLS settings */ int use_tls; /* bool, try to use TLS for I/O */ int tls_verify; /* Verify certs (default: true) */ + int tls_verify_client; /* Verify client certs (default: false) */ int tls_verify_hostname; /* Verify hostname (default: false) */ int tls_debug; /* mbedtls debug level */ char *tls_vhost; /* Virtual hostname for SNI */ diff --git a/include/fluent-bit/tls/flb_tls.h b/include/fluent-bit/tls/flb_tls.h index 47c261ebdf7..11202a0983a 100644 --- a/include/fluent-bit/tls/flb_tls.h +++ b/include/fluent-bit/tls/flb_tls.h @@ -76,6 +76,7 @@ struct flb_tls_backend { /* Additional settings */ int (*context_alpn_set) (void *, const char *); + int (*context_set_verify_client) (void *, int); /* TLS Protocol version */ int (*set_minmax_proto) (struct flb_tls *tls, const char *, const char *); @@ -104,6 +105,7 @@ struct flb_tls_backend { /* Main TLS context */ struct flb_tls { int verify; /* FLB_TRUE | FLB_FALSE */ + int verify_client; /* Verify client certificate */ int debug; /* Debug level */ char *vhost; /* Virtual hostname for SNI */ int mode; /* Client or Server */ @@ -131,6 +133,7 @@ struct flb_tls *flb_tls_create(int mode, int flb_tls_destroy(struct flb_tls *tls); int flb_tls_set_alpn(struct flb_tls *tls, const char *alpn); +int flb_tls_set_verify_client(struct flb_tls *tls, int verify_client); int flb_tls_set_verify_hostname(struct flb_tls *tls, int verify_hostname); #if defined(FLB_SYSTEM_WINDOWS) diff --git a/src/flb_input.c b/src/flb_input.c index 97ebb1e4ad9..38b0b8efe31 100644 --- a/src/flb_input.c +++ b/src/flb_input.c @@ -398,6 +398,7 @@ struct flb_input_instance *flb_input_new(struct flb_config *config, instance->tls = NULL; instance->tls_debug = -1; instance->tls_verify = FLB_TRUE; + instance->tls_verify_client = FLB_FALSE; instance->tls_verify_hostname = FLB_FALSE; instance->tls_vhost = NULL; instance->tls_ca_path = NULL; @@ -651,6 +652,10 @@ int flb_input_set_property(struct flb_input_instance *ins, ins->tls_verify = flb_utils_bool(tmp); flb_sds_destroy(tmp); } + else if (prop_key_check("tls.verify_client_cert", k, len) == 0 && tmp) { + ins->tls_verify_client = flb_utils_bool(tmp); + flb_sds_destroy(tmp); + } else if (prop_key_check("tls.verify_hostname", k, len) == 0 && tmp) { ins->tls_verify_hostname = flb_utils_bool(tmp); flb_sds_destroy(tmp); @@ -1331,6 +1336,16 @@ int flb_input_instance_init(struct flb_input_instance *ins, return -1; } } + + if (ins->tls_verify_client == FLB_TRUE) { + ret = flb_tls_set_verify_client(ins->tls, ins->tls_verify_client); + if (ret == -1) { + flb_error("[input %s] error set up to verify client certificate in TLS context", + ins->name); + + return -1; + } + } } struct flb_config_map *m; diff --git a/src/tls/flb_tls.c b/src/tls/flb_tls.c index 53d6cc53af5..55e8c7feed8 100644 --- a/src/tls/flb_tls.c +++ b/src/tls/flb_tls.c @@ -35,6 +35,11 @@ struct flb_config_map tls_configmap[] = { 0, FLB_FALSE, 0, "Force certificate validation", }, + { + FLB_CONFIG_MAP_BOOL, "tls.verify_client_cert", "off", + 0, FLB_FALSE, 0, + "Enable or disable client certificate verification", + }, { FLB_CONFIG_MAP_INT, "tls.debug", "1", 0, FLB_FALSE, 0, @@ -285,6 +290,21 @@ int flb_tls_set_alpn(struct flb_tls *tls, const char *alpn) return 0; } +int flb_tls_set_verify_client(struct flb_tls *tls, int verify_client) +{ + if (!tls) { + return -1; + } + + tls->verify_client = verify_client; + + if (tls->ctx && tls->api->context_set_verify_client) { + return tls->api->context_set_verify_client(tls->ctx, verify_client); + } + + return 0; +} + int flb_tls_set_verify_hostname(struct flb_tls *tls, int verify_hostname) { if (!tls) { diff --git a/src/tls/openssl.c b/src/tls/openssl.c index 84216cdc776..eb4b879e9a2 100644 --- a/src/tls/openssl.c +++ b/src/tls/openssl.c @@ -301,6 +301,20 @@ int tls_context_alpn_set(void *ctx_backend, const char *alpn) return result; } +static int tls_context_set_verify_client(void *ctx_backend, int verify_client) +{ + struct tls_context *ctx = ctx_backend; + int mode; + + if (ctx->mode == FLB_TLS_SERVER_MODE && verify_client == FLB_TRUE) { + mode = SSL_CTX_get_verify_mode(ctx->ctx); + mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + SSL_CTX_set_verify(ctx->ctx, mode, NULL); + } + + return 0; +} + #ifdef _MSC_VER /* Parse certstore_name prefix like * @@ -801,7 +815,8 @@ static void *tls_context_create(int verify, SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL); } else { - SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); + int verify_flags = SSL_VERIFY_PEER; + SSL_CTX_set_verify(ssl_ctx, verify_flags, NULL); } /* ca_path | ca_file */ @@ -1574,6 +1589,7 @@ static struct flb_tls_backend tls_openssl = { .context_create = tls_context_create, .context_destroy = tls_context_destroy, .context_alpn_set = tls_context_alpn_set, + .context_set_verify_client = tls_context_set_verify_client, .session_alpn_get = tls_session_alpn_get, .set_minmax_proto = tls_set_minmax_proto, .set_ciphers = tls_set_ciphers,