Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OTLP exporter assumes it must use SSL because GetOtlpDefaultIsSslEnable() is returning a wrong value #2058

Closed
MrSparc opened this issue Mar 15, 2023 · 6 comments · Fixed by #2060
Assignees
Labels
bug Something isn't working

Comments

@MrSparc
Copy link
Contributor

MrSparc commented Mar 15, 2023

Describe your environment

  • opentelemetry-cpp v1.8.3
  • OTLP gRPC
  • No SSL
  • No OTLP env vars, just default settings

Steps to reproduce
I'm facing an issue with SSL after upgrade from v1.8.2 to v1.8.3 with my gRPC telemetry.
The error is:

E0315 15:58:51.193959723  145649 ssl_transport_security.cc:1501] Handshake failed with fatal error SSL_ERROR_SSL: error:1408F10B:SSL routines:ssl3_get_record:wrong version number.

So debugging and comparing the behavior of both versions, I noticed that in v1.8.2 OtlpGrpcExporterOptions constructor is setting as default use_ssl_credentials: false but in the new v1.8.3 this default constructor is setting to use_ssl_credentials: true

This looks like a behaviour change introduced by this refactoring handling Boolean environment variables #1982

Digging into the code to look the initialization of use_ssl_credentials in the constructor:

struct OtlpGrpcExporterOptions
{
// The endpoint to export to. By default the OpenTelemetry Collector's default endpoint.
std::string endpoint = GetOtlpDefaultGrpcEndpoint();
// By default when false, uses grpc::InsecureChannelCredentials(); If true,
// uses ssl_credentials_cacert_path if non-empty, else uses ssl_credentials_cacert_as_string
bool use_ssl_credentials = GetOtlpDefaultIsSslEnable();

This method GetOtlpDefaultIsSslEnable() to initialize use_ssl_credentials is based on GetOtlpDefaultTracesIsInsecure():

// Compatibility with OTELCPP 1.8.2
inline bool GetOtlpDefaultIsSslEnable()
{
return (!GetOtlpDefaultTracesIsInsecure());
}

The issue is in the default return value of the following methods:

All these methods are returning by default false if no env vars are defined.
So a false return means, IS NOT insecure, then IS secure 🤯

I don't know the gRPC transpost must be by default secure or insecure, but if the default is secure then this behaviour was enforced in this version.

According to the specification:
Insecure: Whether to enable client transport security for the exporter's gRPC connection. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme

So, if the gRPC endpoint scheme returns 'http' or 'https' as the following default, I think this value should overrided:

std::string GetOtlpDefaultGrpcTracesEndpoint()
{
constexpr char kSignalEnv[] = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
constexpr char kGenericEnv[] = "OTEL_EXPORTER_OTLP_ENDPOINT";
constexpr char kDefault[] = "http://localhost:4317";

What is the expected behavior?
Upgrade from v1.8.2 to v1.8.3 without issues.

What is the actual behavior?
Upgrade to v1.8.3 wrongly assumes that gRPC connection are using SSL and fails because no certificates are defined.

Additional context
As workaround I need to set the env var OTEL_EXPORTER_OTLP_INSECURE=true in order to do not use SSL

@MrSparc MrSparc added the bug Something isn't working label Mar 15, 2023
@marcalff
Copy link
Member

@MrSparc

Thanks for the report, and for the detailed analysis.

So debugging and comparing the behavior of both versions, I noticed that in v1.8.2 OtlpGrpcExporterOptions constructor is setting as default use_ssl_credentials: false but in the new v1.8.3 this default constructor is setting to use_ssl_credentials: true

This looks like a behaviour change introduced by this refactoring handling Boolean environment variables #1982

It is, and I am the one to blame here.

According to the specification: Insecure: Whether to enable client transport security for the exporter's gRPC connection. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme

So, if the gRPC endpoint scheme returns 'http' or 'https' as the following default, I think this value should overrided:

So, the important part is:

  • This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme

The evaluation of OTEL_EXPORTER_OTLP_TRACES_INSECURE to false by default is per the spec.

What was missed is that this variable should not be used if the endpoint provides an http or https scheme, because the scheme takes precedence.

This is a valid bug report.

@marcalff
Copy link
Member

Related to this spec change:

@MrSparc
Copy link
Contributor Author

MrSparc commented Mar 15, 2023

Thanks @marcalff for your fast feedback and the PR proposal to improve it.
The otel-cpp team are the best 👌
Thanks for the amazing work all you are doing for the dev community!

@marcalff
Copy link
Member

@MrSparc

Thanks.

A fix is available, ready for review and test if you want to try it out:

Feel free to comment on the PR.

@marcalff marcalff self-assigned this Mar 16, 2023
@compoundradius
Copy link

Came here to report the same issue, but without the great analysis. Thanks!

@compoundradius
Copy link

compoundradius commented Mar 16, 2023

Here to report that your fix works properly!
Checked against:

git status
On branch fix_otlp_grpc_ssl_default_2058
Your branch is up to date with 'origin/fix_otlp_grpc_ssl_default_2058'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
3 participants