如何配置ASP.NET Core gRPC在服务端和客户端使用SSL/TLS
ASP.NET Core gRPC 生产级SSL/TLS连接配置方案
1. 证书选型
根据你的两类部署场景,分别适配不同证书:
- 公网对外服务端:使用公共可信CA颁发的SSL证书,绑定服务端对应的公网域名即可,可选购泛域名证书覆盖多个子域名业务,到期前及时完成续期即可。
- 用户侧/内网网状拓扑服务端:使用自行搭建的私有CA颁发的专用证书,先生成根CA证书,再为每个节点(支持同时作为服务端、客户端使用)签发节点证书,所有相关节点都需将私有根CA导入系统可信根证书存储,避免校验失败。
2. 服务端Kestrel配置
2.1 公网对外服务端配置
var builder = WebApplication.CreateBuilder(args); // 注册gRPC服务 builder.Services.AddGrpc(); // 配置Kestrel builder.WebHost.ConfigureKestrel(serverOpts => { // 监听gRPC默认端口50051,可按需修改 serverOpts.ListenAnyIP(50051, listenOpts => { // 加载公共CA颁发的PFX格式证书,生产环境建议从系统证书存储、安全配置中心读取,禁止硬编码密码 listenOpts.UseHttps("public_ca_cert.pfx", "your_cert_password"); // 强制启用HTTP/2,gRPC依赖该协议 listenOpts.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2; }); }); var app = builder.Build(); // 映射你的gRPC服务实现 app.MapGrpcService<YourGrpcServiceImpl>(); app.Run();
如果公网服务端前端有Nginx、IIS等反向代理,可将SSL证书配置在代理层,同时确保代理层开启HTTP/2支持,代理到Kestrel的内网链路可按需选择是否加密。
2.2 用户侧/内网网状拓扑服务端配置(支持双向TLS校验)
builder.WebHost.ConfigureKestrel(serverOpts => { serverOpts.ListenAnyIP(50051, listenOpts => { listenOpts.UseHttps(httpsOpts => { // 加载当前节点的服务端证书(私有CA签发) httpsOpts.ServerCertificate = new X509Certificate2("node_server_cert.pfx", "cert_password"); // 开启客户端证书强制校验,适配双向认证需求 httpsOpts.ClientCertificateMode = ClientCertificateMode.RequireCertificate; // 私有CA未搭建CRL服务可关闭吊销校验 httpsOpts.CheckCertificateRevocation = false; // 自定义客户端证书校验逻辑 httpsOpts.ClientCertificateValidation = (cert, chain, policyErrors) => { var rootCa = new X509Certificate2("custom_root_ca.cer"); chain.ChainPolicy.ExtraStore.Add(rootCa); chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; return chain.Build(cert); }; }); listenOpts.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2; }); });
3. 客户端配置
3.1 公网客户端调用公共CA签名的服务端
var builder = WebApplication.CreateBuilder(args); // 注册gRPC客户端 builder.Services.AddGrpcClient<YourGrpcService.YourGrpcServiceClient>(opts => { opts.Address = new Uri("https://your-public-service-domain:50051"); }); // 公共CA证书默认被系统信任,无需额外添加校验逻辑,确保访问域名和证书绑定域名一致即可
3.2 内网/网状拓扑节点作为客户端配置(双向TLS)
builder.Services.AddGrpcClient<YourGrpcService.YourGrpcServiceClient>(opts => { opts.Address = new Uri("https://target-node-address:50051"); }) .ConfigureChannel(channelOpts => { // 加载当前节点的客户端证书(私有CA签发,可与服务端证书共用同一张) var clientCert = new X509Certificate2("node_client_cert.pfx", "cert_password"); channelOpts.HttpHandlerFactory = () => new SocketsHttpHandler { SslOptions = new SslClientAuthenticationOptions { ClientCertificates = new X509CertificateCollection { clientCert }, // 自定义服务端证书校验逻辑 RemoteCertificateValidationCallback = (sender, cert, chain, policyErrors) => { if (policyErrors == SslPolicyErrors.None) return true; var rootCa = new X509Certificate2("custom_root_ca.cer"); chain.ChainPolicy.ExtraStore.Add(rootCa); chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; return chain.Build(cert as X509Certificate2); } } }; });
4. 生产环境注意事项
- 证书密码、存储路径等敏感信息禁止硬编码在代码或明文配置文件中,公网服务端优先使用云服务商证书管理服务、系统证书存储读取凭证,内网节点通过环境变量、加密配置中心传递敏感信息
- 私有根CA证书建议设置较长有效期,节点证书定期轮换,禁止使用过期证书
- 动态IP的内网节点可配置固定内网域名,证书绑定域名避免IP变动导致校验失败
- 禁止直接使用开发环境生成的localhost测试证书部署生产环境,存在极高安全风险
内容的提问来源于stack exchange,提问作者Steve Miller
相关产品推荐
相关产品推荐

