I'm trying to use C# to get RabbitMQ 3.6.2 to use SSL/TLS on Windows 7 against Erlang 18.0. I'm running into errors when I'm enabling SSL in my C# code. I have gone through the steps to set up SSL/TLS here. I've also gone through the [troubleshooting steps][2] which show turn up successful (except I couldn't do the stunnel step due to lack of knowledge of stunnel). Here's my C# code trying to connect to RabbitMQ:
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())
{
}
There's a StackOverflow post regarding the "The remote certificate is invalid according to the validation procedure." exception, but the hack fix doesn't seem to take effect as the callback method suggested is never called. I think that I've added my certificate generated via OpenSSL to the Windows Trusted Root Certification Authorities certificates list for local computer. So I'm at a loss here. Any ideas on how to proceed?
Edit: Here's the final working code for anyone struggling to implement SSL on Rabbit:
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...
}
}
Thanks,
Andy
It can be done as simple as this
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
}
};
My problem was related to using self signed certificates. I had to add the SslOption AcceptablePolicyErrors = SslPolicyErrors.RemoteCertificateNameMismatch | SslPolicyErrors.RemoteCertificateChainErrors
In the example connection factory creation code sslEnabled is true.
new ConnectionFactory()
{
Uri = uri,
ClientProvidedName = clientProvidedName,
AutomaticRecoveryEnabled = true,
Ssl = new SslOption(){
Enabled = sslEnabled,
AcceptablePolicyErrors = SslPolicyErrors.RemoteCertificateNameMismatch |
SslPolicyErrors.RemoteCertificateChainErrors} ,
NetworkRecoveryInterval = TimeSpan.FromSeconds(networkRecoveryIntervalSecs)
}
Usual problem is mismatch between what you provide in Ssl.ServerName
and host SSL certificate was issued for.
Also note that server-side SSL (encrypted connection between your client and server) and client-side authentication with certificate (you provide server with information which confirms that you have certificate it expects) are two different things. By providing Ssl.CertPath
you intent to authorize at server using this certificate, which might or might not be what you want.
I just went through a similar frustrating exercise with the .NET 4.5 client (v. 3.6.6) and the RabbitMQ broker/service on Windows (v. 3.6.6, Erlang 19.2).
The correct combination of RabbitMQ config file options and client settings is not intuitive and the client factory object has changed since the documentation was last updated. Now there's an SslOption class.
Are you still having problems? Perhaps I can help you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With