Hot questions for Using RabbitMQ in ssl

Question:

I'm currently trying to migrate some Java components at to have RabbitMQ connection authentication be performed through SSL client certificates instead of the PLAIN method but, after several days, am still struggling with it as all java component connection attempts are met with handshake errors. Looking into RabbitMQ: handshake error when attempting to use SSL certificates or RabbitMQ SSL giving handshake failure when using SpringAMQP has unfortunately not wielded any results for me.

The environment I'm trying to make this work is an "inherited" VirtualBox VM running Ubuntu LTS 14.04 that represents pretty much the environment I want to deploy to.

The output of rabbitmqctl report is as follows:

Status of node 'rabbit@developer-VirtualBox' ...
[{pid,23352},
 {running_applications,
     [{rabbitmq_management,"RabbitMQ Management Console","3.4.2"},
      {rabbitmq_web_dispatch,"RabbitMQ Web Dispatcher","3.4.2"},
      {webmachine,"webmachine","1.10.3-rmq3.4.2-gite9359c7"},
      {mochiweb,"MochiMedia Web Server","2.7.0-rmq3.4.2-git680dba8"},
      {rabbitmq_management_agent,"RabbitMQ Management Agent","3.4.2"},
      {rabbit,"RabbitMQ","3.4.2"},
      {ssl,"Erlang/OTP SSL application","5.3.2"},
      {public_key,"Public key infrastructure","0.21"},
      {crypto,"CRYPTO version 2","3.2"},
      {asn1,"The Erlang ASN1 compiler version 2.0.4","2.0.4"},
      {os_mon,"CPO  CXC 138 46","2.2.14"},
      {inets,"INETS  CXC 138 49","5.9.7"},
      {rabbitmq_auth_mechanism_ssl,
          "RabbitMQ SSL authentication (SASL EXTERNAL)","3.4.2"},
      {amqp_client,"RabbitMQ AMQP Client","3.4.2"},
      {xmerl,"XML parser","1.3.5"},
      {mnesia,"MNESIA  CXC 138 12","4.11"},
      {sasl,"SASL  CXC 138 11","2.3.4"},
      {stdlib,"ERTS  CXC 138 10","1.19.4"},
      {kernel,"ERTS  CXC 138 10","2.16.4"}]},
 {os,{unix,linux}},
 {erlang_version,
     "Erlang R16B03 (erts-5.10.4) [source] [64-bit] [async-threads:30] [kernel-poll:true]\n"},
 {memory,
     [{total,42662672},
      {connection_readers,0},
      {connection_writers,0},
      {connection_channels,0},
      {connection_other,5264},
      {queue_procs,2632},
      {queue_slave_procs,0},
      {plugins,411368},
      {other_proc,14374616},
      {mnesia,59360},
      {mgmt_db,124224},
      {msg_index,34312},
      {other_ets,1135040},
      {binary,42680},
      {code,21795549},
      {atom,793505},
      {other_system,3884122}]},
 {alarms,[]},
 {listeners,[{clustering,25672,"::"},{amqp,5672,"::"},{'amqp/ssl',5671,"::"}]},
 {vm_memory_high_watermark,0.4},
 {vm_memory_limit,1658211532},
 {disk_free_limit,50000000},
 {disk_free,43703377920},
 {file_descriptors,
     [{total_limit,924},{total_used,4},{sockets_limit,829},{sockets_used,2}]},
 {processes,[{limit,1048576},{used,191}]},
 {run_queue,0},
 {uptime,12}]

Cluster status of node 'rabbit@developer-VirtualBox' ...
[{nodes,[{disc,['rabbit@developer-VirtualBox']}]},
 {running_nodes,['rabbit@developer-VirtualBox']},
 {cluster_name,<<"rabbit@developer-VirtualBox">>},
 {partitions,[]}]

