Active MQ Installation, Security Setup and Hardening - How to

theOverview

ActiveMQ is a Message Oriented Middleware (MOM) also knows as  Message Broker (or) JMS provider with Enterprise features fully loaded. Apache ActiveMQ is one of the best Message broker in the enterprise market, because of it's usability and being robust. Comes from the Apache Software Foundation.

In this post, we are going to discuss the following topics

  • How to install ActiveMQ and perform Security Hardening practices
  • How to configure Broker Authentication?
  • How to configure Broker Authorization (or)  role-based access for the Queues and Topics?
  • How to secure the web console?

 

Let us get started.

 

Infrastructure Setup

  1. Download ActiveMQ Zip distribution from  http://activemq.apache.org/activemq-5153-release.html ( This is the version used in this post)
  2. Extract the zip and goto bin directory and  start your ActiveMQ server ./activemq start  ( Note: In linux OS its shell and for windows it batch )
[email protected]:/apps/activemq/apache-activemq-5.15.3/bin$ ./activemq start
INFO: Loading '/apps/activemq/apache-activemq-5.15.3//bin/env'
INFO: Using java '/usr/bin/java'
INFO: Starting - inspect logfiles specified in logging.properties and log4j.properties to get details
INFO: pidfile created : '/apps/activemq/apache-activemq-5.15.3//data/activemq.pid' (pid '2047')

 

 

Verify your setup

If you have not made any changes in the configuration and started the activeMQ as it was retrieved.

You can go ahead and hit the  URL

http://127.0.0.1:8161/admin/

The default username and password to access the console is admin/admin

 

Secure your ActiveMQ Broker and Web Console

Note*: All the configurations files mentioned here assumed to be available at default activemq/conf/ directory

ActiveMQ can have two Authentication providers they are JAAS Authentication Provider and Simple Authentication Provider

These providers are applied in the configuration using plugin elements

  1.  JAAS Authentication Plugin
  2.  Simple Authentication Plugin

We will be discussing how to implement both security providers in ActiveMQ

Before you proceed, Broker username and password and Authentication and the  Web console username and password and authentication is different.

So we have divided this article into three smaller units

  • Broker Security using JAAS Plugin - With No Password Encryption
  • Broker Security using Simple Authentication Plugin - With Password Encryption
  • Web console Security - With Password Encryption

Broker Security using JAAS Plugin (Non-Encrypted Password)

 

Step1: Update ActiveMQ.xml with JAASAuthentication Plugin configuration

Add the following line beneath the <broker> element in activemq.xml

Step2:  Validate Login.config and Configure JAAS configuration and its properties

In Step1 we have used activemq as the value for configuration (configuration="activemq"). This actually refers to the configuration available at login.config. Open the login.config file and see what user and group properties file names are. By Default, they are users.properties and groups. properties 

activemq {
    org.apache.activemq.jaas.PropertiesLoginModule required
        org.apache.activemq.jaas.properties.user=&quot;users.properties&quot;
        org.apache.activemq.jaas.properties.group=&quot;groups.properties&quot;;
};

 

Step3:  Open the users. properties and change the default password and add new users

  • Add a new user named "testuser" into users.properties and add the "testuser" into users group in groups.properties 
  • Add a new user named "testguest" into users.properties and add the "testguest" into guests group in groups.properties 

these testuser and testguest accounts will be used to test the role-based authentication later

admin=c0mp!ex@01
testuser=S3CURe!
testguest=S3CURe!
admins=admin
users=testuser
guests=testguest

 

Step4: Setup role based Authorization for the Queues and Topics

In ActiveMQ.xml, Inside the plugins tag.  Paste the following content

 

here queue=">"indicate all the Queues ( here > used as a wildcard )

