Connecting rabbitMQ through SSL using .net client

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Connecting rabbitMQ through SSL using .net client

bhavyanshu
This post has NOT been accepted by the mailing list yet.
Facing issue while connecting .net client to rabbitMQ using SSL .

Below is the complete exception i am facing :

"RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were reachable ---> System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner exception. ---> System.ComponentModel.Win32Exception: The message received was unexpected or badly formatted
   --- End of inner exception stack trace ---
   at RabbitMQ.Client.EndpointResolverExtensions.SelectOne[T](IEndpointResolver resolver, Func`2 selector)
   at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
   --- End of inner exception stack trace ---
   at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver, String clientProvidedName)
   at RabbitMQ.Client.ConnectionFactory.CreateConnection()"

Below is the rabbitmq config i am using :

[{ssl, [{versions, ['tlsv1.2', 'tlsv1.1',tlsv1]}]},
{rabbit, [
     {ssl_listeners, [{"127.0.0.1", 5671}]},
     {ssl_options, [{cacertfile,"D:\\testca\\cacert.pem"},
                    {certfile,"D:\\server\\cert.pem"},
                    {keyfile,"D:\\server\\key.pem"},
                                        {password,"default"},
                                        {versions, ['tlsv1.2', 'tlsv1.1',tlsv1]},
                    {verify,verify_peer},
                                        {ssl_allow_poodle_attack,true},
                    {fail_if_no_peer_cert,false}]}
   ]}].


Below is the .net code :

  ConnectionFactory cf = new ConnectionFactory();
           
             cf.Ssl.ServerName = System.Net.Dns.GetHostName();
              cf.Uri = "amqps://guest:guest@localhost:5671/";
             cf.Ssl.CertPath = @"D:\client\keycert.p12";
             cf.Ssl.CertPassphrase = "default";

            cf.Ssl.CertificateSelectionCallback = new LocalCertificateSelectionCallback(SelectLocalCertificate);
           
            cf.Ssl.CertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
         
           
                using (IConnection conn = cf.CreateConnection())
                {
                    using (IModel ch = conn.CreateModel())
                    {
                        ch.QueueDeclare("rabbitmq-dotnet-test", false, false, false, null);
                        ch.BasicPublish("", "rabbitmq-dotnet-test", null,
                                        Encoding.UTF8.GetBytes("Hello, World"));
                        BasicGetResult result = ch.BasicGet("rabbitmq-dotnet-test", true);
                        if (result == null)
                        {
                            Console.WriteLine("No message received.");
                        }
                        else
                        {
                            Console.WriteLine("Received:");
                            DebugUtil.DumpProperties(result, Console.Out, 0);
                        }
                        ch.QueueDelete("rabbitmq-dotnet-test");
                    }
                }


I am getting call twice on SelectLocalCertificate function but ValidateServerCertificate is never called.
If i change the configuration to verify_none then a  ssl connection is established and ValidateServerCertificate  function is called.

certificates has been created through openssl following steps from the rabbitmq ssl tutorial.

Certificates has been imported manually.

Please suggest what could be the issue here.


Reply | Threaded
Open this post in threaded view
|

Re: Connecting rabbitMQ through SSL using .net client

Daniel
This post has NOT been accepted by the mailing list yet.
Firstly, you should test that SSL is working and you can connect on that port with openssl like so:
openssl s_client -connect localhost:5761 -tls1 (you can use other options, this is just an example)

If you get something back with certificate information, then you know it's open and it's a problem with your code. If not, it could be a port problem or something inside the rabbitmq config not working properly. I'd be checking your logfiles there as well, just in case. Or you can use rabbitmq-server.bat with no parameters, if it starts, you should be good. If there is an error, then read the error and check it out.

The differences in config files, I have {auth_mechanisms, ['EXTERNAL', 'PLAIN', 'AMQPLAIN']}, before {ssl_options ... }. You can try those or leave it out, doesn't matter. As long as the .net code matches what it allows. I also had some issues connecting via 'external', so try plain. As for 'versions' in your config, I don't have those, so if all else fails, remove those and try again.

The code I've used in the past is slightly different to yours, you aren't setting Ssl.Enabled, Ssl.host (so it might not even know to turn it on or where to connect).

Try something like this:
static void Main(string[] args)
        {
            bool USE_SSL = Convert.ToBoolean(ConfigurationManager.AppSettings["USE_SSL"]);
           
            var QUEUE_NAME = ConfigurationManager.AppSettings["QUEUE_NAME"];
            var QUEUE_DURABLE = Convert.ToBoolean(ConfigurationManager.AppSettings["QUEUE_DURABLE"]);
            var QUEUE_AUTODELETE = Convert.ToBoolean(ConfigurationManager.AppSettings["QUEUE_AUTODELETE"]);
            var host = "localhost";
           
            var connectionFactory = new ConnectionFactory
            {
                HostName = host,
                VirtualHost = ConfigurationManager.AppSettings["vhost"],
                Port = Convert.ToInt32(ConfigurationManager.AppSettings["port"]), //AmqpTcpEndpoint.UseDefaultPort,
                UserName = ConfigurationManager.AppSettings["username"],
                Password = ConfigurationManager.AppSettings["password"]
            };

            if(USE_SSL)
            {
                connectionFactory.AuthMechanisms = new AuthMechanismFactory[] { new PlainMechanismFactory(), new ExternalMechanismFactory() }; //This matches 'auth_mechanisms' in rabbitmq.config
                connectionFactory.Ssl = new SslOption
                {
                    Enabled = true,
                    ServerName = host,
                    AcceptablePolicyErrors = SslPolicyErrors.RemoteCertificateNameMismatch | SslPolicyErrors.RemoteCertificateChainErrors,
                    CertPath = ConfigurationManager.AppSettings["certificateFilePath"],
                    CertPassphrase = ConfigurationManager.AppSettings["certificatePassphrase"],
                    Version = SslProtocols.Tls
                };
            }

            Console.WriteLine($"\nConnecting to {connectionFactory.HostName}:{connectionFactory.Port}");

            try
            {
                using(var connection = connectionFactory.CreateConnection())
                {
                    Console.WriteLine($"Connected, declaring queue {QUEUE_NAME}");
                    using(var channel = connection.CreateModel())
                    {
                       //publish, consume, do whatever you like here
                    }
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine($"{ex.Message}\n{ex.StackTrace}");
                if(ex.InnerException != null)
                {
                    Console.WriteLine($"{ex.InnerException.Message}\n{ex.InnerException.StackTrace}");
                }
            }
        }
Reply | Threaded
Open this post in threaded view
|

Re: Connecting rabbitMQ through SSL using .net client

bhavyanshu
This post has NOT been accepted by the mailing list yet.
Hi,

I was able to connect through ssl by upgrading the erlang to 19.2.

Thanks for the support.

Regards


On Jul 4, 2017 11:11, "Daniel [via RabbitMQ]" <[hidden email]> wrote:
Firstly, you should test that SSL is working and you can connect on that port with openssl like so:
openssl s_client -connect localhost:5761 -tls1 (you can use other options, this is just an example)

If you get something back with certificate information, then you know it's open and it's a problem with your code. If not, it could be a port problem or something inside the rabbitmq config not working properly. I'd be checking your logfiles there as well, just in case. Or you can use rabbitmq-server.bat with no parameters, if it starts, you should be good. If there is an error, then read the error and check it out.

The differences in config files, I have {auth_mechanisms, ['EXTERNAL', 'PLAIN', 'AMQPLAIN']}, before {ssl_options ... }. You can try those or leave it out, doesn't matter. As long as the .net code matches what it allows. I also had some issues connecting via 'external', so try plain. As for 'versions' in your config, I don't have those, so if all else fails, remove those and try again.

The code I've used in the past is slightly different to yours, you aren't setting Ssl.Enabled, Ssl.host (so it might not even know to turn it on or where to connect).

Try something like this:
static void Main(string[] args)
        {
            bool USE_SSL = Convert.ToBoolean(ConfigurationManager.AppSettings["USE_SSL"]);
           
            var QUEUE_NAME = ConfigurationManager.AppSettings["QUEUE_NAME"];
            var QUEUE_DURABLE = Convert.ToBoolean(ConfigurationManager.AppSettings["QUEUE_DURABLE"]);
            var QUEUE_AUTODELETE = Convert.ToBoolean(ConfigurationManager.AppSettings["QUEUE_AUTODELETE"]);
            var host = "localhost";
           
            var connectionFactory = new ConnectionFactory
            {
                HostName = host,
                VirtualHost = ConfigurationManager.AppSettings["vhost"],
                Port = Convert.ToInt32(ConfigurationManager.AppSettings["port"]), //AmqpTcpEndpoint.UseDefaultPort,
                UserName = ConfigurationManager.AppSettings["username"],
                Password = ConfigurationManager.AppSettings["password"]
            };

            if(USE_SSL)
            {
                connectionFactory.AuthMechanisms = new AuthMechanismFactory[] { new PlainMechanismFactory(), new ExternalMechanismFactory() }; //This matches 'auth_mechanisms' in rabbitmq.config
                connectionFactory.Ssl = new SslOption
                {
                    Enabled = true,
                    ServerName = host,
                    AcceptablePolicyErrors = SslPolicyErrors.RemoteCertificateNameMismatch | SslPolicyErrors.RemoteCertificateChainErrors,
                    CertPath = ConfigurationManager.AppSettings["certificateFilePath"],
                    CertPassphrase = ConfigurationManager.AppSettings["certificatePassphrase"],
                    Version = SslProtocols.Tls
                };
            }

            Console.WriteLine($"\nConnecting to {connectionFactory.HostName}:{connectionFactory.Port}");

            try
            {
                using(var connection = connectionFactory.CreateConnection())
                {
                    Console.WriteLine($"Connected, declaring queue {QUEUE_NAME}");
                    using(var channel = connection.CreateModel())
                    {
                       //publish, consume, do whatever you like here
                    }
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine($"{ex.Message}\n{ex.StackTrace}");
                if(ex.InnerException != null)
                {
                    Console.WriteLine($"{ex.InnerException.Message}\n{ex.InnerException.StackTrace}");
                }
            }
        }



If you reply to this email, your message will be added to the discussion below:
http://rabbitmq.1065348.n5.nabble.com/Connecting-rabbitMQ-through-SSL-using-net-client-tp37435p37438.html
To unsubscribe from Connecting rabbitMQ through SSL using .net client, click here.
NAML