Application environment of node 'rabbit@developer-VirtualBox' ...
[{amqp_client,[{prefer_ipv6,false},{ssl_options,[]}]},
 {asn1,[]},
 {crypto,[]},
 {inets,[]},
 {kernel,
     [{error_logger,tty},
      {inet_default_connect_options,[{nodelay,true}]},
      {inet_dist_listen_max,25672},
      {inet_dist_listen_min,25672}]},
 {mnesia,[{dir,"/var/lib/rabbitmq/mnesia/rabbit@developer-VirtualBox"}]},
 {mochiweb,[]},
 {os_mon,
     [{start_cpu_sup,false},
      {start_disksup,false},
      {start_memsup,false},
      {start_os_sup,false}]},
 {public_key,[]},
 {rabbit,
     [{auth_backends,[rabbit_auth_backend_internal]},
      {auth_mechanisms,['EXTERNAL']},
      {backing_queue_module,rabbit_variable_queue},
      {channel_max,0},
      {cluster_keepalive_interval,10000},
      {cluster_nodes,{[],disc}},
      {cluster_partition_handling,ignore},
      {collect_statistics,fine},
      {collect_statistics_interval,5000},
      {default_permissions,[<<".*">>,<<".*">>,<<".*">>]},
      {default_user,<<"guest">>},
      {default_user_tags,[administrator]},
      {default_vhost,<<"/">>},
      {delegate_count,16},
      {disk_free_limit,50000000},
      {enabled_plugins_file,"/etc/rabbitmq/enabled_plugins"},
      {error_logger,
          {file,"/var/log/rabbitmq/rabbit@developer-VirtualBox.log"}},
      {frame_max,131072},
      {halt_on_upgrade_failure,true},
      {handshake_timeout,10000},
      {heartbeat,580},
      {hipe_compile,false},
      {hipe_modules,
          [rabbit_reader,rabbit_channel,gen_server2,rabbit_exchange,
           rabbit_command_assembler,rabbit_framing_amqp_0_9_1,rabbit_basic,
           rabbit_event,lists,queue,priority_queue,rabbit_router,rabbit_trace,
           rabbit_misc,rabbit_binary_parser,rabbit_exchange_type_direct,
           rabbit_guid,rabbit_net,rabbit_amqqueue_process,
           rabbit_variable_queue,rabbit_binary_generator,rabbit_writer,
           delegate,gb_sets,lqueue,sets,orddict,rabbit_amqqueue,
           rabbit_limiter,gb_trees,rabbit_queue_index,
           rabbit_exchange_decorator,gen,dict,ordsets,file_handle_cache,
           rabbit_msg_store,array,rabbit_msg_store_ets_index,rabbit_msg_file,
           rabbit_exchange_type_fanout,rabbit_exchange_type_topic,mnesia,
           mnesia_lib,rpc,mnesia_tm,qlc,sofs,proplists,credit_flow,pmon,
           ssl_connection,tls_connection,ssl_record,tls_record,gen_fsm,ssl]},
      {log_levels,[{connection,info}]},
      {loopback_users,[<<"guest">>]},
      {mnesia_table_loading_timeout,30000},
      {msg_store_file_size_limit,16777216},
      {msg_store_index_module,rabbit_msg_store_ets_index},
      {plugins_dir,
          "/usr/lib/rabbitmq/lib/rabbitmq_server-3.4.2/sbin/../plugins"},
      {plugins_expand_dir,
          "/var/lib/rabbitmq/mnesia/rabbit@developer-VirtualBox-plugins-expand"},
      {queue_index_max_journal_entries,65536},
      {reverse_dns_lookups,false},
      {sasl_error_logger,
          {file,"/var/log/rabbitmq/rabbit@developer-VirtualBox-sasl.log"}},
      {server_properties,[]},
      {ssl_allow_poodle_attack,false},
      {ssl_apps,[asn1,crypto,public_key,ssl]},
      {ssl_cert_login_from,distinguished_name},
      {ssl_handshake_timeout,5000},
      {ssl_listeners,[5671]},
      {ssl_options,
          [{cacertfile,"/home/developer/rabbitmqcert/devcafiles/cacert.pem"},
           {certfile,"/home/developer/rabbitmqcert/rabbitmq.public.pem"},
           {keyfile,"/home/developer/rabbitmqcert/rabbitmq.private.pem"},
           {verify,verify_peer},
           {ssl_cert_login_from,organization},
           {fail_if_no_peer_cert,true}]},
      {tcp_listen_options,
          [binary,
           {packet,raw},
           {reuseaddr,true},
           {backlog,128},
           {nodelay,true},
           {linger,{true,0}},
           {exit_on_close,false}]},
      {tcp_listeners,[5672]},
      {trace_vhosts,[]},
      {vm_memory_high_watermark,0.4},
      {vm_memory_high_watermark_paging_ratio,0.5}]},
 {rabbitmq_auth_mechanism_ssl,[{name_from,distinguished_name}]},
 {rabbitmq_management,
     [{http_log_dir,none},
      {listener,[{port,15672}]},
      {load_definitions,none},
      {rates_mode,basic},
      {sample_retention_policies,
          [{global,[{605,5},{3660,60},{29400,600},{86400,1800}]},
           {basic,[{605,5},{3600,60}]},
           {detailed,[{10,5}]}]}]},
 {rabbitmq_management_agent,[]},
 {rabbitmq_web_dispatch,[]},
 {sasl,[{errlog_type,error},{sasl_error_logger,false}]},
 {ssl,
     [{protocol_version,['tlsv1.2','tlsv1.1',tlsv1,sslv3]},
      {versions,['tlsv1.2','tlsv1.1']}]},
 {stdlib,[]},
 {webmachine,[{error_handler,rabbit_webmachine_error_handler}]},
 {xmerl,[]}]

