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...
    }
}

谢谢,安迪

RabbitMQ + C# + SSL

通常的问题是您在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不验证证书的特性(它更不安全?)。