You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 21:42:02