question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ChannelOptions doesn't work well in client tls connection

See original GitHub issue

Problem description

In TLS connection scenaio, the client implemented by nodejs(which depends on grpc-js) cannot connect to server. I got the error messages from c++ server ssl_transport_security.cc:1847] No match found for server name: localhost., and no error message from nodejs server.

The certs is signed with a special dns name, and the client uses localhost to connect. So, I use ChannelOptions in node/ChannelArguments in c++ to define the grpc.default_authority. In this way, the c++ client(actually, including java/kotlin/csharp/python/rust/go) works well.

I’m not sure if it’s an issue or my mistake. Please help to check:

my nodejs client node

let address = connectTo + ":" + port
    let secure = process.env.GRPC_HELLO_SECURE
    if (typeof secure !== 'undefined' && secure !== null) {
        logger.info("Connect With TLS(%s)", port)
        let rootCertContent = fs.readFileSync(certChain);
        let privateKeyContent = fs.readFileSync(certKey);
        let certChainContent = fs.readFileSync(certChain);
        const credentials = grpc.credentials.createSsl(rootCertContent, privateKeyContent, certChainContent);
        //https://grpc.github.io/grpc/core/group__grpc__arg__keys.html
        const channelOptions = {
            'grpc.default_authority': serverName
        }
        return new services.LandingServiceClient(address, credentials, channelOptions)
    } else {
        logger.info("Connect With InSecure(%s)", port)
        return new services.LandingServiceClient(address, grpc.credentials.createInsecure())
    }

my c++ client code

const string &port = Utils::getBackendPort();
        const basic_string<char, char_traits<char>, allocator<char>> &target = Utils::getBackend() + ":" + port;
        const string &secure = Utils::getSecure();
        if (!secure.empty() && secure == "Y") {
            grpc::SslCredentialsOptions ssl_opts;
            ssl_opts.pem_root_certs = Connection::getFileContent(certChain);
            ssl_opts.pem_private_key = Connection::getFileContent(certKey);
            ssl_opts.pem_cert_chain = Connection::getFileContent(certChain);
            grpc::ChannelArguments channel_args;
            channel_args.SetString("grpc.default_authority", serverName);
            LOG(INFO) << "Connect with TLS(" << port << ")";
            return grpc::CreateCustomChannel(target, grpc::SslCredentials(ssl_opts), channel_args);
        } else {
            LOG(INFO) << "Connect with InSecure(" << port << ")";
            return grpc::CreateChannel(target, grpc::InsecureChannelCredentials());
        }

Reproduction steps

Clone and go to this folder: https://github.com/feuyeux/hello-grpc/tree/main/grpc/hello-grpc-nodejs

Run the below scripts on two terminals:

export GRPC_HELLO_SECURE="Y" 
sh server_start.sh
export GRPC_HELLO_SECURE="Y" 
sh client_start.sh

Environment

  • OS name, version and architecture: macOS 11.6
  • Node version: v16.13.0 and v17.0.1(need to remove sleep lib)
  • Node installation method: brew
  • Package name and version: package.json

Additional context

https://github.com/feuyeux/hello-grpc

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
murgatroid99commented, Dec 16, 2021

I also want to mention that I will be off for the rest of the year. I will continue to look into this in January, but I do not expect to respond again until then.

1reaction
murgatroid99commented, Dec 16, 2021

I managed to run your Node example. When I have the Node client communicate with the Node server, the server does not report any error like the one you mentioned, but the client actually gets an error that says “unsupported certificate purpose”. I can’t tell why that is happening in this example, but from my research that seems to be some kind of problem with the “X509v3 Extended Key Usage” field in the certificate.

I am still trying to get your C++ example to build, so I have not tested the Node client with the C++ server yet, but one suggestion I have is to not use client authentication (don’t provide the certificate or key to credentials.createSsl) just to simplify the TLS interaction that we are trying to debug. Does that still result in the same error? In addition, can you run the client with the environment variables GRPC_TRACE=subchannel and GRPC_VERBOSITY=DEBUG and look for a line that starts like this:

D 2021-12-16T15:19:14.817Z | subchannel | (3) 127.0.0.1:9996 connection closed with error...

We know what error the server sees, but that line should provide more information about what error the client is seeing when the connection fails.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Troubleshoot gRPC on .NET Core - Microsoft Learn
Without TLS, all connections to the endpoint default to HTTP/1.1, and gRPC calls fail. The gRPC client must also be configured to not...
Read more >
Grpc .Net client fails to connect to server with SSL
I made a working client on the .NET Framework c with a server on .NET Core on localhost: static async Task Main(string[] args)...
Read more >
Authentication - gRPC
Using client-side SSL/TLS. Now let's look at how Credentials work with one of our supported auth mechanisms. This is the simplest authentication ...
Read more >
gRPC Python 1.46.2 documentation
The connections created by local channel credentials are not encrypted, ... every new client connection before starting the TLS handshake with the client, ......
Read more >
Reactor Netty Reference Guide
You do not need to read this guide in a linear fashion. ... In order to send data to a connected client, you...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found