apm-agent-dotnet
apm-agent-dotnet copied to clipboard
[BUG] Cannot connect to APM server which supports only TLSv1.3
APM Agent version
1.20.0
Environment
Operating system and version: Ubuntu 20.04.5 LTS
.NET Framework/Core name and version (e.g. .NET 4.6.1, NET Core 3.1.100) : .NET SDK 7.0.102
Application Target Framework(s) (e.g. net461, netcoreapp3.1): net7.0
Describe the bug
After upgrading to 1.20.0 nothing is sent to APM server, because it fails the TLS handshake:
{"log.level":"error","@timestamp":"2023-03-05T11:03:29.598+0200","log.logger":"beater.http","log.origin":{"file.name":"http/server.go","file.line":3195},"message":"http: TLS handshake error from 10.10.12.162:33834: tls: client offered only unsupported versions: [303 302 301]","service.name":"apm-server","ecs.version":"1.6.0"}
To Reproduce
Steps to reproduce the behavior:
- APM server configuration:
ssl:
enabled: true
certificate: '/path/to/certificate.crt'
key: '/path/to/key.key'
key_passphrase: '${KEY_PASSPHRASE}'
supported_protocols: [TLSv1.3]
-
appsettings.json
"ElasticApm": {
"Enabled": true,
"CentralConfig": false,
"ServiceName": "Foo",
"ServerUrl": "https://apm.some.fully.qualified.name.com:8200"
}
-
Startup.cs
application.UseElasticApm(
_configuration,
new AspNetCoreDiagnosticSubscriber(),
new HttpDiagnosticsSubscriber(),
new EfCoreDiagnosticsSubscriber(),
new ElasticsearchDiagnosticsSubscriber());
After switching supported_protocols: [TLSv1.3]
to supported_protocols: [TLSv1.3,TLSv1.2]
the connection is established successfully and the APM agent works as expected. I'm guessing this is related to #1926.
Expected behavior
TLSv1.3 works same as it did in 1.19.0
Actual behavior
TLSv1.3 does not work
I have the same issue after upgraded Elastic.Apm to 1.20+
A possible solution might be to change in BackendCommUtils.cs from:
#if !NET462
httpClientHandler.ServerCertificateCustomValidationCallback = serverCertificateCustomValidationCallback;
logger.Info()?.Log("CreateHttpClientHandler - Setting ServerCertificateCustomValidationCallback");
httpClientHandler.SslProtocols |= SslProtocols.Tls12;
logger.Info()?.Log("CreateHttpClientHandler - SslProtocols: {SslProtocols}", httpClientHandler.SslProtocols);
#else
// We don't set the ServerCertificateCustomValidationCallback on ServicePointManager here as it would
// apply to the whole AppDomain and that may not be desired. A consumer can set this themselves if they
// need custom validation behaviour.
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
logger.Info()?.Log("CreateHttpClientHandler - SslProtocols: {SslProtocols}", ServicePointManager.SecurityProtocol);
#endif
to something like:
#if NET6_0_OR_GREATER
httpClientHandler.SslProtocols |= SslProtocols.Tls12;
httpClientHandler.SslProtocols |= SslProtocols.Tls13;
logger.Info()?.Log("CreateHttpClientHandler - SslProtocols: {SslProtocols}", httpClientHandler.SslProtocols);
#elif NETFRAMEWORK
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
logger.Info()?.Log("CreateHttpClientHandler - SslProtocols: {SslProtocols}", ServicePointManager.SecurityProtocol);
#else
httpClientHandler.SslProtocols |= SslProtocols.Tls12;
logger.Info()?.Log("CreateHttpClientHandler - SslProtocols: {SslProtocols}", httpClientHandler.SslProtocols);
#endif
#if !NET462
httpClientHandler.ServerCertificateCustomValidationCallback = serverCertificateCustomValidationCallback;
logger.Info()?.Log("CreateHttpClientHandler - Setting ServerCertificateCustomValidationCallback");
#else
// We don't set the ServerCertificateCustomValidationCallback on ServicePointManager here as it would
// apply to the whole AppDomain and that may not be desired. A consumer can set this themselves if they
// need custom validation behaviour.
#endif