我们正在努力使PoC显示用不同语言编写的应用程序可以通过RabbitMQ代理在一个组织中进行通信。我们运行香草RabbitMQ码头图像 rabbitmq:3.6.1-management 和vanilla haproxy docker图像 haproxy:1.6.5 执行SSL:
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 }
]
}
]
}
].
我们在 Go &amp;中编写了一个简单的代码 Node.js ,它们都加载root.crt,cli.crt&amp; 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&amp;单声道。
我错过了一些明显的东西吗?
答案 0 :(得分:2)
这是RabbitMQ .net客户端3.6.2库在使用SSL时不遵守指定端口的问题。
它已被修复,并且在3.6.3发布时可用(它们与服务器同步发布,因此不知道何时发布)。
您的选择是: -
答案 1 :(得分:0)
我从Masstransit Net Core Client连接到docker rabbitmq容器时遇到类似的问题。以下是我有效的配置,可能会有用:
一些注意事项: Masstransit:5.1.5,Net Core版本:2.2
Docker-compose:
...
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)
为避免我的证书中的服务器名称不匹配。