C++ GRPC客户端和Golang服务器之间的连接错误。

huangapple go评论96阅读模式
英文:

connection error between C++ GRPC client and golang server

问题

我正在尝试编写一个与C++和Golang客户端通信的GRPC服务器。由于这都是在我们系统内部进行的,将使用自签名证书对服务器证书进行签名,并且服务器将对客户端证书进行签名。

我能够从Golang客户端连接到服务器。然而,C++客户端无法连接,并且我看到了一堆来自ssl层的错误。在配置C++ grpc客户端时,我做错了什么?

(目前,我的所有证书都使用2048位RSA密钥)

以下是我认为等效的客户端代码(省略了错误处理):

Golang:

import (
    "crypto/tls"
    "io/ioutil"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"
)

func getConnection(hostPort string) (*grpc.ClientConn, error) {
    var config tls.Config
    cert, _ := tls.LoadX509KeyPair("client.crt", "client.key")
    config.Certificates = append(config.Certificates, cert)
    b, _ := ioutil.ReadFile("root.crt")
    config.RootCAs.AppendCertsFromPEM(b)

    options := grpc.WithTransportCredentials(credentials.NewTLS(config))
    return grpc.Dial(hostPort, options)
}

C++:

#include <fstream>
#include <string>
#include <grpc++/grpc++.h>

std::shared_ptr<grpc::Channel> get_connection(const std::string& host_port) {
    auto contents = [](const std::string& filename) -> std::string {
        std::ifstream fh(filename);
        std::stringstream buffer;
        buffer << fh.rdbuf();
        fh.close();
        return buffer.str();
    };

    auto ssl_options = grpc::SslCredentialsOptions();
    ssl_options.pem_cert_chain = contents("client.crt");
    ssl_options.pem_private_key = contents("client.key");
    ssl_options.pem_root_certs = contents("root.crt");
    auto creds = grpc::SslCredentials(ssl_options);
    auto channel = grpc::CreateChannel(hostport, creds);
}

我的错误消息:

C++客户端错误消息

D0322 14:42:12.882767371   11701 env_linux.c:77]             Warning: insecure environment read function 'getenv' used
getting job record
E0322 14:42:12.930157873   11701 ssl_transport_security.c:945] Handshake failed with fatal error SSL_ERROR_SSL: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed.
E0322 14:42:12.930231627   11701 handshake.c:128]            Security handshake failed: {"created":"@1490218932.930210185","description":"Handshake failed","file":"src/core/lib/security/transport/handshake.c","file_line":264,"tsi_code":10,"tsi_error":"TSI_PROTOCOL_FAILURE"}
E0322 14:42:12.964082644   11701 ssl_transport_security.c:945] Handshake failed with fatal error SSL_ERROR_SSL: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed.
E0322 14:42:12.964134746   11701 handshake.c:128]            Security handshake failed: {"created":"@1490218932.964114213","description":"Handshake failed","file":"src/core/lib/security/transport/handshake.c","file_line":264,"tsi_code":10,"tsi_error":"TSI_PROTOCOL_FAILURE"}
std::string JobServerClient::getJobRecord(const string&) const: GRPC connection error 14 []

Golang客户端错误消息

2017/03/22 17:42:12 grpc: Server.Serve failed to create ServerTransport:  connection error: desc = "transport: EOF"
2017/03/22 17:42:12 grpc: Server.Serve failed to create ServerTransport:  connection error: desc = "transport: EOF"

我可以进行哪些额外的调试来确定C++客户端出了什么问题?

英文:

I'm trying to write a GRPC server that talks to both a C++ and golang client. Since this is all internal to our system, there will be a self-signed certificate that signs the server certificate, and the server will sign the client certificates.

I'm able to connect to the server from the golang client. However, the C++ client doesn't connect, and I see a bunch of errors from the ssl layer. What am I doing incorrectly in my configuration of the C++ grpc client?

(My certificates all use a 2048bit RSA key for now)

Here are the client codes that I thought were equivalent (error handling elided):

Golang:

<!-- language: go -->

import (
    &quot;crypto/tls&quot;
	&quot;io/ioutil&quot;
	&quot;google.golang.org/grpc&quot;
	&quot;google.golang.org/grpc/credentials&quot;
)

