Implementing client-side certificates

In case the RabbitMQ broker and client communicate through the Internet, it sounds reasonable that only authorized clients can connect to the broker.

This is the scope of typical user password authentication, but by using, in addition, client-side certificates, the security of the distributed application is highly improved. It also avoids the possibility of MITM attack.

This recipe is the extension/prosecution of the previous one. So, we assume that we already have the CA set up and the server configured, as shown previously.

Getting ready

This recipe is just an extension of the previous one—the same recommendations apply.

How to do it…

Perform the following steps for the client to be able to connect to the RabbitMQ server:

  1. Copy the certificates and the keys, created in the previous recipe, from the Chapter03/Recipe04/certificates directory:
    cp –rp ../Recipe03/certificates/testca .
    cp –rp ../Recipe03/certificates/server .
  2. In the client certificate directory, create the client private key, as shown in Chapter03/Recipe04/certificates/04_create_client_certificates.sh:
    openssl genrsa -out key.pem 2048
  3. Create a certificate signing request:
    openssl req -new -key key.pem -out req.pem -outform PEM 
    -subj /CN=$(hostname)/O=client/ -nodes
  4. In the CA directory, sign the client certificate:
    openssl ca -config openssl.cnf -in ../client/req.pem 
    -out ../client/cert.pem -notext -batch -extensions client_ca_extensions
  5. Back in the client directory, create a PKCS#12 store containing the client certificate and the key protected by a password:
    openssl pkcs12 -export -out keycert.p12 -in cert.pem 
    -in keykey.pem -passout pass:client1234passwd
  6. Create a Java key store containing the server certificate protected with a password, as shown in Chapter03/Recipe04/certificates/05_create_keystore.sh:
    keytool -importcert -alias server001 -file server/cert.pem -keystore keystore/rabbit.jks -keypass passwd1234
  7. Change the rabbitmq.config option fail_if_no_peer_cert to true:
    {fail_if_no_peer_cert,true}
  8. Restart RabbitMQ:
    rabbitmqctl stop
    rabbitmq-server –detached
  9. On the client side, set up a secure connection by setting up the SSL context:
    char[] keyPassphrase = "client1234passwd".toCharArray();
    KeyStoreks = KeyStore.getInstance("PKCS12");
    ks.load(newFileInputStream("certificates/client/keycert.p12"), keyPassphrase);
    
    KeyManagerFactorykmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(ks, keyPassphrase);
    
    char[] trustPassphrase = "passwd1234".toCharArray();  
    KeyStoretks = KeyStore.getInstance("JKS");
    tks.load(newFileInputStream("certificates/keystore/rabbit.jks"), trustPassphrase);
    
    TrustManagerFactorytmf = TrustManagerFactory.getInstance("SunX509");
    tmf.init(tks);
    
    SSLContext c = SSLContext.getInstance("SSLv3");
    c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
    
    ConnectionFactory factory = newConnectionFactory();
    factory.setHost(hostname);
    factory.setPort(5671);
    factory.useSslProtocol(c);
    Connection connection = factory.newConnection();

How it works…

For the client certificate to work, it must be signed with the same CA that has been used to sign the server. Once the certificate is prepared, it is very useful to save it in a keystore, a PKCS#12 store as shown in step 5.

The client needs the server certificate too—it contains the server public key—and so we have prepared a keystore for this one too using a Java keystore with the Java keytool command this time.

Then we reconfigured RabbitMQ (steps 6-7). In this way, the server will deny access if the client has not presented any certificate. You can easily check this by running the previous example now.

Once the client certificates are ready, the RabbitMQ client (step 8) must use them to set up SSLContext. Unlike the previous example, we pass the following call:

factory.useSslProtocol(c);

Only a client following this setup can connect to the RabbitMQ server. The client presenting these certificates cannot connect to a server that has a different server private key since the traffic is being encrypted using the server public key stored in the server certificate.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset