当前位置: 首页 > 知识库问答 >
问题:

如何为gRPC启用服务器端SSL?

储峻
2023-03-14

gRPC新手,找不到任何关于如何在服务器端启用SSL的例子。我使用openssl生成了一个密钥对,但是它报错说私钥无效。

D0608 16:18:31.390303 Grpc.Core.Internal.UnmanagedLibrary Attempting to load native library "...\grpc_csharp_ext.dll"
D0608 16:18:31.424331 Grpc.Core.Internal.NativeExtension gRPC native library loaded successfully.
E0608 16:18:43.307324 0 ..\src\core\lib\tsi\ssl_transport_security.c:644: Invalid private key.
E0608 16:18:43.307824 0 ..\src\core\lib\security\security_connector.c:821: Handshaker factory creation failed with TSI_INVALID_ARGUMENT.
E0608 16:18:43.307824 0 ..\src\core\ext\transport\chttp2\server\secure\server_secure_chttp2.c:188: Unable to create secure server with credentials of type Ssl.

这是我的代码

var keypair = new KeyCertificatePair(
            File.ReadAllText(@"root-ca.pem"),
            File.ReadAllText(@"ssl-private.key"));
SslServerCredentials creds = new SslServerCredentials(new List<KeyCertificatePair>() {keypair});
Server server = new Server
{
    Services = { GrpcTest.BindService(new GrpcTestImpl()) },
    Ports = { new ServerPort("127.0.0.1", Port, creds) }
};

共有3个答案

庄兴发
2023-03-14

如果您已经尝试了@qmo建议但仍然无法正常工作,并且您收到相同的错误,说“StatusCode=不可用,Detail=”DNS解析失败“,我通过在主机文件中添加新记录(位于Windows的C:\Windows\System32\drivers\etc中)来修复它。

127.0.0.1 DESKTOP-QNCI7UN

其中DESKTOP-QNCI7UN是我的机器的名称。然后在我使用的客户端中:

channel = new Channel("DESKTOP-QNCI7UN", 50000, ssl);

通过使用“locahost ”,它不起作用。因此,通过在客户机中使用计算机名,在主机文件中添加记录,修复了该问题。

方祺
2023-03-14

如果证书颁发机构(CA)和证书签名请求(CSR)的使用对于您的任务来说过于复杂,则可以使用自签名证书。

假设有1个服务器和2个(或更多)客户端。

在客户端 1 执行:

openssl req -x509 -newkey rsa:4096 -nodes -keyout client.key -out client.crt -days 3650 -subj '/CN=client1' # generate client1 cert and key
sudo bash -c 'echo "192.168.1.101 my.server" >> /etc/hosts' # create domain for server - if necessary only
scp client.crt server-user@my.server:/path/to/certs/client1.crt # copy public cert client1 to server machine

在客户端2执行:

openssl req -x509 -newkey rsa:4096 -nodes -keyout client.key -out client.crt -days 3650 -subj '/CN=client2' # generate client2 cert and key
sudo bash -c 'echo "192.168.1.101 my.server" >> /etc/hosts' # create domain for server- if necessary only
scp client.crt server-user@my.server:/path/to/certs/client2.crt # copy public cert client2 to server machine

在服务器上执行:

openssl req -x509 -newkey rsa:4096 -nodes -keyout server.key -out server.crt -days 3650 -subj '/CN=my.server' # generate server cert and key
scp server.crt client1-user@client1-addr:/path/to/certs # copy public cert server to client1 machine
scp server.crt client2-user@client2-addr:/path/to/certs # copy public cert server to client2 machine
cat client1.crt client2.crt > client.crt # combine client certs into the single file

服务器代码:

var clientCert = File.ReadAllText(Path.Combine(certPath, "client.crt"));
var serverCert = File.ReadAllText(Path.Combine(certPath, "server.crt"));
var serverKey = File.ReadAllText(Path.Combine(certPath, "server.key"));
var keyPair = new KeyCertificatePair(serverCert, serverKey);
var credentials = new SslServerCredentials(new List<KeyCertificatePair> { keyPair }, clientCert, true);

var server = new Server
{
    Services = { MyService.BindService(new MyAdminService()) },
    Ports = { new ServerPort("0.0.0.0", 54321, credentials) }
};

客户代码:

var serverCert = File.ReadAllText(Path.Combine(_certPath, "server.crt"));
var clientCert = File.ReadAllText(Path.Combine(_certPath, "client.crt"));
var clientKey = File.ReadAllText(Path.Combine(_certPath, "client.key"));
var credentials = new SslCredentials(serverCert, new KeyCertificatePair(clientCert, clientKey));

var channel = new Channel("my.server:54321", credentials);    
var client = new MyService.MyServiceClient(channel);

重要!

