【问题标题】:RabbitMQ DotNet Client does not connect to SSLRabbitMQ DotNet 客户端未连接到 SSL
【发布时间】:2016-05-27 16:13:39
【问题描述】:

我们正在尝试制作一个 PoC,表明用不同语言编写的应用程序可以通过一个组织中的 RabbitMQ 代理进行通信。我们运行执行 SSL 的 vanilla RabbitMQ docker image rabbitmq:3.6.1-management 和 vanilla haproxy docker image haproxy:1.6.5

frontend amqp_front
    bind *:5672 tcp-ut 5s
    mode tcp
    timeout client 60s
    timeout client-fin 1s
    no option clitcpka
    default_backend amqp_back

frontend amqp_front_ssl
    bind *:5671 tcp-ut 5s ssl crt /etc/certs/haproxy/rmq.pem ca-file /etc/certs/haproxy/root.crt verify required
    mode tcp
    timeout client 60s
    timeout client-fin 1s
    no option clitcpka
    acl client ssl_c_s_dn(CN) -m str cli
    tcp-request content reject if !client
    default_backend amqp_back

RabbitMQ 配置为:

[
  {rabbit,
    [
      { tcp_listeners, [ 5672 ] },
      { ssl_listeners, [ ] },
      {default_pass, <<"pwd">>},
      {default_user, <<"usr">>},
      {default_vhost, <<"default">>},
      {loopback_users, []}
    ]
  },
  { rabbitmq_management, [
      { listener, [
        { port, 15672 },
        { ssl, false }
        ]
      }
    ]
  }
].

我们在 GoNode.js 中编写了一个简单的代码,它们都加载了 root.crt、cli.crt 和 cli.key 并成功连接到 SSL 端口5671 和消费。

尝试使用 RabbitMQ.Client.dll(版本 3.6.0、3.6.1、3.6.2)在 .Net 中编写相同的简单代码但失败了:

X509Store store = new X509Store (StoreName.Root, StoreLocation.LocalMachine);
store.Open (OpenFlags.ReadOnly);

var factory = new ConnectionFactory ();
factory.Ssl.Enabled = true;
factory.Ssl.ServerName = "rmq";
factory.Ssl.Certs = store.Certificates;
factory.Ssl.CertPassphrase = "";
factory.HostName = "localhost";
factory.Port = 5671;
factory.UserName = "usr";
factory.Password = "pwd";
factory.VirtualHost = "default";

var conn = factory.CreateConnection ()

.Net 客户端只是忽略了端口 5671 而忽略了上面的设置,它只是转到 5672。如果 5672 是打开的 - 连接到它,如果 5672 是关闭的 - 失败并拒绝连接。

Go 和 Node.js 中的代码证明我的 SSL 设置是有效的。 .Net客户端的错误表明SSL的东西甚至没有机会跳进去。

我在 debian jessie & Mono 上。

我是否遗漏了一些明显的东西?

【问题讨论】:

  • 你的rabbitmq.config怎么样?
  • 我已经用 RabbitMQ 配置更新了原始帖子。这是一个默认配置。

标签: .net ssl mono rabbitmq haproxy


【解决方案1】:

这是 RabbitMQ .net 客户端 3.6.2 库在使用 SSL 时不遵守指定端口的问题。

它已经被修复,将在 3.6.3 发布时可用(它们与服务器同步发布,所以不知道什么时候发布)。

您的选择是:-

  • 使用旧版本的 .net 客户端
  • 从最新源构建 .net 客户端
  • 尽可能使用标准端口
  • 等待 3.6.3 发布

【讨论】:

    【解决方案2】:

    我在从 masstransit Net Core Client 连接到 docker rabbitmq 容器时遇到了类似的问题。以下是我的工作配置,可能很有用:

    一些注意事项: Masstransit:5.1.5,Net Core 版本:2.2

    Docker 撰写:

    ...
      bus_rabbitmq:
        image: rabbitmq:3-management
        hostname: docker-host
        environment:
          RABBITMQ_DEFAULT_VHOST: "databus"
          RABBITMQ_SSL_CACERTFILE: "/app/certs/dev/myCA.pem"
          RABBITMQ_SSL_CERTFILE: "/app/certs/dev/rabbitmq/rabbit-server.crt"
          RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT: "false"
          RABBITMQ_SSL_KEYFILE: "/app/certs/dev/rabbitmq/rabbit-server.key"
          RABBITMQ_SSL_VERIFY: "verify_peer"
          RABBITMQ_MANAGEMENT_SSL_CACERTFILE: "/app/certs/dev/myCA.pem"
          RABBITMQ_MANAGEMENT_SSL_CERTFILE: "/app/certs/dev/rabbitmq/rabbit-server.crt"
          RABBITMQ_MANAGEMENT_SSL_FAIL_IF_NO_PEER_CERT: "false"
          RABBITMQ_MANAGEMENT_SSL_VERIFY: "verify_peer"
          RABBITMQ_MANAGEMENT_SSL_KEYFILE: "/app/certs/dev/rabbitmq/rabbit-server.key"
        ports:
          - "15672:15672"
          - "15671:15671"
          - "5672:5672"
          - "5671:5671"
        volumes:
        - ./certs:/app/certs
        networks:
          - local_network
    ...
    

    客户端配置:

    ...
    var rabbitCredentials = CredentialsService.RetrieveRabbitMqCredentials();
    
    builder.Register(c =>
        {
            return Bus.Factory.CreateUsingRabbitMq(sbc =>
            {
                sbc.Host(rabbitCredentials.RabbitConnectionString, 5671, rabbitCredentials.RabbitVHost, h =>
                {
                    var certData = CertsService.RetrieveCertificateInfo(ServiceType.RabbitMq);
    
                    h.Username(rabbitCredentials.UserName);
                    h.Password(rabbitCredentials.Password);
                    h.Heartbeat(10);
                    h.UseSsl(s =>
                    {
                        s.Protocol = SslProtocols.Tls12;
                        s.Certificate = X509Certificate.CreateFromCertFile(certData.Path);
                        s.AllowPolicyErrors(SslPolicyErrors.RemoteCertificateNameMismatch);
                        s.UseCertificateAsAuthenticationIdentity = false;
                    });
                });
    
                sbc.ReceiveEndpoint("data_queue", ec =>
                {
                    // loading consumers
                    ec.LoadFrom(c);
    
                    // loading saga state machines
                    //ec.LoadStateMachineSagas(c);
                });
            });
        })
        .As<IBusControl>()
        .As<IPublishEndpoint>()
        .SingleInstance();
    ...
    

    我需要使用:

    AllowPolicyErrors(SslPolicyErrors.RemoteCertificateNameMismatch)

    为了避免我的证书中的服务器名称不匹配。

    【讨论】:

      猜你喜欢
      • 2021-04-17
      • 1970-01-01
      • 1970-01-01
      • 2017-06-14
      • 2015-11-17
      • 1970-01-01
      • 1970-01-01
      • 2017-11-15
      • 2015-11-22
      相关资源
      最近更新 更多