Sunday, January 27, 2013

Binding non-SSL-capable AMQP Clients to SSL RabbitMQ

This is an article in the RabbitMQ Configuration and Management Series.  For more articles like this, please visit the series' index.

Many languages support AMQP, but not all support SSL. Probably the most popular of the languages not supporting SSL is Node.js. Fortunately, there is a very easy solution that does not involve you rewriting a client library, and it works for every language.
The solution is to utilize stunnel, a process that will initiate an SSL connection (via OpenSSL), wrapping the underlying TCP-based communication initiated by the client. More plainly, your application connects to a port on localhost using AMQP, stunnel connects to the broker via SSL, and then pipes your local request to the AMQP broker through the SSL tunnel.
stunnel can be installed on most major operating systems (Windows, UNIX, OSX, Linux); but we will talk primary about how to do it on OSX and CentOS.
  1. Install stunnel.
    On OSX: sudo port install stunnel
    On CentOS: sudo yum install stunnel
  2. Next, we need to configure stunnel.
Create a local file and name it something like stunnel.conf.
vi stunnel.conf
Add the following to the stunnel.conf:
client = yes
foreground=yes
cert = {path to cert}/{client name}.certkey.pem

[amqp]
accept = {local port the client will communicate on}
connect = {broker IP address}:{broker SSL port}
Dissecting the file:
  • client: Indicates that we are a client contacting a server protected by SSL.
  • foreground:  Should stunnel run in the console instead of in the background.
  • cert:  A file with both the certificate and private key.
  • [amqp]:  This is a header for a route registration (we are calling it "amqp").
  • accept:  The incoming port to accept communications.
  • connect:  The port, or optionally, host and port to establish an SSL connection with.
Using our previous example:
client = yes
foreground=yes
cert = app01.certkey.pem

[amqp]
accept = 5673
connect = 192.168.192.155:5673
  1. Generate the client certificate.
    Using the certificate scripts in CMF-AMQP-Configuration:
    sh create_client_script.sh {client} {password}
    For example:
    sh create_client_script.sh app01 password123
    stunnel requires our key and certificate to be collocated in the same file. To do this, lets create a new file and append the contents of {client}.key.pem and {client}.cert.pem generated by create_client_cert.sh:

    cd {path/to/cert/dir}
    cat {client}.cert.pem >> {client}.keycert.pem
    cat {client}.key.pem >> {client}.keycert.pem

    For example:
    cd client/
    cat app01.cert.pem >> app01.keycert.pem
    cat app01.key.pem >> app01.keycert.pem
    
    The "keycert" file is now ready to be used with stunnel.
  2. Start stunnel.
    stunnel {path/to/configuartion}/stunnel.conf
    For example, assuming we are in the directory of stunnel.conf:
    stunnel stunnel.conf
  3. Now, simply start your client, binding to the port on localhost you chose stunnel to accept connections on.

Verifying stunnel Works

The CMF-AMQP-Configuration repository contains a test client to demonstrate this capability.

Install Node.js if you don't already have it installed.

Clone the CMF-AMQP-Configuration repository on GitHub:
git clone https://github.com/Berico-Technologies/CMF-AMQP-Configuration.git

Change into the node-test-client directory:
cd node-test-client

Install the the project's dependencies:
npm install

Edit the config.js file and add the correct stunnel and connection settings:
vi config.js
Using the settings from the example:
module.exports = { 
  host: "localhost", 
  port: 5673, 
  vhost: "/", 
  login: "guest", 
  password: "guest", 
  publishingInterval: 50 
};
Now run the example:
node run_test.js
If everything works as prescribed, you should see the following output in the console:

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.