Connections:

Channels:

Queues on /:

Exchanges on /:
name    type    durable auto_delete internal    arguments   policy
    direct  true    false   false   []  
amq.direct  direct  true    false   false   []  
amq.fanout  fanout  true    false   false   []  
amq.headers headers true    false   false   []  
amq.match   headers true    false   false   []  
amq.rabbitmq.log    topic   true    false   true    []  
amq.rabbitmq.trace  topic   true    false   true    []  
amq.topic   topic   true    false   false   []  

Bindings on /:

Consumers on /:

Permissions on /:
user    configure   write   read
O=dev,CN=rules  .*  .*  .*
guest   .*  .*  .*

Policies on /:

Parameters on /:

Going through it I can see that:

  • The _rabbitmq_auth_mechanism_ssl_ plugin is active
  • I am listening for SSL connections on port 5671
  • The only accepted auth mechanism is EXTERNAL
  • I am only accepting TLS v1.1 and TLS v1.2
  • There is a user _O=dev,CN=rules_ defined, matching the subject in the client certificate. This user has no password associated (cleared it using _sudo rabbitmqctl clear_password "O=dev,CN=rules"_ and the management screen reflects that)
  • CA cert file is read from _/home/developer/rabbitmqcert/devcafiles/cacert.pem_. This corresponds to a CA created for dev purposes, with all public keys (server and client alike) used in this being signed by it

For simplicity (and sanity), I've tried connecting to the RabbitMQ instance using the following Java code:

package com.rabbitmq.sample;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DefaultSaslConfig;
import com.rabbitmq.client.QueueingConsumer;

public class CertificateAuthenticatedRabbitMQClientExample {

    private static final String CLIENT_CERTIFICATE_PASSWORD = "MySecretPassword";
    private static final String QUEUE_USED = "sampleQueue";
    public static void main(String[] args) throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, KeyManagementException, InterruptedException {
        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        KeyManager[] clientKeyManagerList = null;
        try(FileInputStream clientCertificateInputStream = new FileInputStream(new File("/home/developer/rabbitmqcert/ruleprocessing.password.p12"))) {
            KeyStore clientKeStore = KeyStore.getInstance("PKCS12");                                        //Create a clean KeyStore
            clientKeStore.load(clientCertificateInputStream, CLIENT_CERTIFICATE_PASSWORD.toCharArray());    //Load the client's certificate into the keystore
            KeyManagerFactory clientSSLKeyManagerFactory = KeyManagerFactory.getInstance("SunX509");
            clientSSLKeyManagerFactory.init(clientKeStore, CLIENT_CERTIFICATE_PASSWORD.toCharArray());
            clientKeyManagerList = clientSSLKeyManagerFactory.getKeyManagers();                             //Get list of key managers (in essence, only the keystore with the client certificate)
        }
        TrustManager[] clientTrustManagerList = {
          new X509TrustManager() {
              //Dummy trust store that trusts any server you connect to.
              //For demo purposes only
              @Override
              public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}
              @Override
              public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}
              @Override
              public X509Certificate[] getAcceptedIssuers() { return null;}
          }
        };
        sslContext.init(clientKeyManagerList, clientTrustManagerList, null);        //Initialize SSL context with the key and trust managers we've created/loaded before

        ConnectionFactory rabbitMqConnectionFactory = new ConnectionFactory();      //Create factory
        rabbitMqConnectionFactory.setHost("localhost");
        rabbitMqConnectionFactory.setPort(5671);
        rabbitMqConnectionFactory.setSaslConfig(DefaultSaslConfig.EXTERNAL);        //Set authentication method as SSL auth
        rabbitMqConnectionFactory.useSslProtocol(sslContext);                       //Set the created SSL context as the one to use
        Connection rabbitMqOutboundConnection = null;
        Channel rabbitMqOutboundChannel = null;
        try {
            rabbitMqOutboundConnection = rabbitMqConnectionFactory.newConnection();
            rabbitMqOutboundChannel = rabbitMqOutboundConnection.createChannel();
            rabbitMqOutboundChannel.queueDeclare(QUEUE_USED, false, false, false, null);
            rabbitMqOutboundChannel.basicPublish("", QUEUE_USED, null, "This is a sample message".getBytes());
            System.out.println("Message successfully sent to queue");
        }finally{
            if(rabbitMqOutboundChannel != null) {
                rabbitMqOutboundChannel.close();
            }
            if(rabbitMqOutboundConnection != null) {
                rabbitMqOutboundConnection.close();
            }
        }
        Connection rabbitMqInboundConnection = null;
        Channel rabbitMqInboundChannel = null;
        try {
            rabbitMqInboundConnection = rabbitMqConnectionFactory.newConnection();
            rabbitMqInboundChannel = rabbitMqInboundConnection.createChannel();
            rabbitMqInboundChannel.queueDeclare(QUEUE_USED, false, false, false, null);
            QueueingConsumer rabbitMqQueueConsumer = new QueueingConsumer(rabbitMqInboundChannel);
            rabbitMqInboundChannel.basicConsume(QUEUE_USED, true, rabbitMqQueueConsumer);
            QueueingConsumer.Delivery deliveryResult = rabbitMqQueueConsumer.nextDelivery();
            System.out.println("Message read from the queue: " + new String(deliveryResult.getBody()));
        }finally{
            if(rabbitMqInboundChannel != null) {
                rabbitMqInboundChannel.close();
            }
            if(rabbitMqInboundConnection != null) {
                rabbitMqInboundConnection.close();
            }
        }
    }

}

