RabbitMQ is an AMQP provider i.e. it can reliably queue, service and maintain messages according to a range of policies and parameters.
By default, it listens to plain old TCP connections and sends and receives messages over plaintext. This feature just works "out of the box". For users who wish to use SSL over TCP aka TLS, it requires a bit more work on their part.
By default, it listens to plain old TCP connections and sends and receives messages over plaintext. This feature just works "out of the box". For users who wish to use SSL over TCP aka TLS, it requires a bit more work on their part.
- First, let's create a bunch of certificates and sign them with our own CA. For this, we'll use easyrsa3. Easyrsa is a CLI tool to create, sign and manage your own certification authorities. It's maintained by OpenVPN team.
- Now, let's configure RabbitMQ for using certificate we just created. RabbitMQ uses configuration stored at /etc/rabbitmq/rabbitmq.config. The relevant additions needed are as follows,
[ {rabbit, [ {ssl_listeners, [5671]}, {ssl_options, [{cacertfile,"/path/to/easyrsa/ca.crt"}, {certfile,"/path/to/server/broker.crt"}, {keyfile,"/path/to/server/broker.key"}, {password, "password-used-to-encrypt-broker.key
"}, {verify, verify_peer}, {fail_if_no_peer_cert, false}]} ]} ]. - Make sure user "rabbitmq" has access to the certificates otherwise you'll see "eacess" errors being raised while trying to connect. What worked for me was to chown these files to rabbitmq user and chmod read access to others (o+r) to all the directories above the file.
- You might want to tail rabbitmq log file, for knowing what is happening where. The log files are at, /var/log/rabbitmq/.
- After every change in rabbitmq configuration, you'll need to restart the service using systemctl/service directive, as the case maybe.
- To test if the connections are proper, we may use openssl.
$ openssl s_client -connect localhost:5671 -cert /etc/rabbitmq/ssl/client/cert.pem -key /etc/rabbitmq/ssl/client/key.pem -CAfile /etc/rabbitmq/ssl/certificate_auth/cacert.pem
Make sure to keep an eye on the rabbitmq log file and the console output. Any errors here will indicate a problem with the configuration. - Now, let's delve into the actual client code. Let's look at Python first,
- PYTHON
import ssl
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost', port=5671, ssl=True, ssl_options=dict(
ssl_version=ssl.PROTOCOL_TLSv1,
ca_certs="/path/to/ca.crt",
certfile="/path/to/client.crt",
keyfile="/path/to/client.key",
cert_reqs=ssl.CERT_REQUIRED
)))
channel = connection.channel() - JAVA
Before doing anything, you'll first need to import the broker/server certificate into your client's truststore. Truststores are JDK's way of specifing and storing trusted certificates. To import broker's certificate into a truststore file,$ keytool -import -alias server1 -file /path/to/server/cert.pem -keystore /path/to/rabbitstore
Also, we'll need client public and private key and certificates combined in p12 format. For that we'll again use easyrsa3,./easyrsa export-p12 client
The Java code to connect to broker is as follows,import java.io.*;
import java.security.*;
import javax.net.ssl.*;
import com.rabbitmq.client.*;
char[] keyPassphrase = "MySecretPassword".toCharArray();
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new FileInputStream("/path/to/client/keycert.p12"), keyPassphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, passphrase);
char[] trustPassphrase = "rabbitstore".toCharArray();
KeyStore tks = KeyStore.getInstance("JKS");
tks.load(new FileInputStream("/path/to/trustStore"), trustPassphrase);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(tks);
SSLContext c = SSLContext.getInstance("TLSv1.2");
c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5671);
factory.useSslProtocol(c);
Connection conn = factory.newConnection();
Download easyrsa using your native package manager i.e. yum or apt-get
$cp -Rp /usr/share/easy-rsa ~/easy-rsa-3
$cd ~/easy-rsa-3
$./easyrsa init-pki
$./easyrsa build-ca
$./easyrsa build-server-full broker [nopass]
$./easyrsa build-client-full client1 [nopass]This creates three entities (collection of private keys, public keys and certificates) for a CA, a server named broker and a client named client1. Private keys are stored in ./private/, certificates are stored in ./issued. You may move the files to any suitable place you like for it's required that we link them up at appropriate places. Be careful about the keys, as they to be kept secret. Using nopass switch will disable PEM password, might be useful when you don't to prompt user for PEM password.
Comments
Post a Comment