C# 中的 gRPC 客户端不适用于支持 mTLS 的 Go 中的 gRPC 服务器

我在 Golang 中有一个gRPC 服务器,它使用以下 ServerOptions 启用了 mTLS:


// getServerOptions returns a list of GRPC server options.

// Current options are TLS certs and opencensus stats handler.

func (h *serviceHandler) getServerOptions() []grpc.ServerOption {

    tlsCer, err := tls.LoadX509KeyPair(tlsDir+"tls.crt", tlsDir+"tls.key")

    if err != nil {

        logger.WithError(err).Fatal("failed to generate credentials")

    }


    cfg := &tls.Config{

        Certificates: []tls.Certificate{tlsCer},

        ClientAuth:   tls.RequireAndVerifyClientCert,

        GetConfigForClient: func(*tls.ClientHelloInfo) (*tls.Config, error) {

            h.certMutex.RLock()

            defer h.certMutex.RUnlock()

            return &tls.Config{

                Certificates: []tls.Certificate{tlsCer},

                ClientAuth:   tls.RequireAndVerifyClientCert,

                ClientCAs:    h.caCertPool,

            }, nil

        },

    }

    // Add options for creds and OpenCensus stats handler to enable stats and tracing.

    return []grpc.ServerOption{grpc.Creds(credentials.NewTLS(cfg)), grpc.StatsHandler(&ocgrpc.ServerHandler{})}

}

服务器对于 Golang 中的gRPC 客户端工作正常,但在证书交换握手后对于以下 gRPC c# 客户端失败。


        static async Task Main(string[] args)

        {

            string baseAddress = "x.x.x.x";

            var x509Cert = new X509Certificate2("client.pfx", "123");

            var client = CreateClientWithCert("https://" + baseAddress + ":443", x509Cert);


            try {

                var response = await client.PostAllocateAsync(new AllocationRequest {Namespace = "Default"});

                Console.Write(response.State.ToString());

            } 

            catch(RpcException e)

            {

                Console.WriteLine($"gRPC error: {e.Status.Detail}");

            }

            catch 

            {

                Console.WriteLine($"Unexpected error calling agones-allocator");

                throw;

            }

        }

    }


慕神8447489
浏览 118回答 1
1回答

RISEBY

我写了一些示例代码来重现这里报告的跨平台不兼容问题。根本原因是在 golang 服务器中使用 GetConfigForClient 时,在这种情况下用于刷新客户端 CA 证书,来自 C# 客户端的请求失败。但是,当它被替换为VerifyPeerCertificate时,问题得到了解决。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go