I am, however, always greeted with a Exception in thread "main" java.net.SocketException: Broken pipe error on execution and, looking at the RabbitMQ server log, I see:

=INFO REPORT==== 29-Dec-2014::15:55:30 ===
accepting AMQP connection <0.644.0> (127.0.0.1:35299 -> 127.0.0.1:5671)

=ERROR REPORT==== 29-Dec-2014::15:55:30 ===
SSL: certify: ssl_handshake.erl:1343:Fatal error: handshake failure

Based on what I've seen around the internet and here, I've tried changing the verify value to verify_none but, when doing do, I get the following instead:

=INFO REPORT==== 29-Dec-2014::14:51:13 ===
accepting AMQP connection <0.311.0> (127.0.0.1:35271 -> 127.0.0.1:5671)

=ERROR REPORT==== 29-Dec-2014::14:51:17 ===
closing AMQP connection <0.311.0> (127.0.0.1:35271 -> 127.0.0.1:5671):
{handshake_error,starting,0,
                 {amqp_error,access_refused,
                             "EXTERNAL login refused: no peer certificate",
                             'connection.start_ok'}}

As per the advice given under the SSL troubleshooting page, I have tried performing an s_client connection to the server with, once again, different results depending on the value of verify. If verify is set to verify_peer, I get the following:

developer@developer-VirtualBox:~/rabbitmqcert$ openssl s_client -tls1_2 -connect localhost:5671 -cert ruleprocessing.public.pem -key ruleprocessing.private.pem -CAfile devcafiles/cacert.pem 
CONNECTED(00000003)
depth=1 CN = RabbitMQCA
verify return:1
depth=0 CN = rabbitmq, O = dev
verify return:1
139797055162016:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1260:SSL alert number 40
139797055162016:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:596:
---
Certificate chain
 0 s:/CN=rabbitmq/O=dev
   i:/CN=RabbitMQCA
 1 s:/CN=RabbitMQCA
   i:/CN=RabbitMQCA
---
Server certificate
-----BEGIN CERTIFICATE-----
<<OMMITED>>
-----END CERTIFICATE-----
subject=/CN=rabbitmq/O=dev
issuer=/CN=RabbitMQCA
---
Acceptable client certificate CA names
/CN=RabbitMQCA
---
SSL handshake has read 1646 bytes and written 2103 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA256
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : AES256-SHA256
    Session-ID: FC972B9A5D3EC359DC0467C8F02410E3AD66DA151C4411C0D5892115A439431A
    Session-ID-ctx: 
    Master-Key: E4FE793C71692852F6F3C4E9C5CB17774D8A50511338EF2E75691DC0DC2119F56611FC959C12429BBAFD46EC760ED713
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1419871438
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

As you can see, a handshake error happens at the start but then seems to be recovered.

If verify is set to verify_none, I get the following:

CONNECTED(00000003)
depth=1 CN = RabbitMQCA
verify return:1
depth=0 CN = rabbitmq, O = dev
verify return:1
---
Certificate chain
 0 s:/CN=rabbitmq/O=dev
   i:/CN=RabbitMQCA
 1 s:/CN=RabbitMQCA
   i:/CN=RabbitMQCA
