By default, ActiveMQ automatically creates a destination inside the broker any time a client either consumes from or produces to a destination. Although this functionality is useful for many implementations, when you have a large number of brokers and clients it can lead to accidents. If a destination is misspelled, or, worse, a client connects to the wrong broker instance, ActiveMQ will happily create the destination even though it’s undesired.
In systems that use publish/subscribe topics, this can lead to message loss. If a topic-producing client connects to a broker with no consumers, i.e. the wrong broker, and starts publishing messages, all of those messages will be discarded, per Java Message Service (JMS) topic behavior. If an extremely productive producer starts blasting the wrong message broker with messages, it can become overwhelmed and lead to downtime.
In a traffic-partitioned broker network, you may have hundreds or even thousands of broker nodes. Keeping a strict destination inventory for clients becomes increasingly important as the complexity of your broker and client network increases. So that makes us ask – is ActiveMQ’s dynamic queue creation feature working for you? Or is the feature is more trouble than it’s worth.
Disabling the feature
Unfortunately, ActiveMQ doesn’t provide a simple switch to make this possible.
Instead, you must make use of ActiveMQ’s JAAS-based authorization feature, and disallow clients the ability to create destinations. Authorization in ActiveMQ is based on roles and allowed operations. A role can be mapped to one of three actions, “read,” “write,” or “admin.” It is the “admin” operation that allows a client to create or remove a destination from the broker instance.
For implementations which already authenticate clients using JAAS, an administrator just has to restrict the “admin” operation to a role which isn’t used by the client. If you’re not authenticating your clients, which means they are authenticating as the “anonymous” role, so you just need to restrict the “admin” operation to a role other than “anonymous” to restrict their ability to create destinations.
You can do both of these by setting an AuthorizationPolicy against all queues and topics, and, if you are authenticating your clients, by assigning the client’s group to a role that does not allow the “admin” operation on the specified destinations.
The destination policy will look something like:
<plugins> <jaasAuthenticationPlugin configuration="activemq-domain" /> <authorizationPlugin> <map> <authorizationMap> <authorizationEntries> <authorizationEntry queue=">" admin="admins" /> <authorizationEntry topic=">" admin="admins" /> </authorizationEnries> </authorizationMap> </map> </authorizationPlugin> ... </plugins>
This configuration will tell the broker that only users with the “admins” role, as specified in conf/groups.properties, are allowed to create or destroy destinations within the broker. As long as the authenticating (or anonymous) client does not belong to the “admins” role, the clients will not be able to automatically create destinations in the broker, and will receive an exception if they attempt to Produce or Consume from a destination which doesn’t exist.
Note: This restriction applies only to clients that are authenticating into the broker, and not the Web Console or CLI, which manage their authentication through a different mechanism than the JAAS configuration. So even with this restriction in place, users will still be able to create and destroy destinations using the admin tools.
Create startup destinations
Once that change has been made, you’ll also want to configure the broker to create the desired destinations during broker startup, since the clients will no longer be able to create them on-demand. This will allow strict control over exactly which destinations exist inside the broker.
To do this, you’ll want to configure “startup destinations.” This can be done via the broker’s activemq.xml configuration file. The element supports a sub-entity called which you can use to create these:
<broker…> … <destinations> <queue physicalName=”MyStartupQueue”/> <topic physicalName=”MyStartupTopic”/> </destinations> … </broker>
This configuration would create two destinations in the broker on broker startup, a queue called “MyStartupQueue,” and a topic called “MyStartupTopic.” When the broker starts, it will automatically create these destinations if they do not already exist. As mentioned, you can also create destinations from within the Web Console and/or the CLI.
By combining the JAAS authentication context above, and creating startup destinations, you can have guaranteed strict controls over what destinations exist within the broker, and prevent clients from creating arbitrary ones. Though not as straightforward of a solution as it could be, it does effectively solve the problem, should your business decide to turn off ActiveMQ’s dynamic queue creation feature.
– Register now to attend our webinar “OSS has taken over the enterprise: The top five OSS trends of 2015“
– Let us help you solve open source issues with enterprise-class support