From 00c903c3d7cc86ce2622cc416de57464ab5b1a69 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Wed, 23 Oct 2024 11:22:27 +0900 Subject: [PATCH 01/12] feat(): Add mTLS Support for OTLP Exporter --- .../.publicApi/Stable/PublicAPI.Unshipped.txt | 6 ++ .../ExportClient/OtlpHttpLogExportClient.cs | 22 ++++- .../OtlpHttpMetricsExportClient.cs | 22 ++++- .../ExportClient/OtlpHttpTraceExportClient.cs | 22 ++++- .../OtlpExporterOptions.cs | 82 +++++++++++++++++++ .../OtlpExporterOptionsExtensions.cs | 34 +++++++- 6 files changed, 184 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt index e69de29bb2d..a8e346f06de 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/.publicApi/Stable/PublicAPI.Unshipped.txt @@ -0,0 +1,6 @@ +OpenTelemetry.Exporter.OtlpExporterOptions.CertificateFile.get -> string! +OpenTelemetry.Exporter.OtlpExporterOptions.CertificateFile.set -> void +OpenTelemetry.Exporter.OtlpExporterOptions.ClientCertificateFile.get -> string! +OpenTelemetry.Exporter.OtlpExporterOptions.ClientCertificateFile.set -> void +OpenTelemetry.Exporter.OtlpExporterOptions.ClientKeyFile.get -> string! +OpenTelemetry.Exporter.OtlpExporterOptions.ClientKeyFile.set -> void diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpHttpLogExportClient.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpHttpLogExportClient.cs index 6347ece8f3b..2e83705f697 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpHttpLogExportClient.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpHttpLogExportClient.cs @@ -19,7 +19,7 @@ internal sealed class OtlpHttpLogExportClient : BaseOtlpHttpExportClient[] StandardHeaders = new KeyValuePair[] { @@ -75,6 +81,36 @@ internal OtlpExporterOptions( }; this.BatchExportProcessorOptions = defaultBatchOptions!; + + // Load CertificateFile from environment variable + if (Environment.GetEnvironmentVariable(CertificateFileEnvVarName) is string certificateFile) + { + this.CertificateFile = certificateFile; + } + else + { + this.CertificateFile = string.Empty; + } + + // Load ClientKeyFile from environment variable + if (Environment.GetEnvironmentVariable(ClientKeyFileEnvVarName) is string clientKeyFile) + { + this.ClientKeyFile = clientKeyFile; + } + else + { + this.ClientKeyFile = string.Empty; + } + + // Load ClientCertificateFile from environment variable + if (Environment.GetEnvironmentVariable(ClientCertificateFileEnvVarName) is string clientCertificateFile) + { + this.ClientCertificateFile = clientCertificateFile; + } + else + { + this.ClientCertificateFile = string.Empty; + } } /// @@ -142,6 +178,21 @@ public Func HttpClientFactory } } + /// + /// Gets or sets the trusted certificate to use when verifying a server's TLS credentials. + /// + public string CertificateFile { get; set; } + + /// + /// Gets or sets the path to the private key to use in mTLS communication in PEM format. + /// + public string ClientKeyFile { get; set; } + + /// + /// Gets or sets the path to the certificate/chain trust for client's private key to use in mTLS communication in PEM format. + /// + public string ClientCertificateFile { get; set; } + /// /// Gets a value indicating whether or not the signal-specific path should /// be appended to . @@ -220,6 +271,37 @@ internal OtlpExporterOptions ApplyDefaults(OtlpExporterOptions defaultExporterOp return this; } + internal HttpMessageHandler CreateDefaultHttpMessageHandler() + { + var handler = new HttpClientHandler(); + +#if NET6_0_OR_GREATER + if (!string.IsNullOrEmpty(this.CertificateFile)) + { + var trustedCertificate = new X509Certificate2(this.CertificateFile); + + handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => + { + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(trustedCertificate); + return chain.Build(cert); + }; + } + + if (!string.IsNullOrEmpty(this.ClientCertificateFile) && !string.IsNullOrEmpty(this.ClientKeyFile)) + { + var clientCertificate = X509Certificate2.CreateFromPemFile(this.ClientCertificateFile, this.ClientKeyFile); + handler.ClientCertificates.Add(clientCertificate); + } +#else + // Implement alternative methods for earlier .NET versions + throw new PlatformNotSupportedException("mTLS support requires .NET 6.0 or later."); +#endif + +#pragma warning disable CS0162 // Unreachable code detected + return handler; + } + private static string GetUserAgentString() { var assembly = typeof(OtlpExporterOptions).Assembly; diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index b755e15880b..dbbca97df7d 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -17,6 +17,9 @@ using LogOtlpCollector = OpenTelemetry.Proto.Collector.Logs.V1; using MetricsOtlpCollector = OpenTelemetry.Proto.Collector.Metrics.V1; using TraceOtlpCollector = OpenTelemetry.Proto.Collector.Trace.V1; +#if NET6_0_OR_GREATER +using System.Security.Cryptography.X509Certificates; +#endif namespace OpenTelemetry.Exporter; @@ -33,7 +36,36 @@ public static Channel CreateChannel(this OtlpExporterOptions options) throw new NotSupportedException($"Endpoint URI scheme ({options.Endpoint.Scheme}) is not supported. Currently only \"http\" and \"https\" are supported."); } -#if NETSTANDARD2_1 || NET +#if NET6_0_OR_GREATER + var handler = new HttpClientHandler(); + + // Set up custom certificate validation if CertificateFile is provided + if (!string.IsNullOrEmpty(options.CertificateFile)) + { + var trustedCertificate = new X509Certificate2(options.CertificateFile); + handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => + { + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(trustedCertificate); + return chain.Build(cert); + }; + } + + // Set up client certificate if provided + if (!string.IsNullOrEmpty(options.ClientCertificateFile) && !string.IsNullOrEmpty(options.ClientKeyFile)) + { + var clientCertificate = X509Certificate2.CreateFromPemFile(options.ClientCertificateFile, options.ClientKeyFile); + handler.ClientCertificates.Add(clientCertificate); + } + + var grpcChannelOptions = new GrpcChannelOptions + { + HttpHandler = handler, + DisposeHttpClient = true, + }; + + return GrpcChannel.ForAddress(options.Endpoint, grpcChannelOptions); +#elif NETSTANDARD2_1 || NET return GrpcChannel.ForAddress(options.Endpoint); #else ChannelCredentials channelCredentials; From 0d0aa98ae1a179c8f981f16e20a8d598236a328e Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sun, 27 Oct 2024 11:29:41 +0700 Subject: [PATCH 02/12] feat(): feat: Add certificate handling in HttpClientFactory using X509CertificateLoader --- .../ExportClient/OtlpHttpLogExportClient.cs | 22 +----- .../OtlpHttpMetricsExportClient.cs | 22 +----- .../ExportClient/OtlpHttpTraceExportClient.cs | 22 +----- .../OtlpExporterOptions.cs | 69 +++++++++++++++---- .../OtlpExporterOptionsExtensions.cs | 11 ++- 5 files changed, 67 insertions(+), 79 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpHttpLogExportClient.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpHttpLogExportClient.cs index 2e83705f697..6347ece8f3b 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpHttpLogExportClient.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/ExportClient/OtlpHttpLogExportClient.cs @@ -19,7 +19,7 @@ internal sealed class OtlpHttpLogExportClient : BaseOtlpHttpExportClient { + #if NET6_0_OR_GREATER + // Create a new handler + var handler = new HttpClientHandler(); + + // Load server certificate + if (!string.IsNullOrEmpty(this.CertificateFile)) + { + var trustedCertificate = X509CertificateLoader.LoadFromFile(this.CertificateFile); + + handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => + { + if (cert != null && chain != null) + { + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(trustedCertificate); + return chain.Build(cert); + } + return false; + }; + } + + // Load client certificate for mTLS + if (!string.IsNullOrEmpty(this.ClientCertificateFile) && !string.IsNullOrEmpty(this.ClientKeyFile)) + { + var clientCertificate = X509Certificate2.CreateFromPemFile(this.ClientCertificateFile, this.ClientKeyFile); + handler.ClientCertificates.Add(clientCertificate); + } + + // Create and return the HttpClient + return new HttpClient(handler) + { + Timeout = TimeSpan.FromMilliseconds(this.TimeoutMilliseconds), + }; + #else + // For earlier .NET versions return new HttpClient { Timeout = TimeSpan.FromMilliseconds(this.TimeoutMilliseconds), }; + #endif }; this.BatchExportProcessorOptions = defaultBatchOptions!; @@ -271,35 +307,42 @@ internal OtlpExporterOptions ApplyDefaults(OtlpExporterOptions defaultExporterOp return this; } - internal HttpMessageHandler CreateDefaultHttpMessageHandler() + internal HttpClient AddCertificatesToHttpClient(HttpClientHandler handler) { - var handler = new HttpClientHandler(); - -#if NET6_0_OR_GREATER + #if NET6_0_OR_GREATER + // Set up server certificate validation if CertificateFile is provided if (!string.IsNullOrEmpty(this.CertificateFile)) { + // Load the certificate from the file var trustedCertificate = new X509Certificate2(this.CertificateFile); + // Set custom server certificate validation callback handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { - chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; - chain.ChainPolicy.CustomTrustStore.Add(trustedCertificate); - return chain.Build(cert); + if (cert != null && chain != null) + { + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(trustedCertificate); + return chain.Build(cert); + } + return false; }; } + // Add client certificate if both files are provided if (!string.IsNullOrEmpty(this.ClientCertificateFile) && !string.IsNullOrEmpty(this.ClientKeyFile)) { + // Load the client certificate from PEM files var clientCertificate = X509Certificate2.CreateFromPemFile(this.ClientCertificateFile, this.ClientKeyFile); handler.ClientCertificates.Add(clientCertificate); } -#else - // Implement alternative methods for earlier .NET versions - throw new PlatformNotSupportedException("mTLS support requires .NET 6.0 or later."); -#endif -#pragma warning disable CS0162 // Unreachable code detected - return handler; + // Create and return an HttpClient with the modified handler + return new HttpClient(handler); + #else + // Handle alternative methods for earlier .NET versions + throw new PlatformNotSupportedException("mTLS support requires .NET 6.0 or later."); + #endif } private static string GetUserAgentString() diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index dbbca97df7d..cd7c525b52d 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -45,9 +45,14 @@ public static Channel CreateChannel(this OtlpExporterOptions options) var trustedCertificate = new X509Certificate2(options.CertificateFile); handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { - chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; - chain.ChainPolicy.CustomTrustStore.Add(trustedCertificate); - return chain.Build(cert); + if (cert != null && chain != null) + { + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(trustedCertificate); + return chain.Build(cert); + } + + return false; }; } From e7c6f5b8408d11e5236f82780bbd6ba1b8624ac1 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sun, 27 Oct 2024 11:33:16 +0700 Subject: [PATCH 03/12] feat(): feat: Add certificate handling in HttpClientFactory using X509CertificateLoader --- .../OtlpExporterOptions.cs | 2 +- .../OtlpExporterOptionsExtensions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs index 04517e35c88..778c6e06602 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs @@ -81,7 +81,7 @@ internal OtlpExporterOptions( // Load server certificate if (!string.IsNullOrEmpty(this.CertificateFile)) { - var trustedCertificate = X509CertificateLoader.LoadFromFile(this.CertificateFile); + var trustedCertificate = X509Certificate2.CreateFromPemFile(this.CertificateFile); handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index cd7c525b52d..614f3803c3b 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -42,7 +42,7 @@ public static Channel CreateChannel(this OtlpExporterOptions options) // Set up custom certificate validation if CertificateFile is provided if (!string.IsNullOrEmpty(options.CertificateFile)) { - var trustedCertificate = new X509Certificate2(options.CertificateFile); + var trustedCertificate = X509Certificate2.CreateFromPemFile(options.CertificateFile); handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { if (cert != null && chain != null) From 3b43fd347a65fb75fa94673730852fd26ab07367 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sun, 27 Oct 2024 11:34:28 +0700 Subject: [PATCH 04/12] feat(): feat: Add certificate handling in HttpClientFactory using X509CertificateLoader --- .../OtlpExporterOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs index 778c6e06602..81233913b86 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs @@ -314,7 +314,7 @@ internal HttpClient AddCertificatesToHttpClient(HttpClientHandler handler) if (!string.IsNullOrEmpty(this.CertificateFile)) { // Load the certificate from the file - var trustedCertificate = new X509Certificate2(this.CertificateFile); + var trustedCertificate = X509Certificate2.CreateFromPemFile(this.CertificateFile); // Set custom server certificate validation callback handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => From 4b6d3cda44c53379ebc08d08ec3afaec0f86bb43 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sun, 27 Oct 2024 11:35:29 +0700 Subject: [PATCH 05/12] feat(): feat: Add certificate handling in HttpClientFactory using X509CertificateLoader --- .../OtlpExporterOptions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs index 81233913b86..b88467d48bd 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs @@ -91,6 +91,7 @@ internal OtlpExporterOptions( chain.ChainPolicy.CustomTrustStore.Add(trustedCertificate); return chain.Build(cert); } + return false; }; } @@ -325,6 +326,7 @@ internal HttpClient AddCertificatesToHttpClient(HttpClientHandler handler) chain.ChainPolicy.CustomTrustStore.Add(trustedCertificate); return chain.Build(cert); } + return false; }; } From 5864dbfba4e14c456f4315eda2dcb1b069c10491 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sun, 27 Oct 2024 20:00:11 +0700 Subject: [PATCH 06/12] feat(): feat: Add certificate handling in HttpClientFactory using X509CertificateLoader --- .../OtlpExporterOptions.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs index b88467d48bd..c42c1bba1eb 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs @@ -74,7 +74,7 @@ internal OtlpExporterOptions( this.DefaultHttpClientFactory = () => { - #if NET6_0_OR_GREATER +#if NET6_0_OR_GREATER // Create a new handler var handler = new HttpClientHandler(); @@ -108,13 +108,13 @@ internal OtlpExporterOptions( { Timeout = TimeSpan.FromMilliseconds(this.TimeoutMilliseconds), }; - #else +#else // For earlier .NET versions return new HttpClient { Timeout = TimeSpan.FromMilliseconds(this.TimeoutMilliseconds), }; - #endif +#endif }; this.BatchExportProcessorOptions = defaultBatchOptions!; @@ -310,7 +310,7 @@ internal OtlpExporterOptions ApplyDefaults(OtlpExporterOptions defaultExporterOp internal HttpClient AddCertificatesToHttpClient(HttpClientHandler handler) { - #if NET6_0_OR_GREATER +#if NET6_0_OR_GREATER // Set up server certificate validation if CertificateFile is provided if (!string.IsNullOrEmpty(this.CertificateFile)) { @@ -341,10 +341,10 @@ internal HttpClient AddCertificatesToHttpClient(HttpClientHandler handler) // Create and return an HttpClient with the modified handler return new HttpClient(handler); - #else +#else // Handle alternative methods for earlier .NET versions throw new PlatformNotSupportedException("mTLS support requires .NET 6.0 or later."); - #endif +#endif } private static string GetUserAgentString() From 2e7e412deee2accac434962f58d26392319ca954 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Mon, 11 Nov 2024 20:21:42 +0900 Subject: [PATCH 07/12] feat(): Add mTLS Support for OTLP Exporter --- .../OtlpExporterOptionsExtensions.cs | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index 614f3803c3b..0c16c28cb23 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -282,6 +282,7 @@ public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptio binder: null, new Type[] { typeof(string) }, modifiers: null); + if (createClientMethod != null) { HttpClient? client = (HttpClient?)createClientMethod.Invoke(httpClientFactory, new object[] { httpClientName }); @@ -290,7 +291,38 @@ public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptio { client.Timeout = TimeSpan.FromMilliseconds(options.TimeoutMilliseconds); - return client; + // Set up a new HttpClientHandler to configure certificates and callbacks + var handler = new HttpClientHandler(); + + #if NET6_0_OR_GREATER + // Add server certificate validation + if (!string.IsNullOrEmpty(options.CertificateFile)) + { + var trustedCertificate = X509Certificate2.CreateFromPemFile(options.CertificateFile); + handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => + { + if (cert != null && chain != null) + { + chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust; + chain.ChainPolicy.CustomTrustStore.Add(trustedCertificate); + return chain.Build(cert); + } + return false; + }; + } + + // Add client certificate + if (!string.IsNullOrEmpty(options.ClientCertificateFile) && !string.IsNullOrEmpty(options.ClientKeyFile)) + { + var clientCertificate = X509Certificate2.CreateFromPemFile(options.ClientCertificateFile, options.ClientKeyFile); + handler.ClientCertificates.Add(clientCertificate); + } + #else + throw new PlatformNotSupportedException("mTLS support requires .NET 6.0 or later."); + #endif + + // Re-create HttpClient using the custom handler + return new HttpClient(handler) { Timeout = client.Timeout }; } } } From afc8df69719e8a11e51ca29501539c782f6c35e4 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Mon, 11 Nov 2024 20:39:15 +0900 Subject: [PATCH 08/12] feat(): Add mTLS Support for OTLP Exporter --- .../OtlpExporterOptionsExtensions.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index 0c16c28cb23..9a920081107 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -294,7 +294,7 @@ public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptio // Set up a new HttpClientHandler to configure certificates and callbacks var handler = new HttpClientHandler(); - #if NET6_0_OR_GREATER +#if NET6_0_OR_GREATER // Add server certificate validation if (!string.IsNullOrEmpty(options.CertificateFile)) { @@ -317,12 +317,12 @@ public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptio var clientCertificate = X509Certificate2.CreateFromPemFile(options.ClientCertificateFile, options.ClientKeyFile); handler.ClientCertificates.Add(clientCertificate); } - #else - throw new PlatformNotSupportedException("mTLS support requires .NET 6.0 or later."); - #endif // Re-create HttpClient using the custom handler return new HttpClient(handler) { Timeout = client.Timeout }; +#else + throw new PlatformNotSupportedException("mTLS support requires .NET 6.0 or later."); +#endif } } } From c5101b111b395a7da6b950863f54d695c7cb1009 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Mon, 11 Nov 2024 20:42:43 +0900 Subject: [PATCH 09/12] feat(): Add mTLS Support for OTLP Exporter --- .../OtlpExporterOptionsExtensions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index 9a920081107..737037d3c1c 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -307,6 +307,7 @@ public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptio chain.ChainPolicy.CustomTrustStore.Add(trustedCertificate); return chain.Build(cert); } + return false; }; } From 84a4d5b5a61eefd12084f032241dc772263f6393 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Mon, 11 Nov 2024 21:29:23 +0900 Subject: [PATCH 10/12] feat(): Add mTLS Support for OTLP Exporter --- .../OtlpExporterOptionsExtensions.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index 737037d3c1c..21cd1432cb7 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -319,11 +319,12 @@ public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptio handler.ClientCertificates.Add(clientCertificate); } - // Re-create HttpClient using the custom handler - return new HttpClient(handler) { Timeout = client.Timeout }; #else - throw new PlatformNotSupportedException("mTLS support requires .NET 6.0 or later."); + Debug.WriteLine("Warning: mTLS support requires .NET 6.0 or later. Defaulting to insecure HttpClient."); #endif + + // Re-create HttpClient using the custom handler + return new HttpClient(handler) { Timeout = client.Timeout }; } } } From 716949cc510d1ddd23ce1e80e768c014e1e85871 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Mon, 11 Nov 2024 21:31:04 +0900 Subject: [PATCH 11/12] feat(): Add mTLS Support for OTLP Exporter --- .../OtlpExporterOptionsExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index 21cd1432cb7..0ee42585908 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -320,7 +320,7 @@ public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptio } #else - Debug.WriteLine("Warning: mTLS support requires .NET 6.0 or later. Defaulting to insecure HttpClient."); + Console.WriteLine("Warning: mTLS support requires .NET 6.0 or later. Defaulting to insecure HttpClient."); #endif // Re-create HttpClient using the custom handler From 2781534b62585ab5291e2558970a0f0a22d6ec8f Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Mon, 11 Nov 2024 21:33:32 +0900 Subject: [PATCH 12/12] feat(): Add mTLS Support for OTLP Exporter --- .../OtlpExporterOptionsExtensions.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs index 0ee42585908..ddec1827289 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptionsExtensions.cs @@ -295,7 +295,7 @@ public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptio var handler = new HttpClientHandler(); #if NET6_0_OR_GREATER - // Add server certificate validation + // Add server certificate validation if CertificateFile is specified if (!string.IsNullOrEmpty(options.CertificateFile)) { var trustedCertificate = X509Certificate2.CreateFromPemFile(options.CertificateFile); @@ -312,19 +312,24 @@ public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptio }; } - // Add client certificate + // Add client certificate if ClientCertificateFile and ClientKeyFile are specified if (!string.IsNullOrEmpty(options.ClientCertificateFile) && !string.IsNullOrEmpty(options.ClientKeyFile)) { var clientCertificate = X509Certificate2.CreateFromPemFile(options.ClientCertificateFile, options.ClientKeyFile); handler.ClientCertificates.Add(clientCertificate); } -#else - Console.WriteLine("Warning: mTLS support requires .NET 6.0 or later. Defaulting to insecure HttpClient."); -#endif - // Re-create HttpClient using the custom handler return new HttpClient(handler) { Timeout = client.Timeout }; + +#else + // Throw only if certificates are required but the environment is unsupported + if (!string.IsNullOrEmpty(options.CertificateFile) || + (!string.IsNullOrEmpty(options.ClientCertificateFile) && !string.IsNullOrEmpty(options.ClientKeyFile))) + { + throw new PlatformNotSupportedException("mTLS support requires .NET 6.0 or later."); + } +#endif } } }