---
Server certificate
-----BEGIN CERTIFICATE-----
<<OMMITED>>
-----END CERTIFICATE-----
subject=/CN=rabbitmq/O=dev
issuer=/CN=RabbitMQCA
---
No client certificate CA names sent
---
SSL handshake has read 1666 bytes and written 663 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA256
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : AES256-SHA256
    Session-ID: C4156551790BA116DC38A981728A71768D0B53AAEBEE969A4DA150746E5373FB
    Session-ID-ctx: 
    Master-Key: 3470DD0C0247B94EA784C3CEF94888C160205E9F06C14869B564A00AF5E4F7FAF5B4FC977E290B80DBCD140133F75AC0
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1419871570
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

This time, the handshake error does not occur occur at the start.

As a side note, since I am not very sure about "cleanliness" of the VM I got, I've actually tried creating a new VM (same Ubuntu version), installed RabbitMQ (same version), configured it in pretty much the same way (the only thing changing was certificate locations) and ran the same client code (certificate path modified). The final result was a success. Unfortunately I cannot do much with regards to getting this VM to be used as the dev VM at this time.

TL;DR; After configuring a RabbitMQ server running on an Ubuntu VM to accept SSL connections from a Java client using certificate authentication, all connection attempts fail with an handshake failure as reason if verify=verify_peer, or EXTERNAL login refused: no peer certificate if verify=verify_none


Answer:

The problem was related to the way client certificates were signed. They were signed using server_ca_extensions instead of using client_ca_extensions.

Question:

I have rabbitMQ installed using the following configuration

[
  {rabbit, [
     {ssl_listeners, [5671]},
     {ssl_options, [{cacertfile,"C:\\dev\\rabbitcert\\testca\\cacert.pem"},
                    {certfile,"C:\\dev\\rabbitcert\\server\\cert.pem"},
                    {keyfile,"C:\\dev\\rabbitcert\\server\\key.pem"},
                    {verify,verify_peer},
                    {fail_if_no_peer_cert,false}]}
   ]}
].

And i am Instantiating the Connection Factory as such (data replaced with dummy):

private static ConnectionFactory getConnectionFactoryForQueue(){
        com.rabbitmq.client.ConnectionFactory connectionFactory = new com.rabbitmq.client.ConnectionFactory();
        connectionFactory.setUsername("user");
        connectionFactory.setHost("MyIpAddress.0.1.1");
        connectionFactory.setPassword("pass");
        connectionFactory.setPort(5671);
        connectionFactory.setVirtualHost("/");
        SsmProtos.SSLDetails ssl = listener.getSslDetails();
        char[] keyPassphrase = "keyPassPhrase".toCharArray();
        try {
            KeyStore ks = KeyStore.getInstance("PKCS12");
            ks.load(new FileInputStream("path/to/keycert.p12"), keyPassphrase);

            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(ks, keyPassphrase);

            char[] trustPassphrase = "trustPassPhrase".toCharArray();
            KeyStore tks = KeyStore.getInstance("JKS");
            tks.load(new FileInputStream("path/to/trust/store"), trustPassphrase);

            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
            tmf.init(tks);

            SSLContext c = SSLContext.getInstance("SSLv3");
            c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
            connectionFactory.useSslProtocol(c);

        } catch (NoSuchAlgorithmException | CertificateException | IOException | 
                UnrecoverableKeyException | KeyStoreException | KeyManagementException e) {
            throw new IllegalArgumentException("Failed Setting up SSL",e);
        }
    return new CachingConnectionFactory(connectionFactory);
}

When I try to connect I get the following error from the Java side

Errors encountered:Error creating bean with name 'getSsmRequestAmqpAdmin' defined in class com.ixaris.ssm.server.service.ServerConfiguration: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.amqp.core.AmqpAdmin com.ixaris.ssm.shared.busobject.ServerInfoConfiguration.getSsmRequestAmqpAdmin()] threw exception; nested exception is org.springframework.amqp.AmqpIOException: java.net.SocketException: Software caused connection abort: recv failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getSsmRequestAmqpAdmin' defined in class com.ixaris.ssm.server.service.ServerConfiguration: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.amqp.core.AmqpAdmin com.ixaris.ssm.shared.busobject.ServerInfoConfiguration.getSsmRequestAmqpAdmin()] threw exception; nested exception is org.springframework.amqp.AmqpIOException: java.net.SocketException: Software caused connection abort: recv failed
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:597)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1094)
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.amqp.core.AmqpAdmin com.ixaris.ssm.shared.busobject.ServerInfoConfiguration.getSsmRequestAmqpAdmin()] threw exception; nested exception is org.springframework.amqp.AmqpIOException: java.net.SocketException: Software caused connection abort: recv failed
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:586)
Caused by: org.springframework.amqp.AmqpIOException: java.net.SocketException: Software caused connection abort: recv failed
    at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:63)
    at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:195)