USERS.> indicates the Queues starts with USERS.  in the name ( i,e: USERS.TestQueueSame applies to GUEST as well.

 

Step5: Configure the ActiveMQ web console to use the right credentials while browsing the Queues/Topics

Open the credentials.properties. This file is used to let the Activemq web console know the username and password it should use while trying to access the broker resources like Queue and Topic

by default, the file might contain values like given below.


activemq.username=system
activemq.password=manager
guest.password=password

 

Replace the activemq.username and activemq.password values with the correct values. in my case, I am going to use the admin account, discussed in the previous step

activemq.username=admin
activemq.password=c0mp!ex@01

 

Step6: Start/Restart ActiveMQ  for the changes to reflect

The Complete configuration file (activemq.xml) with all aforementioned configurations can be downloaded from  here

Broker Security using Simple Authentication Plugin ( Encrypted Password)

 

Step1:  Add the following elements in conf/activemq.xml to setup Encryption method, Encryption Key, and Properties file

In the preceding command snippet, you could notice the configurationEncryptor  is pointing to credentials-enc.properties

This file should be used to pass the encrypted username and password to the ActiveMQ broker configuration. The entries in this file could be referenced into the activemq configuration file activemq.xml

We need to pass the Secret key which is used to encrypt the password as an environment variable.  We will do that in Step 5.

Next Step is to encrypt the passwords.

 

Step2:  To add the password into credentials-enc.properties file, we must encrypt the password using ActiveMQ encrypt command.

./activemq encrypt – password mysecretkey – input c0mp!ex@01

where passwordis a secret used by the encryptor and input is the password you want to encrypt.

 

While encrypting the password, you are going to issue the password as clear text in terminal.

I would not recommend it.   Use the following script instead, which does the same thing except it reads your password secretly and not showing on the terminal

#!/bin/bash
echo &quot;Enter the password to encrypt: &quot;
read -s pass
./activemq encrypt – password mysecretkey – input $pass

 

Here is Sample output  taken as it runs

[email protected]:/apps/amq/apache-activemq-5.15.3/bin$ ./encrypt.sh 
Enter the password to encrypt: 
INFO: Loading '/apps/amq/apache-activemq-5.15.3//bin/env'
INFO: Using java '/usr/bin/java'
Java Runtime: Oracle Corporation 1.8.0_152 /Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre
  Heap sizes: current=62976k  free=61658k  max=932352k
    JVM args: -Xms64M -Xmx1G -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=/apps/amq/apache-activemq-5.15.3//conf/login.config -Dactivemq.classpath=/apps/amq/apache-activemq-5.15.3//conf:/apps/amq/apache-activemq-5.15.3//../lib/: -Dactivemq.home=/apps/amq/apache-activemq-5.15.3/ -Dactivemq.base=/apps/amq/apache-activemq-5.15.3/ -Dactivemq.conf=/apps/amq/apache-activemq-5.15.3//conf -Dactivemq.data=/apps/amq/apache-activemq-5.15.3//data
Extensions classpath:
  [/apps/amq/apache-activemq-5.15.3/lib,/apps/amq/apache-activemq-5.15.3/lib/camel,/apps/amq/apache-activemq-5.15.3/lib/optional,/apps/amq/apache-activemq-5.15.3/lib/web,/apps/amq/apache-activemq-5.15.3/lib/extra]
ACTIVEMQ_HOME: /apps/amq/apache-activemq-5.15.3
ACTIVEMQ_BASE: /apps/amq/apache-activemq-5.15.3
ACTIVEMQ_CONF: /apps/amq/apache-activemq-5.15.3/conf
ACTIVEMQ_DATA: /apps/amq/apache-activemq-5.15.3/data
Encrypted text: qf/gz6Vde5woFY9vx0Z2ocD77M0Wzf3o

The last line contains the Encrypted Text and that's your encrypted password.

Note*: You must also encrypt the password of activemq default account's [system] password. The default password for the systemuser account is manager

After encrypting all the passwords, you need to add it to the credentials-enc.properties file

Step3:  Add the encrypted passwords into credentials-enc.properties file.

activemq.username=system
activemq.password=ENC(akuvjz1mFoau15BJwE5Mpg==)
admin.username=admin
admin.password=ENC(psJMVHGCcYjyZ+HvZFkBpOzIwnbcZygn)
testuser.username=testuser
testuser.password=ENC(Ci5pGj/RNaP85ZWnwT0zdA==)
testguest.username=testguest
testguest.password=EN(Ci5pGj/RNaP85ZWnwT0zdA==)

Here we have  configured four usernames and its passwords

  1. activemq.username and activemq.password for default system account ( this account is used by the web console to access the broker resources )
  2. admin.username and admin.password is for admin privileged account
  3. testuser.username and testuser.password is for user privileged account
  4. testguest.username and testguest.password is for guest privileged account

 

Step4: Add the following Simple authentication plugin into activemq.xml file right after the <broker> tag starts

Step5: In order to setup Authorization, we must also add the Authorization plugin. Add the following entry, into <plugins></plugins> element

Step6: Run Active-MQ using Encrypted Passwords

To run the Active-MQ broker with encrypted password configuration, follow the following steps:

  1. Set environment variable for encryption
    $ export ACTIVEMQ_ENCRYPTION_PASSWORD=mysecretkey
  2. Set the AMQ broker
    $ bin/activemq start 
  3. Reset the environment variable for encryption
    $ unset ACTIVEMQ_ENCRYPTION_PASSWORD

    Resetting the environment is important to avoid saving passwords on your system.

Step7: Start/Restart the ActiveMQ

The Complete configuration file (activemq.xml) with all aforementioned configurations can be downloaded from  here

Secure the console by encrypting the web-console username and password

 

By default, web console user credentials are stored in jetty-realm.properties

It will have a clear text username and password as shown below


# Defines users that can access the web (console, demo, etc.)
# username: password [,rolename ...]
admin: admin, admin
user: user, user

Now we need to encrypt this password for better security. This is how you need to do that

  1.  Download Jetty from https://www.eclipse.org/jetty/download.html
  2.  Unzip and Untar the downloaded package into the desired location on your server. Finally, you will get a directory like this

    jetty-distribution-9.4.10.v20180503  ( Version might change )

  3. cd to that directory and you need to execute the encryption command
[email protected]:/apps/amq/jetty-distribution-9.4.10.v20180503$ java -cp lib/jetty-util-9.4.10.v20180503.jar org.eclipse.jetty.util.security.Password adminuser admin
2018-05-22 02:48:41.398:INFO::main: Logging initialized @179ms to org.eclipse.jetty.util.log.StdErrLog
admin
OBF:1u2a1toa1w8v1tok1u30
MD5:21232f297a57a5a743894a0e4a801fc3
CRYPT:adpexzg3FUZAk

Here adminuser is the salt which is used to encrypt the password not the actual username and admin is the password

The last line contains our encrypted password

CRYPT:adpexzg3FUZAk

Now, Copy this password to jetty-realm.properties and replace the clear text password

# Defines users that can access the web (console, demo, etc.)
# username: password [,rolename ...]
admin: CRYPT:adpexzg3FUZAk, admin
user: user, user

Start/Restart your ActiveMQ instance

 

Test the Broker Authorization and Authentication

 

To Test the Broker Authentication and Authorization is working as expected.  We need a JMS Client which could connect to the broker and do some task like sending (or) receiving messages from the queue.

You can use the following JMS Client we have designed. AMQ-QUEUE-CLI.jar

How to use it

  1. Download the ZIP file from here and extract the files
  2. AMQ-QUEUE-CLI.jar support both send/publish and receive/consume operation

To Send a message to the Queue use the following QueueSender CLI

java -cp AMQ-QUEUE-CLI.jar QueueSender

Execution Result

[email protected]:/users/aksarav/tools$ java -cp AMQ-QUEUE-CLI.jar QueueSender
-------------------------------
ACTIVEMQ - QUEUE SENDER - CLI
-------------------------------

Enter the Queue Name you wanna send this message to  (or) &quot;quit&quot; to exit : TestQueue

Enter the details to Connect to ActiveMQ
Enter the UserName : admin
Enter the Password : c0mp!ex@01
Enter the ConnectionURL : tcp://localhost:61616

Enter the message to send: 
Test Message One
 INFO | sent message with text='Test Message One'

Enter the Queue Name you wanna send this message to  (or) &quot;quit&quot; to exit : TestQueue
 INFO | Taking Already Entered Username,Password and ActiveMQ URL

Enter the message to send: 
Test Message Two
 INFO | sent message with text='Test Message Two'

Enter the Queue Name you wanna send this message to  (or) &quot;quit&quot; to exit : TestQueue
 INFO | Taking Already Entered Username,Password and ActiveMQ URL

Enter the message to send: 
Test Message Three
 INFO | sent message with text='Test Message Three'

Enter the Queue Name you wanna send this message to  (or) &quot;quit&quot; to exit : quit
You have entered Quit, We are not sure if that's Queue Name.

Please Clarify? 
1) Press One to Exit 
2) Press 2 to Reset/Continue 
3) Quit is my Queue Name

