RabbitMQ启用TLS后连接报错Unknown CA,请求排查原因
RabbitMQ TLS连接报错:Unknown CA 问题排查请求
环境与配置
RabbitMQ服务端配置(rabbitMQ.config)
log.console = true log.console.level = debug log.file.level = debug listeners.tcp = none listeners.ssl.default = 5671 ssl_options.cacertfile = C:/Users/UserId/AppData/Roaming/RabbitMQ/result-new/ca_certificate.pem ssl_options.certfile = C:/Users/UserId/AppData/Roaming/RabbitMQ/result-new/server_PNQ1-LP98R10J3_certificate.pem ssl_options.keyfile = C:/Users/UserId/AppData/Roaming/RabbitMQ/result-new/server_PNQ1-LP98R10J3_key.pem ssl_options.verify = verify_none ssl_options.fail_if_no_peer_cert = false
服务端可正常启动,但客户端连接时出现错误。
客户端报错信息
RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable ---> System.AggregateException: One or more errors occurred. (The remote certificate is invalid according to the validation procedure.) ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure. at System.Net.Security.SslStream.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, ExceptionDispatchInfo exception) at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest) at System.Net.Security.SslStream.PartialFrameCallback(AsyncProtocolRequest asyncRequest) --- End of stack trace from previous location where exception was thrown --- at System.Net.Security.SslStream.ThrowIfExceptional() at System.Net.Security.SslStream.InternalEndProcessAuthentication(LazyAsyncResult lazyResult) at System.Net.Security.SslStream.EndProcessAuthentication(IAsyncResult result) at System.Net.Security.SslStream.EndAuthenticateAsClient(IAsyncResult asyncResult) at System.Net.Security.SslStream.<>c.<AuthenticateAsClientAsync>b__64_2(IAsyncResult iar) at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at RabbitMQ.Client.Impl.SslHelper.<>c__DisplayClass2_0.<TcpUpgrade>b__0(SslOption opts) at RabbitMQ.Client.Impl.SslHelper.TcpUpgrade(Stream tcpStream, SslOption options) at RabbitMQ.Client.Impl.SocketFrameHandler..ctor(AmqpTcpEndpoint endpoint, Func`2 socketFactory, TimeSpan connectionTimeout, TimeSpan readTimeout, TimeSpan writeTimeout) at RabbitMQ.Client.Framing.Impl.IProtocolExtensions.CreateFrameHandler(IProtocol protocol, AmqpTcpEndpoint endpoint, ArrayPool`1 pool, Func`2 socketFactory, TimeSpan connectionTimeout, TimeSpan readTimeout, TimeSpan writeTimeout) at RabbitMQ.Client.ConnectionFactory.CreateFrameHandler(AmqpTcpEndpoint endpoint) at RabbitMQ.Client.EndpointResolverExtensions.SelectOne[T](IEndpointResolver resolver, Func`2 selector) --- End of inner exception stack trace --- at RabbitMQ.Client.EndpointResolverExtensions.SelectOne[T](IEndpointResolver resolver, Func`2 selector) at RabbitMQ.Client.Framing.Impl.AutorecoveringConnection.Init(IEndpointResolver endpoints) at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName) --- End of inner exception stack trace --- at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName) at RabbitMQ.Client.ConnectionFactory.CreateConnection(String clientProvidedName) at RabbitMQ.Client.ConnectionFactory.CreateConnection() at RabbitMQ.Explore.Program.RabbitMQWithSSLEnable() in C:\Users\E5695455\Desktop\RabbitMQ-RnD\RabbitMQ.Explore-master\RabbitMQ.Explore-master\RabbitMQ.Explore\Program.cs:line 167
RabbitMQ服务端日志报错
2023-09-13 17:29:45.329000+05:30 [notice] <0.3749.0> TLS server: In state connection received CLIENT ALERT: Fatal - Unknown CA 2023-09-13 17:29:45.329000+05:30 [notice] <0.3749.0> 2023-09-13 17:29:45.329000+05:30 [info] <0.3752.0> accepting AMQP connection <0.3752.0> ([::1]:61235 -> [::1]:5671) 2023-09-13 17:29:45.330000+05:30 [error] <0.3752.0> closing AMQP connection <0.3752.0> ([::1]:61235 -> [::1]:5671): 2023-09-13 17:29:45.330000+05:30 [error] <0.3752.0> {inet_error,{tls_alert,{unknown_ca,"TLS server: In state connection received CLIENT ALERT: Fatal - Unknown CA "}}} 2023-09-13 17:29:45.330000+05:30 [debug] <0.3755.0> Closing all channels from connection '[::1]:61235 -> [::1]:5671' because it has been closed
客户端连接代码
try { string rabbitmqHostName = "PNQ1-LP98R10J3"; string rabbitmqServerName = "PNQ1-LP98R10J3"; string certificateFilePath = "C:\\Users\\UserId\\AppData\\Roaming\\RabbitMQ\\fromclient\\client_vwmazadsolapac4_certificate.pem"; string certificatePassphrase = ""; string rabbitmqUsername = "test"; string rabbitmqPassword = "test"; var mTLSEnabled = false; var factory = new ConnectionFactory(); factory.Uri = new Uri($"amqps://{rabbitmqUsername}:{rabbitmqPassword}@{rabbitmqHostName}:5671"); // Note: This should NEVER be "localhost" factory.Ssl.ServerName = rabbitmqServerName; if (mTLSEnabled) { // Path to my .p12 file. factory.Ssl.CertPath = certificateFilePath; // Passphrase for the certificate file - set through OpenSSL factory.Ssl.CertPassphrase = certificatePassphrase; } factory.Ssl.Enabled = true; // Make sure TLS 1.2 is supported & enabled by your operating system factory.Ssl.Version = SslProtocols.Tls12; // This is the default RabbitMQ secure port factory.Port = AmqpTcpEndpoint.UseDefaultPort; factory.VirtualHost = "/"; using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { Logger.LogWriter($"{System.Reflection.MethodBase.GetCurrentMethod().Name} - Successfully connected and opened a channel"); Console.WriteLine("Successfully connected and opened a channel"); channel.QueueDeclare("rabbitmq-dotnet-test", false, false, false, null); Logger.LogWriter($"{System.Reflection.MethodBase.GetCurrentMethod().Name} - Successfully declared a queue"); Console.WriteLine("Successfully declared a queue"); channel.QueueDelete("rabbitmq-dotnet-test"); Console.WriteLine("Successfully deleted the queue"); Logger.LogWriter($"{System.Reflection.MethodBase.GetCurrentMethod().Name} - Successfully deleted a queue"); } } } catch (System.Exception ex) { var error = ex.ToString(); Logger.LogWriter($"{System.Reflection.MethodBase.GetCurrentMethod().Name} - {error}"); System.Console.WriteLine(error); }
已执行的排查步骤
- 查阅官方SSL排查文档
- 使用tls-gen生成证书
- 执行
rabbitmq-diagnostics测试TLS版本和加密套件,结果正常 - 使用OpenSSL工具测试TLS连接,结果正常
但仍无法解决Unknown CA错误,请求协助排查原因。
问题根源与解决方法
1. 核心原因:客户端未信任服务端CA证书
服务端配置verify_none仅表示服务端不验证客户端证书,但客户端默认会验证服务端证书的合法性——即检查服务端证书是否由本地信任的CA签发。你的客户端代码未指定信任的CA证书,导致系统无法识别服务端证书的签发CA,从而抛出Unknown CA错误。
2. 针对性解决步骤
(1)客户端添加CA证书信任
修改客户端代码,添加服务端使用的CA证书路径:
// 新增这一行,指向服务端的ca_certificate.pem文件 factory.Ssl.CACertPath = "C:/Users/UserId/AppData/Roaming/RabbitMQ/result-new/ca_certificate.pem";
(2)验证证书主机名匹配
检查服务端证书的主机名是否与客户端设置的ServerName一致:
用OpenSSL命令查看证书信息:
openssl x509 -in server_PNQ1-LP98R10J3_certificate.pem -text -noout
确认Subject字段的CN值,或X509v3 Subject Alternative Name中包含PNQ1-LP98R10J3。如果不匹配,需要重新生成符合主机名的证书。
(3)检查证书文件完整性与权限
确保服务端的ca_certificate.pem是完整的根CA证书,客户端能正常读取该文件(无权限限制)。
(4)临时调试验证(仅测试环境)
若需快速确认问题,可临时关闭客户端证书验证(生产环境禁止):
factory.Ssl.AcceptablePolicyErrors = SslPolicyErrors.RemoteCertificateChainErrors | SslPolicyErrors.RemoteCertificateNameMismatch | SslPolicyErrors.RemoteCertificateNotAvailable;
如果此时能成功连接,即可确认是证书信任链问题,再采用步骤(1)(2)的正规方案修复。
内容的提问来源于stack exchange,提问作者user2467944
相关产品推荐
相关产品推荐