Caused by: java.net.SocketException: Software caused connection abort: recv failed
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:150)

And the following appears on the rabbitMQ Logs (192.168.24.75 is my IP)

=INFO REPORT==== 14-Aug-2014::11:25:07 ===
accepting AMQP connection <0.272.0> (192.168.24.75:49860 -> 192.168.24.75:5671)

=ERROR REPORT==== 14-Aug-2014::11:25:08 ===
SSL: certify: ssl_handshake.erl:1391:Fatal error: handshake failure

=ERROR REPORT==== 14-Aug-2014::11:25:13 ===
error on AMQP connection <0.272.0>:
{ssl_upgrade_error,{tls_alert,"handshake failure"}}

Both the application and the queue are on my machine at the moment. I have opened up TCP ports 5671 and 5672 on my firewall.

Am I missing something?


Answer:

The issue was not in that code, but rather with the path to my Keycert I was using the Server Certificate rather than the Client Certificate.

Question:

I have sucessfully configurated RabbitMQ to accept TLS-Connections(Only TLS1.1 and TLS1.2)

now I have written a Java program which connects to the rabbitMQ-Server.

The server(10.0.0.120) and the 2 clients(10.0.0.121-122) are all running on an seperate RaspberryPI which almost same configuration

I can connect to the Server using openssl

root@10.0.0.122:~# openssl s_client -connect 10.0.0.120:5671
...
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : AES256-SHA256
    Session-ID:     2D1E2F6CECA4DCB3D7403E9DEF9F9DEAADF5AC15298D6CA54120F26D70D5E4A7
    Session-ID-ctx:
    Master-Key:     003C06F78281F23D8E2D7432E84B59EEABE586FA4472CF29259F8E7DAE4BD5F2F678A7F4FA27F9FBE6616481BAEEA131
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1422352831
    Timeout   : 300 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
---

root@10.0.0.121:~# openssl s_client -connect 10.0.0.120:5671
...
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : AES256-SHA256
    Session-ID:         B5538A83AE671DF2295632D02549C2E3059EED8DC73235DCE3D58FD69ABF7A62
    Session-ID-ctx:
    Master-Key: 86F3DDB68E5AB3796A9B762289AE7BD6D0E9A71CB549836D1A01C468180CAB98B9B819A1AF2255AE0BBF8B5911823EB8
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1422352895
    Timeout   : 300 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
---

both have the same java version

root@10.0.0.121:~# java -version
java version "1.7.0_40"
Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
Java HotSpot(TM) Client VM (build 24.0-b56, mixed mode)

root@10.0.0.122:~# java -version
java version "1.7.0_40"
Java(TM) SE Runtime Environment (build 1.7.0_40-b43)
Java HotSpot(TM) Client VM (build 24.0-b56, mixed mode)

and on both is running the same jar file

root@10.0.0.121:~# md5sum rabbitReceive.jar
6df91e2e714341588908798f7e28fa10  rabbitReceive.jar

root@10.0.0.122:~# md5sum rabbitReceive.jar
6df91e2e714341588908798f7e28fa10  rabbitReceive.jar

when I start the JAR file on 10.0.0.122 (where it works!) I get this on the rabbitMQ server log

=INFO REPORT==== 27-Jan-2015::11:07:11 ===
accepting AMQP connection <0.3709.0> (10.0.0.121:52944 -> 10.0.0.120:5671)

when I start the Jar file on 10.0.0.121 I get this on the rabbitMQ server log

=INFO REPORT==== 27-Jan-2015::11:08:06 ===
accepting AMQP connection <0.3755.0> (10.0.0.122:37283 -> 10.0.0.120:5671)

=ERROR REPORT==== 27-Jan-2015::11:08:11 ===
Error on AMQP connection <0.3755.0>:
 {ssl_upgrade_error,timeout}

and this exception in the Clients JVM