Your Option :1

To Receive a Single Message from the Queue use the QueueReceiver CLI with Single

[email protected]:/users/aksarav/tools$ java -cp AMQ-QUEUE-CLI.jar QueueReceiver onebyone
-------------------------------
ACTIVEMQ - QUEUE RECEIVER- CLI
-------------------------------

Enter the Queue Name (or) quit/Quit to Exit : TestQueue

Enter the details to Connect to ActiveMQ
Enter the UserName : admin
Enter the Password : c0mp!ex@01
Enter the ConnectionURL : tcp://localhost:61616
 INFO | 
received message with text='Test Message One'
 INFO | message acknowledged
 INFO | Test Message One

Enter the Queue Name (or) quit/Quit to Exit : quit
You have entered Quit, We are not sure if that's Queue Name.

Please Clarify? 
1) Press One to Exit 
2) Press 2 Continue 
3) Quit is my Queue Name

 Your Option :1

To Receive all the Messages from the Queue use the following command

[email protected]:/users/aksarav/tools$ java -cp AMQ-QUEUE-CLI.jar QueueReceiver allatonce
-------------------------------
ACTIVEMQ - QUEUE RECEIVER- CLI
-------------------------------

Enter the Queue Name (or) quit/Quit to Exit : TestQueue

Enter the details to Connect to ActiveMQ
Enter the UserName : admin
Enter the Password : c0mp!ex@01
Enter the ConnectionURL : tcp://localhost:61616
 INFO | 
