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
- Download ActiveMQ Zip distribution from http://activemq.apache.org/activemq-5153-release.html ( This is the version used in this post)
- 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
- JAAS Authentication Plugin
- 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="users.properties" org.apache.activemq.jaas.properties.group="groups.properties"; };
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.TestQueue
) Same 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 password
is 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 "Enter the password to encrypt: " 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 system
user 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
activemq.username
andactivemq.password
for default system account ( this account is used by the web console to access the broker resources )admin.username
andadmin.password
is for admin privileged accounttestuser.username
andtestuser.password
is for user privileged accounttestguest.username
andtestguest.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:
- Set environment variable for encryption
$ export ACTIVEMQ_ENCRYPTION_PASSWORD=mysecretkey
- Set the AMQ broker
$ bin/activemq start
- 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
- Download Jetty from https://www.eclipse.org/jetty/download.html
- 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 )
- 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
- Download the ZIP file from here and extract the files
- 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) "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 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) "quit" 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) "quit" 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) "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 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) "quit" 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.<init>(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) "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 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) "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 to Reset/Continue 3 => 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 => Press One to Exit 2 => Press 2 Continue 3 => 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
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