java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:196)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
    at sun.security.ssl.InputRecord.read(InputRecord.java:480)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)
    at sun.security.ssl.SSLSocketImpl.waitForClose(SSLSocketImpl.java:1705)
    at sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:122                                                                                                                                                                                                                                             )
    at sun.security.ssl.Handshaker.kickstart(Handshaker.java:909)
    at sun.security.ssl.SSLSocketImpl.kickstartHandshake(SSLSocketImpl.java:                                                                                                                                                                                                                                             1423)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.                                                                                                                                                                                                                                             java:1288)
    at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702)
    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
    at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82                                                                                                                                                                                                                                             )
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
    at java.io.DataOutputStream.flush(DataOutputStream.java:123)
    at com.rabbitmq.client.impl.SocketFrameHandler.sendHeader(SocketFrameHan                                                                                                                                                                                                                                             dler.java:129)
    at com.rabbitmq.client.impl.SocketFrameHandler.sendHeader(SocketFrameHan                                                                                                                                                                                                                                             dler.java:134)
    at com.rabbitmq.client.impl.AMQConnection.start(AMQConnection.java:278)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory                                                                                                                                                                                                                                             .java:617)
    at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory                                                                                                                                                                                                                                             .java:639)
    at rabbitMqTest.Test.main(Test.java:97)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.                                                                                                                                                                                                                                             java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces                                                                                                                                                                                                                                             sorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoa                                                                                                                                                                                                                                             der.java:58)

Any Ideas what the problem could be?


Answer:

As you see, between the start of your jar and the error, there are exactly 5 seconds between.

By default, the ssl-handshake timeout is set to 5 seconds. Your problem is that the ssl handshake can't be done in the default 5 seconds.

You need to change the NORMAL_TIMEOUT and possible the HANDSHAKE_TIMEOUT too at the top of rabbit_reader.erl to increase the timeout.

You can find the configuration-settings are described here.

Question:

We are using apache-camel to connect with rabbitmq. Now we are planning to connect rabbitmq using https. I followed steps to enable rabbitmq to https using

https://www.rabbitmq.com/ssl.html.

Now in my code we are using.

rabbitmq://host:port/exchange?autoAck=false&autoDelete=false&password=test&prefetchCount=1&queue=testqueue&sslProtocol=TLSv1.2&username=test

This works fine if we disable peer verification in rabbimq. But if i want to enable peer verification then i need to pass KeyManager and truststore. Not sure how can pass this details. I can see the documentation say to use connectionFactory as

To use a custom RabbitMQ connection factory. When this option is set, all connection options (connectionTimeout, requestedChannelMax…​) set on URI are not used

when i given this as part of query parameter i got below error..