received message with text='Test Message Two'
 INFO | message acknowledged
 INFO | Test Message Two
 INFO | 
received message with text='Test Message Three'
 INFO | message acknowledged
 INFO | Test Message Three
 INFO | no more messages to read from the queue

Enter the Queue Name (or) quit/Quit to Exit : quit
You have entered Quit, We are not sure if that's Queue Name.

Please Clarify? 
1) Press One to Exit 
2) Press 2 Continue 
3) Quit is my Queue Name

 Your Option :1


Testing the Authorization/ Role-based Access

Try this AMQ-QUEUE-CLI.jar with different accounts like admin,testuser,testguest to see how the authorization is working as per the configuration we have made.

Try to send a message to the "TestQueue"  using the testuser (or) testguest we have already created.

[email protected]:/users/aksarav/tools$ java -cp AMQ-QUEUE-CLI.jar QueueSender
-------------------------------
ACTIVEMQ - QUEUE SENDER - CLI
-------------------------------

Enter the Queue Name you wanna send this message to  (or) &quot;quit&quot; to exit : TestQueue

Enter the details to Connect to ActiveMQ
Enter the UserName : testuser
Enter the Password : S3CURe!
Enter the ConnectionURL : tcp://localhost:61616
May 22, 2018 2:21:50 PM QueueSender main
SEVERE: null
javax.jms.JMSSecurityException: User testuser is not authorized to write to: queue://TestQueue
	at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:52)
	at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1399)
	at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1428)
	at org.apache.activemq.ActiveMQSession.syncSendPacket(ActiveMQSession.java:2086)
	at org.apache.activemq.ActiveMQMessageProducer.&lt;init&gt;(ActiveMQMessageProducer.java:124)
	at org.apache.activemq.ActiveMQSession.createProducer(ActiveMQSession.java:1117)
	at QueueSender.init(QueueSender.java:72)
	at QueueSender.main(QueueSender.java:154)
