Saturday, November 28, 2015

RabbitMQ - WSO2 ESB 4.9.0 Secure Communication Channel Implementation part 1

Environment

  • WSO2 ESB 4.9.0
  • RabbitMQ 3.5.6
  • Erlang 17.3
  • JAVA 1.7

Description


 In this blog post I'm going to share my knowledge on Securing the connection between RabbirMQ Message Broker and WSO2 ESB.

The use case here going to explain is, ESB is going to act as a consumer and consumes messages from RabbitMQ server. So simply ESB will act as a Client and RabbitMQ Server Will act as the Server.

As the first step lets create certificates and keys which required for the RabbitMQ Server and the ESB to create SSL communication.
I'm following the same steps in official RabbitMQ site to create server and client certificates and keys. 

We have to follow the following steps in order to achieve
  1. Create own certificate Authority
  2. Generate CA signed certificates to the server
  3. Generate CA signed certificates to the client

Creating  the Certificate Authority


First, go in to desirable directory and execute following commands. (Note – remove the # mark and execute each line separately)

 # mkdir testca  
 # cd testca  
 # mkdir certs private  
 # chmod 700 private  
 # echo 01 > serial  
 # touch index.txt  

 Then create a new file using the following command, inside the tesca directory.

 #gedit openssl.cnf  

Add following content to the openssl.cnf file and save the file

 [ca]  
 default_ca = testca  
 [ testca ]  
 dir = .  
 certificate = $dir/cacert.pem  
 database = $dir/index.txt  
 new_certs_dir = $dir/certs  
 private_key = $dir/private/cakey.pem  
 serial = $dir/serial  
 default_crl_days = 7  
 default_days = 365  
 default_md = sha1  
 policy = testca_policy  
 x509_extensions = certificate_extensions  
 [ testca_policy ]  
 commonName = supplied  
 stateOrProvinceName = optional  
 countryName = optional  
 emailAddress = optional  
 organizationName = optional  
 organizationalUnitName = optional  
 [ certificate_extensions ]  
 basicConstraints = CA:false  
 [ req ]  
 default_bits = 2048  
 default_keyfile = ./private/cakey.pem  
 default_md = sha1  
 prompt = yes  
 distinguished_name = root_ca_distinguished_name  
 x509_extensions = root_ca_extensions  
 [ root_ca_distinguished_name ]  
 commonName = hostname  
 [ root_ca_extensions ]  
 basicConstraints = CA:true  
 keyUsage = keyCertSign, cRLSign  
 [ client_ca_extensions ]  
 basicConstraints = CA:false  
 keyUsage = digitalSignature  
 extendedKeyUsage = 1.3.6.1.5.5.7.3.2  
 [ server_ca_extensions ]  
 basicConstraints = CA:false  
 keyUsage = keyEncipherment  
 extendedKeyUsage = 1.3.6.1.5.5.7.3.1  

So now we can create key and the certificate for the Certificate Authority. Still inside the tesca directory, execute following commands.

 # openssl req -x509 -config openssl.cnf -newkey rsa:2048 -days 365 -out cacert.pem -outform PEM -subj /CN=MyTestCA/ -nodes  
 # openssl x509 -in cacert.pem -out cacert.cer -outform DER  


So now we have successfully created our Certificate Authority. Then we need to create keys and certificates for the server and the client.

Generating certificate and key for the Server


Assuming you are still inside the testca directory, execute the following commands.

 # cd ..  
 # ls  
 # mkdir server  
 # cd server  
 # openssl genrsa -out key.pem 2048  
 # openssl req -new -key key.pem -out req.pem -outform PEM -subj /CN=$(hostname)/O=server/ -nodes  
 # cd ../testca  
 # openssl ca -config openssl.cnf -in ../server/req.pem -out ../server/cert.pem -notext -batch -extensions server_ca_extensions  
 # cd ../server  
 # openssl pkcs12 -export -out keycert.p12 -in cert.pem -inkey key.pem -passout pass:MySecretPassword  

Generating certificate and key for the client

 # cd ..  
 # ls  
 # mkdir client  
 # cd client  
 # openssl genrsa -out key.pem 2048  
 # openssl req -new -key key.pem -out req.pem -outform PEM -subj /CN=$(hostname)/O=client/ -nodes  
 # cd ../testca  
 # openssl ca -config openssl.cnf -in ../client/req.pem -out ../client/cert.pem -notext -batch -extensions client_ca_extensions  
 # cd ../client  
 # openssl pkcs12 -export -out keycert.p12 -in cert.pem -inkey key.pem -passout pass:MySecretPassword  

We are done here, now we have Certificate Authority, Server and Client Certificates and Keys. So lets move to configure the RabbitMQ server.


Configuring RabbiMQ Server



I have already written a blog post on configuring the RabbitMQ. You can follow this link to get details about it. I prefer to use generic Linux package, then you can access resources in one location. (logs, config files etc.)

You need to know some important resources and their location before proceeding ahead.

  • Rabbitmq log file – [Rabbit_Home]/var/log (There are two log files available, required one is rabbit@user-machine.log (not the sasl.log file))
  • Rabbitmq configuration file – [Rabbit_Home]/etc/rabbitmq (by default there is no configuration file available. You can create new configuration file with name of rabbitmq.config)

Also use following commands to start and stop the RabbitMQ server (Assuming you are in [RabbitMQ_Home]/sbin directory)

  • To start - ./rabbitmq-server start
  • To stop - ./rabbitmqctl stop

I think you have successfully installed the RabbitMQ plugins and the Management console is up and running.

After you start the server, you can see following log entries in rabbit.log file.

=INFO REPORT==== 9-Nov-2015::14:57:52 ===
started TCP Listener on [::]:5672

=INFO REPORT==== 9-Nov-2015::14:58:00 ===
Management plugin started. Port: 15672

RabbitMQ server is listening on TCP port 5672 which is the default port and we can't see any ports activated for the SSL connections.

Configuring rabbitmq.config file we can enable SSL listener with various SSL options. Following is sample rabbitmq.config file.

  [  
        { rabbitmq_management,[{listener, [ {port, 15672},   
                               {ssl, true},   
                               {ssl_opts, [{cacertfile,"/home/krishan/testca/cacert.pem"},  
                                       {certfile, "/home/krishan/server/cert.pem"},  
                                      {keyfile, "/home/krishan/server/key.pem"}  
                                      ]  
                               }  
                             ]  
                       }]  
        },  
        {ssl, [{versions, ['tlsv1.2']}]},  
        {rabbit,[  
             {tcp_listeners, [5672]},  
             {ssl_listeners, [5671]},  
             {ssl_options, [{cacertfile,"/home/krishan/testca/cacert.pem"},  
                      {certfile, "/home/krishan/server/cert.pem"},  
                      {keyfile, "/home/krishan/server/key.pem"},  
                      {verify, verify_none},  
                      {fail_if_no_peer_cert,false},  
                      {versions, ['tlsv1.2']}                       
                     ]  
               }  
              ]  
        }  
  ].  



After adding the rabbitmq.config file, restart the server. Then you can see the following entries in rabbit.log file.

=INFO REPORT==== 9-Nov-2015::16:57:47 ===
started TCP Listener on [::]:5672

=INFO REPORT==== 9-Nov-2015::16:57:47 ===
started SSL Listener on [::]:5671

So you can see that the RabbitMQ server has started SSL listner on port 5671.

We are now almost done with configuring the RabbitMQ broker and lets see the configuration of the WSO2 ESB in my next post.