ERROR [2020-01-10 19:29:12,030] io.dropwizard.cli.ServerCommand: Unable to start server, shutting down                                                                                                 
! org.apache.camel.NoSuchBeanException: No bean could be found in the registry for: com.rabbitmq.client.ConnectionFactory@44f0ff2b of type: com.rabbitmq.client.ConnectionFactory                      
! at org.apache.camel.util.CamelContextHelper.mandatoryLookup(CamelContextHelper.java:173)                                                                                                             
! at org.apache.camel.util.EndpointHelper.resolveReferenceParameter(EndpointHelper.java:326)                                                                                                           
! at org.apache.camel.util.EndpointHelper.resolveReferenceParameter(EndpointHelper.java:308)                                                                                                           
! at org.apache.camel.impl.DefaultComponent.resolveAndRemoveReferenceParameter(DefaultComponent.java:415)                                                                                              
! at org.apache.camel.impl.DefaultComponent.resolveAndRemoveReferenceParameter(DefaultComponent.java:394)                                                                                              
! at org.apache.camel.component.rabbitmq.RabbitMQComponent.createEndpoint(RabbitMQComponent.java:62)                                                                                                   
! at org.apache.camel.component.rabbitmq.RabbitMQComponent.createEndpoint(RabbitMQComponent.java:32)                                                                                                   
! at org.apache.camel.impl.DefaultComponent.createEndpoint(DefaultComponent.java:116)                                                                                                                  
! at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:631)                                                                                                               
! ... 33 common frames omitted                                                                                                                                                                         
! Causing: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: rabbitmq://host:port/exchangeName?autoAck=false&autoDelete=false&connectionFactory=com.rabbitmq.c
lient.ConnectionFactory%4044f0ff2b&password=test&prefetchCount=1&queue=testQueue&sslProtocol=TLSv1.2&username=test due to: No bean could be found in the registry for: com.rabbitmq.client.Connec
tionFactory@44f0ff2b of type: com.rabbitmq.client.ConnectionFactory                                                                                                                                    
! at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:678)                                                                                                               
! at org.apache.camel.util.CamelContextHelper.getMandatoryEndpoint(CamelContextHelper.java:80)                                                                                                         
! at org.apache.camel.model.RouteDefinition.resolveEndpoint(RouteDefinition.java:219)                                                                                                                  
! at org.apache.camel.impl.DefaultRouteContext.resolveEndpoint(DefaultRouteContext.java:112)                                                                                                           
! at org.apache.camel.impl.DefaultRouteContext.resolveEndpoint(DefaultRouteContext.java:118)                                                                                                           
! at org.apache.camel.model.FromDefinition.resolveEndpoint(FromDefinition.java:69)                                                                                                                     
! at org.apache.camel.impl.DefaultRouteContext.getEndpoint(DefaultRouteContext.java:94)                                                                                                                
! at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1278)                                                                                                                       
! at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:204)                                                                                                                        
! ... 25 common frames omitted                                                                                                                                                                         
! Causing: org.apache.camel.FailedToCreateRouteException: Failed to create route route1: Route(route1)[[From[rabbitmq://10.65.226.201:5671/preValidat... because of Failed to resolve endpoint: rabbitmq://host:port/exchangeName?autoAck=false&autoDelete=false&connectionFactory=com.rabbitmq.c
lient.ConnectionFactory%4044f0ff2b&password=test&prefetchCount=1&queue=testQueue&sslProtocol=TLSv1.2&username=test due to: No bean could be found in the registry for: com.rabbitmq.client.ConnectionFactory@44f0ff2b of type: com.rabbitmq.client.ConnectionFactory 

How can i pass connectionFactory to uri in rabbitmq.


Answer:

To pass ConnectionFactory object instance we need to do lookup of object, This can be achieved by puting object into registry, Create a registry and put the connection into registry. For details camel & Rabbitmq Custom ConnectionFactory

    SimpleRegistry simpleRegistry = new SimpleRegistry();
    String beanName = "rabbitConnectionFactory";
    simpleRegistry.put(beanName, connectionFactory);
    CamelContext camelContext = new DefaultCamelContext(simpleRegistry);

Then create rabbitmq url which will refer to connectionFactory.

"rabbitmq:/jobProgress?autoAck=false&autoDelete=false&prefetchCount=1&prefetchEnabled=true" +
            "&queue=jobProgress&connectionFactory=#rabbitConnectionFactory";

Question:

What should I do to make sure that my rabbitmq user has permission to run : C:\Windows\system32\cmd.exe . In fact i want to use SSL protocole with Rabbitmq but the node crashes. Here's the sslLogfile :

=CRASH REPORT==== 4-May-2016::18:33:16 ===
  crasher:
    initial call: rabbit_mgmt_external_stats:init/1
    pid: <0.233.0>
    registered_name: rabbit_mgmt_external_stats
    exception exit: {eacces,
                        [{erlang,open_port,
                             [{spawn,
                                  "C:\\Windows\\system32\\cmd.exe /c handle.exe /accepteula -s -p 2052 2> nul"},
                              [stream,in,eof,hide]],
                             []},
                         {os,cmd,1,[{file,"os.erl"},{line,204}]},
                         {rabbit_mgmt_external_stats,get_used_fd,1,[]},
                         {rabbit_mgmt_external_stats,'-infos/2-lc$^0/1-0-',2,
                             []},
                         {rabbit_mgmt_external_stats,'-infos/2-lc$^0/1-0-',2,
                             []},
                         {rabbit_mgmt_external_stats,emit_update,1,[]},
                         {rabbit_mgmt_external_stats,handle_info,2,[]},
                         {gen_server,handle_msg,5,
                             [{file,"gen_server.erl"},{line,599}]}]}
      in function  gen_server:terminate/6 (gen_server.erl, line 746)
    ancestors: [rabbit_mgmt_agent_sup,<0.231.0>]
    messages: []
    links: [<0.232.0>]
    dictionary: []
    trap_exit: false
    status: running
    heap_size: 4185
    stack_size: 27
    reductions: 77435063
  neighbours:

Here's my rabbitmq.config file :

[
   {ssl, [{versions, ['tlsv1.2']}]},
   {
     rabbit, 
      [
          {ssl_listeners, [5676]},
  {ssl_options, [{cacertfile,"D:/Profiles/user/AppData/Roaming/RabbitMQ/testca/cacert.pem"},
                         {certfile,  "D:/Profiles/user/AppData/Roaming/RabbitMQ/server/cert.pem"},
                         {keyfile,   "D:/Profiles/user/AppData/Roaming/RabbitMQ/server/key.pem"},
                         {versions, ['tlsv1.2']},
          {verify,verify_peer},
                         {fail_if_no_peer_cert,false}
 ]},    
       {loopback_users, []}
      ]
   }
].

Answer:

eacces is an Erlang file error:

eacces: Missing permission for reading the file, or for searching one of the parent directories.

Set the right permissions.

Stop the RabbitMQ service and try to use rabbitmq-server.bat and execute it as administrator.

Then check the logs