Caused by: java.lang.SecurityException: User testuser is not authorized to write to: queue://TestQueue
	at org.apache.activemq.security.AuthorizationBroker.addProducer(AuthorizationBroker.java:199)
	at org.apache.activemq.broker.BrokerFilter.addProducer(BrokerFilter.java:109)
	at org.apache.activemq.broker.TransportConnection.processAddProducer(TransportConnection.java:644)
	at org.apache.activemq.command.ProducerInfo.visit(ProducerInfo.java:108)
	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:330)
	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:194)
	at org.apache.activemq.transport.MutexTransport.onCommand(MutexTransport.java:50)
	at org.apache.activemq.transport.WireFormatNegotiator.onCommand(WireFormatNegotiator.java:125)
	at org.apache.activemq.transport.AbstractInactivityMonitor.onCommand(AbstractInactivityMonitor.java:301)
	at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)
	at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:233)
	at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215)
	at java.lang.Thread.run(Thread.java:748)

As expected the user has been denied access to write message to the TestQueue. As per the Authorization configuration, we have made, testuser would only be able to write/read messages from the queues which start with the USERS. string in its name

Now Let us try creating a new Queue named "USERS.TestQueue" and try to do write/read the messages onto that queue.

Sending the Message to the USERS.TestQueue [ Queue will be auto created as its not already availalble]

[email protected]:/users/aksarav/tools$ java -cp AMQ-QUEUE-CLI.jar QueueSender
-------------------------------
ACTIVEMQ - QUEUE SENDER - CLI
-------------------------------

Enter the Queue Name you wanna send this message to  (or) &quot;quit&quot; to exit : USERS.TestQueue

Enter the details to Connect to ActiveMQ
Enter the UserName : testuser
Enter the Password : S3CURe!
Enter the ConnectionURL : tcp://localhost:61616

Enter the message to send: 
Hello There
 INFO | sent message with text='Hello There'

Enter the Queue Name you wanna send this message to  (or) &quot;quit&quot; to exit : quit
You have entered Quit, We are not sure if that's Queue Name.

Please Clarify? 
1 =&gt; Press One to Exit 
2 =&gt;  Press 2 to Reset/Continue 
3 =&gt; Quit is my Queue Name

Your Option :1

Reading the message from the USERS.TestQueue

[email protected]:/users/aksarav/tools$ java -cp AMQ-QUEUE-CLI.jar QueueReceiver allatonce
-------------------------------
ACTIVEMQ - QUEUE RECEIVER- CLI
-------------------------------

Enter the Queue Name (or) quit/Quit to Exit : USERS.TestQueue

Enter the details to Connect to ActiveMQ
Enter the UserName : testuser
Enter the Password : S3CURe!
Enter the ConnectionURL : tcp://localhost:61616
 INFO | 
received message with text='Hello There'
 INFO | message acknowledged
 INFO | Hello There
 INFO | no more messages to read from the queue

Enter the Queue Name (or) quit/Quit to Exit : quit
You have entered Quit, We are not sure if that's Queue Name.

Please Clarify? 
1 =&gt; Press One to Exit 
2 =&gt;  Press 2 Continue 
3 =&gt; Quit is my Queue Name

 Your Option :1

From the above test runs, we can conclude the Authorization (or) role-based access is working fine.

Hope this article helps. For any questions feel free to write to me / comment here.

If you like mwinventory, Subscribe for latest posts and stay connected. Leave your name and email in the below form

Loading

We promise! we never SPAM.

 

Cheers,

A K S A R A V

Write to us at [email protected]

Follow us on  Facebook |   Twitter

To Join our Community in Whatsapp – Click here