Ruby's grpc(v1.3.2) gem SSL/TLS connection issue with grpc server built entirely in golang

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

Ruby's grpc(v1.3.2) gem SSL/TLS connection issue with grpc server built entirely in golang

问题

最近,我尝试使用版本为1.3.2的rubygem grpc作为客户端,并连接到一个使用golang构建的grpc服务器。我查阅了GRPC.IO上的文档,并在我的代码中使用了它。

irb(main):017:0> GRPC::Core::Credentials.new(File.read(CA_FILE_PATH))
NameError: uninitialized constant GRPC::Core::Credentials
        from (irb):17
        from /usr/local/share/gems/gems/railties-4.2.1/lib/rails/commands/console.rb:110:in `start'
        from /usr/local/share/gems/gems/railties-4.2.1/lib/rails/commands/console.rb:9:in `start'
        from /usr/local/share/gems/gems/railties-4.2.1/lib/rails/commands/commands_tasks.rb:68:in `console'
        from /usr/local/share/gems/gems/railties-4.2.1/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
        from /usr/local/share/gems/gems/railties-4.2.1/lib/rails/commands.rb:17:in `<top (required)>'
        from bin/rails:4:in `require'
        from bin/rails:4:in `<main>'

然而,他们的文档明确指出:

creds = GRPC::Core::Credentials.new(load_certs)  # load_certs typically loads a CA roots file
stub = Helloworld::Greeter::Stub.new('myservice.example.com', creds)

然后我遇到了ChannelCredentialscreds应该是ChannelCredentials对象或一个符号(例如*:this_channel_is_insecure*)。因此,我也尝试了一下。

我从grpc gem的源代码中获取了以下函数。这个函数在rspec测试用例中被调用来加载证书:

def load_certs
      data_dir = "#{Rails.root}/certs"
      files = ['ca.pem', 'server.key', 'server.pem']
      files.map { |f| File.open(File.join(data_dir, f)).read }
end

然后我尝试了以下代码:

channel_creds = GRPC::Core::ChannelCredentials.new(load_certs)
stub = Helloworld::Greeter::Stub.new('myservice.example.com', channel_creds)

但是上述代码失败了,报错如下:

E0619 09:59:10.410575570   14208 ssl_transport_security.c:601] Could not load any root certificate.
E0619 09:59:10.410604954   14208 ssl_transport_security.c:1315] Cannot load server root certificates.
E0619 09:59:10.410622519   14208 security_connector.c:837]   Handshaker factory creation failed with TSI_INVALID_ARGUMENT.

我还尝试了以下代码:

channel_creds = GRPC::Core::ChannelCredentials.new(File.read(CA_FILE_PATH))
stub = Helloworld::Greeter::Stub.new('myservice.example.com', creds)

但是我得到的只是来自日志或rpc服务器的错误:

2017/06/16 10:52:34 transport: http2Server.HandleStreams failed to receive the preface from client: EOF
2017/06/16 10:53:35 transport: http2Server.HandleStreams failed to receive the preface from client: EOF
2017/06/16 10:53:59 transport: http2Server.HandleStreams failed to receive the preface from client: EOF
2017/06/16 10:55:06 transport: http2Server.HandleStreams failed to receive the preface from client: EOF

有人成功尝试过启用SSL/TLS的Ruby客户端和Golang服务器组合吗?

英文:

Recently, I was trying to use rubygem grpc version 1.3.2 as a clinet and connect to a grpc server which is built from golang. I went through the documentation at GRPC.IO and used it in my code as it.

    irb(main):017:0> GRPC::Core::Credentials.new(File.read(CA_FILE_PATH))
NameError: uninitialized constant GRPC::Core::Credentials
        from (irb):17
        from /usr/local/share/gems/gems/railties-4.2.1/lib/rails/commands/console.rb:110:in `start'
        from /usr/local/share/gems/gems/railties-4.2.1/lib/rails/commands/console.rb:9:in `start'
        from /usr/local/share/gems/gems/railties-4.2.1/lib/rails/commands/commands_tasks.rb:68:in `console'
        from /usr/local/share/gems/gems/railties-4.2.1/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
        from /usr/local/share/gems/gems/railties-4.2.1/lib/rails/commands.rb:17:in `<top (required)>'
        from bin/rails:4:in `require'
        from bin/rails:4:in `<main>'

However their documentation specifically says,

creds = GRPC::Core::Credentials.new(load_certs)  # load_certs typically loads a CA roots file
stub = Helloworld::Greeter::Stub.new('myservice.example.com', creds)

Then I came across ChannelCredentials and the creds is supposed to be either ChannelCredentials object or a symbol(e.g. :this_channel_is_insecure). Hence, I gave it a try as well.

I've taken the following function from the grpc gem's source code itself. This function was called in rspec test cases for loading the certs:

def load_certs
      data_dir = "#{Rails.root}/certs"
      files = ['ca.pem', 'server.key', 'server.pem']
      files.map { |f| File.open(File.join(data_dir, f)).read }