func getConnection(hostPort string) (*grpc.ClientConn, error) {
    var config tls.Config
    cert, _ := tls.LoadX509KeyPair(&quot;client.crt&quot;, &quot;client.key&quot;)
    config.Certificates = append(config.Certificates, cert)
    b, _ := ioutil.ReadFile(&quot;root.crt&quot;)
    config.RootCAs.AppendCertsFromPEM(b)

    options := grpc.WithTransportCredentials(credentials.NewTLS(config))
    return grpc.Dial(hostPort, options)
}

C++:

<!-- language: c++ -->

#include &lt;fstream&gt;
#include &lt;string&gt;
#include &lt;grpc++/grpc++.h&gt;

std::shared_ptr&lt;grpc::Channel&gt; get_connection(const std::string&amp; host_port) {
    auto contents = [](const std::string&amp; filename) -&gt; std::string {
        std::ifstream fh(filename);
        std::stringstream buffer;
        buffer &lt;&lt; fh.rdbuf();
        fh.close();
        return buffer.str();
    };

    auto ssl_options = grpc::SslCredentialsOptions();
    ssl_options.pem_cert_chain = contents(&quot;client.crt&quot;);
    ssl_options.pem_private_key = contents(&quot;client.key&quot;);
    ssl_options.pem_root_certs = contents(&quot;root.crt&quot;);
    auto creds = grpc::SslCredentials(ssl_options);
    auto channel = grpc::CreateChannel(hostport, creds);
}

My error messages:

C++ Client error messages

<!-- language: text -->

D0322 14:42:12.882767371   11701 env_linux.c:77]             Warning: insecure environment read function &#39;getenv&#39; used
getting job record
E0322 14:42:12.930157873   11701 ssl_transport_security.c:945] Handshake failed with fatal error SSL_ERROR_SSL: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed.
E0322 14:42:12.930231627   11701 handshake.c:128]            Security handshake failed: {&quot;created&quot;:&quot;@1490218932.930210185&quot;,&quot;description&quot;:&quot;Handshake failed&quot;,&quot;file&quot;:&quot;src/core/lib/security/transport/handshake.c&quot;,&quot;file_line&quot;:264,&quot;tsi_code&quot;:10,&quot;tsi_error&quot;:&quot;TSI_PROTOCOL_FAILURE&quot;}
E0322 14:42:12.964082644   11701 ssl_transport_security.c:945] Handshake failed with fatal error SSL_ERROR_SSL: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed.
E0322 14:42:12.964134746   11701 handshake.c:128]            Security handshake failed: {&quot;created&quot;:&quot;@1490218932.964114213&quot;,&quot;description&quot;:&quot;Handshake failed&quot;,&quot;file&quot;:&quot;src/core/lib/security/transport/handshake.c&quot;,&quot;file_line&quot;:264,&quot;tsi_code&quot;:10,&quot;tsi_error&quot;:&quot;TSI_PROTOCOL_FAILURE&quot;}
std::string JobServerClient::getJobRecord(const string&amp;) const: GRPC connection error 14 []

Golang Client error messages

<!-- language: text -->

2017/03/22 17:42:12 grpc: Server.Serve failed to create ServerTransport:  connection error: desc = &quot;transport: EOF&quot;
2017/03/22 17:42:12 grpc: Server.Serve failed to create ServerTransport:  connection error: desc = &quot;transport: EOF&quot;

What additional debugging can I do to determine where the C++ client is going awry?

答案1

得分: 1

错误消息是由于在运行C++代码的系统上呈现的证书不受信任所引起的。

如果您使用的是自签名证书,您需要将根签名密钥添加到该系统上的ca-certificates中,或者配置您的C++代码以读取和识别该根签名密钥。

如果您在代码中提供有关密钥的更多信息(我假设root.crt是您的根签名密钥),可能会有人能够给您提供更具体的帮助。

英文:

The error message is caused by the certificate being presented is not trusted on the system that the C++ code is running on.

If you're using a self-signed certificate you either need to add your root signing key to the ca-certificates on that system or configure your C++ code to read and recognise that root signing key.

If you provide more information on the keys in your code (I assume the root.crt is your root signing key), someone may be able to give you more specific help.

huangapple
  • 本文由 发表于 2017年3月23日 05:51:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/42963332.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定