Does anybody have experience with securing/hardening ActiveMQ? Check lists or guides would be welcome.
In my option you need to think of atleast two factors when implementing the message services. These are authentication and authorization.
Authentication is the process of making sure the entity's intregrity is intact. Usually this is done by supplying a password. ActiveMQ supports JAAS and also has an API that supports custom built authentication plugins.
The easiest way to implement this is to configure your broker xml file to only allow authenticated users. Example which could be placed under the
<plugin> tag in your xml:
<simpleAuthenticationPlugin> <users> <authenticationUser username="admin" password="password" groups="admins,publishers,consumers"/> </users> </simpleAuthenticationPlugin>
The groups provided will be usefull for the authorization of the user. Very usefull when you need to only allow some services to some user groups. Use the createConnection(username, password) method for the authentication procedure.
Authorization is all about allowing an entity access to a secured resource. Often implemented with the help of ACL's. The following sample XML will provide authorization on a destination:
<authorizationPlugin> <map> <authorizationMap> <authorizationEntries> <authorizationEntry topic=">" read="admins" write="admins"admin="admins" /> <authorizationEntry topic="YourTopic.>" read="consumers" write="publishers" admin="publishers" /> <authorizationEntry topic="YourTopic.Stats" read="guests" /> </authorizationEntries> </authorizationMap> </map> </authorizationPlugin>
Note that the > wild card provides the authorization scheme recursively to anything under that path.
Message level authorization
Sometimes it can be usefull to add authorization at the message level instead of at the connection level. This is done by creating a java class MessageAuthorizationPolicy thus forcing you to implement the method boolean isAllowedToConsume(ConnectionContextcontext, Message message) . Here you can implement your own criteries of authorization.
To put the authorization policy in good use you need to install and configure it into your ActiveMQ setup. Basicly it is done via these steps:
- Compile your class into a JAR file
- Put the JAR in ApacheMQ's lib folder
- Add a proper messageAuthorizationPolicy element to your configuration
- Restart ActiveMQ
Chris Dale's answer is pretty much spot on, except for a small detail: if you just use the
<simpleAuthenticactionPlugin> as suggested, and try to use the web console and then try to browse a queue (go to queue page -> click on browse), it will cause an error because of the "system" user:
Stopping vm://localhost#0 because Failed with SecurityException: User name [system] or password is invalid.
As mentioned on Phillip's Blog, in order to make it function correctly will have to also add a "system" user, and edit the tag "activemq.password" inside "credentials.properties".
<users /> you would have to add a "system" user:
<authenticationUser username="system" password="password" groups="admins,publishers,consumers"/>
And then, "credentials.properties" will need to be modified in order to match the chosen password:
I'm posting this here because the answer was surprisingly hard to find.