end

Then I gave it a try with,

channel_creds = GRPC::Core::ChannelCredentials.new(load_certs)
stub = Helloworld::Greeter::Stub.new('myservice.example.com', channel_creds)

But the above failed with

E0619 09:59:10.410575570   14208 ssl_transport_security.c:601] Could not load any root certificate.
E0619 09:59:10.410604954   14208 ssl_transport_security.c:1315] Cannot load server root certificates.
E0619 09:59:10.410622519   14208 security_connector.c:837]   Handshaker factory creation failed with TSI_INVALID_ARGUMENT.

I also tried:

channel_creds = GRPC::Core::ChannelCredentials.new(File.read(CA_FILE_PATH))
stub = Helloworld::Greeter::Stub.new('myservice.example.com', creds)

But all I got was error from the logs or rpc server:

2017/06/16 10:52:34 transport: http2Server.HandleStreams failed to receive the preface from client: EOF
2017/06/16 10:53:35 transport: http2Server.HandleStreams failed to receive the preface from client: EOF
2017/06/16 10:53:59 transport: http2Server.HandleStreams failed to receive the preface from client: EOF
2017/06/16 10:55:06 transport: http2Server.HandleStreams failed to receive the preface from client: EOF

Has anyone successfully tried this Ruby client Golang server combination with SSL/TLS enabled?

答案1

得分: 4

是的,客户端存根构造函数的第二个参数(creds参数)应该是一个GRPC::Core::ChannelCredentials对象,或者更具体地说,是::this_channel_is_insecure符号(如果传递后者,将使用不安全的连接)。

我要注意的是,使用以下代码的测试可能会产生误导,因为只有使用客户端的私钥和证书链才有意义(我相信该特定测试并未使用密钥和证书链)。

关于GRPC::Core::ChannelCredentials构造函数:

有三种形式可以使用(在https://github.com/grpc/grpc/blob/master/src/ruby/ext/grpc/rb_channel_credentials.c#L128中的构造函数代码上方有一条注释对它们进行了说明),选项如下:

  • Credentials.new()

  • Credentials.new(pem_root_certs)

  • Credentials.new(pem_root_certs, pem_private_key, pem_cert_chain)

在所有情况下,根文件、私钥和证书链参数都是PEM编码的字符串。

请注意,如果不传递任何参数(使用Credentials.new()),则服务器根证书将按照此头注释中描述的方式找到(请参阅当服务器根证书参数为null时的行为描述)。只有当您希望客户端使用私钥和证书链时,才需要使用最后一个构造函数。

英文:

> creds is supposed to be either ChannelCredentials object or a symbol

Yes the second argument of a client stub constructor (the creds argument), should be either a GRPC::Core::ChannelCredentials object or <i>specifically</i> the ::this_channel_is_insecure symbol (if the latter is passed, an insecure connection will be used).

I'd note that the test that uses

def load_certs
      data_dir = &quot;#{Rails.root}/certs&quot;
      files = [&#39;ca.pem&#39;, &#39;server.key&#39;, &#39;server.pem&#39;]
      files.map { |f| File.open(File.join(data_dir, f)).read }
end

might actually be misleading, since it only makes sense to construct channel credentials with the <i>client's</i> private key and certificate chain (that specific test I believe doesn't use the key and cert chain).

On the GRPC::Core::ChannelCredentials constructor:

There are three forms that can be used, (there's a comment above the constructor code in https://github.com/grpc/grpc/blob/master/src/ruby/ext/grpc/rb_channel_credentials.c#L128 that goes over them), but the options are:

  • Credentials.new()

  • Credentials.new(pem_root_certs)

  • Credentials.new(pem_root_certs, pem_private_key, pem_cert_chain)

In all cases, the roots file, private key, and cert chain parameters are pem encoded strings.

Note that if no arguments are passed (Credentials.new() is used), then the server root certificates will be found as described in this header comment (see the description for the behavior when server root certs parameter is null). And the last constructor is only needed if you want the <i>client</i> to use a private key and cert chain.

答案2

得分: 0

我可以确认这个是有效的。

channel_creds = GRPC::Core::ChannelCredentials.new(File.read("/home/user/.lnd/tls.cert"))
stub = Lnrpc::Lightning::Stub.new("127.0.0.1:10009", channel_creds)
obj = Lnrpc::GetInfoRequest.new
pp stub.get_info(obj)
英文:

I can confirm this works.

channel_creds = GRPC::Core::ChannelCredentials.new(File.read(&quot;/home/user/.lnd/tls.cert&quot;))
stub = Lnrpc::Lightning::Stub.new(&quot;127.0.0.1:10009&quot;, channel_creds)
obj = Lnrpc::GetInfoRequest.new
pp stub.get_info(obj)

huangapple
  • 本文由 发表于 2017年6月19日 18:11:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/44627766.html
匿名

发表评论

匿名网友

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

确定