要使用TLS证书,请在生成服务器证书时使用域名。

客户端证书可以使用任何唯一字符串

域名应至少包含 1 个点 (.),例如 my.servermy.server.customzone

如果使用顶级域名,如< code>my-server,则需要等待很长时间才能解决(对我来说,通常需要76秒)。

优点:-无需生成CSR,将其传递给带有CA的机器,在那里签名并复制回原始机器

缺点:-添加新客户端需要向服务器添加证书

弘伟彦
2023-03-14

这是我所做的。

使用 OpenSSL,生成具有以下各项的证书:

@echo off
set OPENSSL_CONF=c:\OpenSSL-Win64\bin\openssl.cfg   

echo Generate CA key:
openssl genrsa -passout pass:1111 -des3 -out ca.key 4096

echo Generate CA certificate:
openssl req -passin pass:1111 -new -x509 -days 365 -key ca.key -out ca.crt -subj  "/C=US/ST=CA/L=Cupertino/O=YourCompany/OU=YourApp/CN=MyRootCA"

echo Generate server key:
openssl genrsa -passout pass:1111 -des3 -out server.key 4096

echo Generate server signing request:
openssl req -passin pass:1111 -new -key server.key -out server.csr -subj  "/C=US/ST=CA/L=Cupertino/O=YourCompany/OU=YourApp/CN=%COMPUTERNAME%"

echo Self-sign server certificate:
openssl x509 -req -passin pass:1111 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

echo Remove passphrase from server key:
openssl rsa -passin pass:1111 -in server.key -out server.key

echo Generate client key
openssl genrsa -passout pass:1111 -des3 -out client.key 4096

echo Generate client signing request:
openssl req -passin pass:1111 -new -key client.key -out client.csr -subj  "/C=US/ST=CA/L=Cupertino/O=YourCompany/OU=YourApp/CN=%CLIENT-COMPUTERNAME%"

echo Self-sign client certificate:
openssl x509 -passin pass:1111 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt

echo Remove passphrase from client key:
openssl rsa -passin pass:1111 -in client.key -out client.key

将密码1111更改为任何您喜欢的密码

服务器:

var cacert = File.ReadAllText(@"ca.crt");
var servercert = File.ReadAllText(@"server.crt");
var serverkey = File.ReadAllText(@"server.key");
var keypair = new KeyCertificatePair(servercert, serverkey);
var sslCredentials = new SslServerCredentials(new List<KeyCertificatePair>() { keypair }, cacert, false);

var server = new Server
{
    Services = { GrpcTest.BindService(new GrpcTestImpl(writeToDisk)) },
    Ports = { new ServerPort("0.0.0.0", 555, sslCredentials) }
};
server.Start();

客户:

var cacert = File.ReadAllText(@"ca.crt");
var clientcert = File.ReadAllText(@"client.crt");
var clientkey = File.ReadAllText(@"client.key");
var ssl = new SslCredentials(cacert, new KeyCertificatePair(clientcert, clientkey));
channel = new Channel("localhost", 555, ssl);
client = new GrpcTest.GrpcTestClient(channel);

如果“本地主机”不起作用,请改用主机名。

 类似资料:
  • 我正在用C++开发双向流gRPC。我想在服务器端设置一个超时限制,如果连接超过一个阈值,就关闭连接。 但是我发现的唯一超时机制是在客户端(https://grpc.io/blog/deadlines/#c)。我找不到任何API可以用于ServerContext(https://grpc.github.io/grpc/cpp/classgrpc_1_1_server_context.html)。有人

  • 我正在使用收集器跟踪java服务中的跨度,这一服务是http和grpc。收集器终结点是localhost:55680。此java服务跟踪成功。 现在,我想使用这个收集器基于gRPC跟踪我的go服务。 在我的go服务中,我复制以下文件:interceptor。去grpctrace。从repo opentelemetry转到contrib,这里https://github.com/open-telem

  • 运行命令: 日志: 2020-03-27 03:47:12.744007:I tensor flow _ serving/core/loader _ harness . cc:87]成功加载可服务版本{ name:docker _ test version:1 } e 0327 03:47:12.745641810 6 server _ chttp 2 . cc:40]{ " created ":

  • 下面的代码片段显示了如何在gRPC AspNet核心应用程序中启用gRPC web: 客户端应用程序的代码如下所示:

  • 我使用的是Kube v 1 . 13 . 0版。由于Heapster从v1.11开始贬值,我不得不启用集群指标的API服务器来实现HPA。 附图仅供参考 有人能指导我逐步启用API Metrics服务器或任何演示视频吗。这将非常有助于进一步进行。 如果需要任何进一步的信息,请告诉我。 谢谢Deena

  • 我有一个方法,可以启动一个简单的cpp grpc服务器。 我想做