RabbitMQ + C# + SSL
本文关键字:SSL RabbitMQ | 更新日期: 2023-09-27 18:08:31
我正在尝试使用c#来获得RabbitMQ 3.6.2在Windows 7上对Erlang 18.0使用SSL/TLS。当我在c#代码中启用SSL时,我遇到了错误。我在这里介绍了设置SSL/TLS的步骤。我还经历了[故障排除步骤][2],这些步骤显示出现了成功(除了由于缺乏对stunnel的了解而无法执行stunnel步骤)。下面是我尝试连接到RabbitMQ的c#代码:
var factory = new ConnectionFactory()
{
// NOTE: guest username ONLY works with HostName "localhost"!
//HostName = Environment.MachineName,
HostName = "localhost",
UserName = "guest",
Password = "guest",
};
// Without this line, RabbitMQ.log shows error: "SSL: hello: tls_handshake.erl:174:Fatal error: protocol version"
// When I add this line to go to TLS 1.2, .NET throws an exception: The remote certificate is invalid according to the validation procedure.
// https://stackoverflow.com/questions/9983265/the-remote-certificate-is-invalid-according-to-the-validation-procedure:
// Walked through this tutorial to add the client certificate as a Windows Trusted Root Certificate: http://www.sqlservermart.com/HowTo/Windows_Import_Certificate.aspx
factory.Ssl.Version = SslProtocols.Tls12;
factory.Ssl.ServerName = "localhost"; //System.Net.Dns.GetHostName();
factory.Ssl.CertPath = @"C:'OpenSSL-Win64'client'keycert.p12";
factory.Ssl.CertPassphrase = "Re$sp3cMyS3curi1ae!";
factory.Ssl.Enabled = true;
factory.Port = 5671;
// Error: "The remote certificate is invalid according to the validation procedure."
using (var connection = factory.CreateConnection())
{
}
有一个关于"远程证书根据验证过程无效"异常的StackOverflow帖子,但黑客修复似乎没有生效,因为所建议的回调方法从未被调用。我认为我已经将通过OpenSSL生成的证书添加到本地计算机的Windows可信根证书颁发机构证书列表中。所以我很困惑。对如何继续有什么想法吗?
Edit:这是为在Rabbit上实现SSL而挣扎的人提供的最终工作代码:
var factory = new ConnectionFactory();
factory.HostName = ConfigurationManager.AppSettings["rabbitmqHostName"];
factory.AuthMechanisms = new AuthMechanismFactory[] { new ExternalMechanismFactory() };
// Note: This should NEVER be "localhost"
factory.Ssl.ServerName = ConfigurationManager.AppSettings["rabbitmqServerName"];
// Path to my .p12 file.
factory.Ssl.CertPath = ConfigurationManager.AppSettings["certificateFilePath"];
// Passphrase for the certificate file - set through OpenSSL
factory.Ssl.CertPassphrase = ConfigurationManager.AppSettings["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 = 5671;
factory.VirtualHost = "/";
// Standard RabbitMQ authentication (if not using ExternalAuthenticationFactory)
//factory.UserName = ConfigurationManager.AppSettings["rabbitmqUsername"];
//factory.Password = ConfigurationManager.AppSettings["rabbitmqPassword"];
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
// publish some messages...
}
}
谢谢,安迪
通常的问题是您在Ssl.ServerName
中提供的内容与颁发给主机的SSL证书不匹配。
还要注意服务器端SSL(客户端和服务器之间的加密连接)和客户端证书身份验证(您向服务器提供确认您拥有它期望的证书的信息)是两个不同的东西。通过提供Ssl.CertPath
,您打算使用此证书对服务器进行授权,这可能是您想要的,也可能不是。
我的问题与使用自签名证书有关。我必须添加sslloption AcceptablePolicyErrors = SslPolicyErrors。RemoteCertificateNameMismatch |SslPolicyErrors。RemoteCertificateChainErrors
在示例中,连接工厂创建代码sslEnabled为true。
new ConnectionFactory()
{
Uri = uri,
ClientProvidedName = clientProvidedName,
AutomaticRecoveryEnabled = true,
Ssl = new SslOption(){
Enabled = sslEnabled,
AcceptablePolicyErrors = SslPolicyErrors.RemoteCertificateNameMismatch |
SslPolicyErrors.RemoteCertificateChainErrors} ,
NetworkRecoveryInterval = TimeSpan.FromSeconds(networkRecoveryIntervalSecs)
}
就像这样简单
const string RabbitMqServerHostname = "myserver.northeurope.cloudapp.azure.com";
var factory = new ConnectionFactory()
{
HostName = RabbitMqServerHostname,
UserName = "myuser",
Password = "mypassword",
// The settings below turn on SSL
Port = 5671,
Ssl = new SslOption
{
Enabled = true,
ServerName = RabbitMqServerHostname
}
};
我刚刚用。net 4.5客户端(v. 3.6.6)和Windows上的RabbitMQ代理/服务(v. 3.6.6, Erlang 19.2)进行了类似的令人沮丧的练习。
RabbitMQ配置文件选项和客户端设置的正确组合并不直观,并且客户端工厂对象自文档上次更新以来已经更改。现在有一门贪渎课。
你还有问题吗?也许我能帮你。
我已经解决了只更改Ssl的问题。
服务器名称到颁发证书的通用名称(CN),因为它与承载服务的服务器不同。factory.Ssl.ServerName = "[certificate cn]";
我曾尝试使用python(因为提供程序使用该语言)并且它工作,我想然后python不验证证书的特性(它更不安全?)。