Chapter 7. Configuring Security
7.1. Securing Remote Connections
7.1.1. Using the Legacy Security Subsystem
You can use the legacy security
subsystem in JBoss EAP to secure the messaging-activemq
subsystem. The legacy security
subsystem uses legacy security realms and domains. See the JBoss EAP Security Architecture guide for more information on security realms and security domains. The messaging-activemq
subsystem is pre-configured to use the security realm named ApplicationRealm
and the security domain named other
.
The legacy security
subsystem approach is the default configuration from JBoss EAP 7.0.
The ApplicationRealm
is defined near the top of the configuration file.
<management> <security-realms> ... <security-realm name="ApplicationRealm"> <authentication> <local default-user="$local" allowed-users="*" skip-group-loading="true"/> <properties path="application-users.properties" relative-to="jboss.server.config.dir" /> </authentication> <authorization> <properties path="application-roles.properties" relative-to="jboss.server.config.dir" /> </authorization> </security-realm> </security-realms> ... </management>
As its name implies, ApplicationRealm
is the default security realm for all application-focused subsystems in JBoss EAP such as the messaging-activemq
, undertow
, and ejb3
subsystems. ApplicationRealm
uses the local filesystem to store usernames and hashed passwords. For convenience JBoss EAP includes a script that you can use to add users to the ApplicationRealm
. See Default User Configuration in the JBoss EAP How To Configure Server Security guide for details.
The other
security domain is the default security domain for the application-related subsystems like messaging-activemq
. It is not explicitly declared in the configuration; however, you can confirm which security domain is used by the messaging-activemq
subsystem with the following management CLI command:
/subsystem=messaging-activemq/server=default:read-attribute(name=security-domain) { "outcome" => "success", "result" => "other" }
You can also update which security domain is used:
/subsystem=messaging-activemq/server=default:write-attribute(name=security-domain, value=mySecurityDomain)
The JBoss EAP How To Configure Server Security guide has more information on how to create new security realms and domains. For now, it is worth noting how the other
domain appears in the configuration:
<subsystem xmlns="urn:jboss:domain:security:1.2"> <security-domains> <security-domain name="other" cache-type="default"> <authentication> <login-module code="Remoting" flag="optional"> <module-option name="password-stacking" value="useFirstPass"/> </login-module> <login-module code="RealmDirect" flag="required"> <module-option name="password-stacking" value="useFirstPass"/> </login-module> </authentication> </security-domain> ... <security-domains> </subsystem>
The 'other' domain uses two login-modules as its means of authentication. The first module, Remoting
, authenticates remote EJB invocations, while the RealmDirect
module uses the information store defined in a given realm to authenticate users. In this case the default realm ApplicationRealm
is used, since no realm is declared. Each module has its password-stacking
option set to useFirstPass
, which tells the login-module to store the principal name and password of the authenticated user. See the JBoss EAP Login Module Reference for more details on the login modules and their options.
Role-based access is configured at the address level, see Role Based Security for Addresses.
7.1.2. Using the Elytron Subsystem
You can also use the elytron
subsystem to secure the messaging-activemq
subsystem. You can find more information on using the elytron
subsystem and creating and Elytron security domains in the Elytron Subsystem section of How to Configure Identity Management guide.
To use an Elytron security domain:
Undefine the legacy security domain.
/subsystem=messaging-activemq/server=default:undefine-attribute(name=security-domain)
Set an Elytron security domain.
/subsystem=messaging-activemq/server=default:write-attribute(name=elytron-domain, value=myElytronSecurityDomain) reload
7.1.2.1. Setting an Elytron Security Domain Using the Management Console
To set an Elytron security domain using the Management Console:
- Access the management console. For more information, see Management Console in the JBoss EAP Configuration Guide.
-
Navigate to Configuration
Subsystems Messaging-ActiveMQ Messaging Provider default and select Provider Settings from the drop-down. - Navigate to the Security tab and click Edit.
- You can add or edit the value of Elytron domain here. Remember to remove any existing value from the Security domain field.
- Click Save to save the changes. A dialog appears confirming that the server configuration changed and tells you the server needs to be reloaded.
Reload the server.
- For a standalone server, click the Reload Server Now button to reload the server.
- In a managed domain, click the Go to Runtime button. From the Runtime tab, select the appropriate server and click the Reload drop down option to reload the server.
You can only define either security-domain
or elytron-domain
, but you cannot have both defined at the same time. If neither is defined, JBoss EAP will use the security-domain
default value of other
, which maps to the other
legacy security domain.
7.1.3. Securing the Transport
The default http-connector
that comes bundled with JBoss EAP messaging is not secured by default. You can secure the message transport and enable web traffic for SSL/TLS by following the instructions to configure one-way and two-way SSL/TLS for applications in How to Configure Server Security for JBoss EAP.
The above approach to secure a message transport also works for securing the http-acceptor
.
When you configure the transport as described above, you must perform the following additional steps.
-
By default, all HTTP acceptors are configured to use the default
http-listener
, which listens on the HTTP port. You must configure HTTP acceptors to use thehttps-listener
, which listens on the HTTPS port. -
The
socket-binding
element for all HTTP connectors must be updated to usehttps
instead ofhttp
. -
Each
http-connector
that communicates through SSL/TLS must set thessl-enabled
parameter totrue
. -
If an HTTP connector is used to connect to another server, you must configure the related parameters such as
trust-store
andkey-store
. Securing thehttp-connector
requires that you configure the same parameters as you do with aremote-connector
, which is documented in Securing a Remote Connector.
See Configuring the Messaging Transports for information about the configuring acceptors and connectors for messaging transports.
7.1.4. Securing a Remote Connector
If you are not using the default http-connector
and have instead created your own remote-connector
and remote-acceptor
for TCP communications, you can configure each for SSL/TLS by using the properties in the table below. The properties appear in the configuration as part of the child <param>
elements of the acceptor or connector.
Typically, a server owns its private SSL/TLS key and shares its public key with clients. In this scenario, the server defines the key-store-path
and key-store-password
parameters in a remote-acceptor
. Since each client can have its truststore located at a different location, and be encrypted by a different password, specifying the trust-store-path
and trust-store-password
properties on the remote-connector
is not recommended. Instead, configure these parameters on the client side using the system properties javax.net.ssl.trustStore
and javax.net.ssl.trustStorePassword
. The only parameter which you need to configure for a remote-connector
is ssl-enabled=true
. However, if the server uses remote-connector
to connect to another server, it makes sense in this case to set the trust-store-path
and trust-store-password
parameters of the remote-connector
.
In the above use case, the remote-acceptor
would be created using the following management CLI command:
/subsystem=messaging-activemq/server=default/remote-acceptor=mySslAcceptor:add(socket-binding=netty,params={ssl-enabled=true, key-store-path=PATH/TO/server.jks, key-store-password=${VAULT::server-key::key-store-password::sharedKey}})
To create the remote-connector
from the above use case, use the following management CLI command:
/subsystem=messaging-activemq/server=default/remote-connector=mySslConnector:add(socket-binding=netty,params={ssl-enabled=true})
The management CLI also allows you to add a parameter to an already existing remote-acceptor
or remote-connector
as well:
/subsystem=messaging-activemq/server=default/remote-connector=myOtherSslConnector:map-put(name=params,key=ssl-enabled,value=true)
Note that the remote-acceptor
and remote-connector
both reference a socket-binding
to declare the port to be used for communication. See the Overview of the Messaging Subsystem Configuration for more information on socket bindings and their relationship to acceptors and connectors.
Property | Description |
---|---|
enabled-cipher-suites | Can be used to configure an acceptor or connector. This is a comma separated list of cipher suites used for SSL/TLS communication. The default value is null which means the JVM’s default will be used. |
enabled-protocols | Can be used to configure an acceptor or connector. This is a comma separated list of protocols used for SSL/TLS communication. The default value is null which means the JVM’s default will be used. |
key-store-password |
When used on an acceptor, this is the password for the server-side keystore. |
key-store-path |
When used on an acceptor, this is the path to the SSL/TLS keystore on the server which holds the server’s certificates. Use for certificates either self-signed or signed by an authority. |
key-store-provider | Defines the format of the file in which keys are stored, PKCS11 or PKCS12 for example. The accepted values are JDK specific. |
needs-client-auth |
This property is only for an acceptor. It tells a client connecting to this acceptor that two-way SSL/TLS is required. Valid values are |
ssl-enabled |
Must be |
trust-store-password |
When used on an acceptor, this is the password for the server-side truststore. This is only relevant for an acceptor if you are using two-way SSL/TLS. |
trust-store-path |
When used on an acceptor, this is the path to the server-side SSL/TLS keystore that holds the keys of all the clients that the server trusts. This is only relevant for an acceptor if you are using two-way SSL/TLS. |
trust-store-provider | Defines the format of the file in which keys are stored, PKCS11 or PKCS12 for example. The accepted values are JDK specific. |
7.2. Securing Destinations
In addition to securing remote connections into the messaging server, you can also configure security around specific destinations. This is done by adding a security constraint using the security-setting
configuration element. JBoss EAP messaging comes with a security-setting
configured by default, as shown in the output from the following management CLI command:
/subsystem=messaging-activemq/server=default:read-resource(recursive=true) { "outcome" => "success", "result" => { .... "security-setting" => {"#" => {"role" => {"guest" => { "consume" => true, "create-durable-queue" => false, "create-non-durable-queue" => true, "delete-durable-queue" => false, "delete-non-durable-queue" => true, "manage" => false, "send" => true }}}} } }
The security-setting
option makes use of wildcards in the name
field to handle which destinations to apply the security constraint. The value of a single #
will match any address. For more information on using wildcards in security constraints, see Role Based Security for Addresses.
7.2.1. Role-Based Security for Addresses
JBoss EAP messaging contains a flexible role-based security model for applying security to queues, based on their addresses.
The core JBoss EAP messaging server consists mainly of sets of queues bound to addresses. When a message is sent to an address, the server first looks up the set of queues that are bound to that address and then routes the message to the bound queues.
JBoss EAP messaging has a set of permissions that can be applied against queues based on their address. An exact string match on the address can be used or a wildcard match can be used using the wildcard characters #
and *
. See Address Settings for more information on how to use the wildcard syntax.
You can create multiple roles for each security-setting
, and there are 7 permission settings that can be applied to a role. Below is the complete list of the permissions available:
-
create-durable-queue
allows the role to create a durable queue under matching addresses. -
delete-durable-queue
allows the role to delete a durable queue under matching addresses. -
create-non-durable-queue
allows the role to create a non-durable queue under matching addresses. -
delete-non-durable-queue
allows the role to delete a non-durable queue under matching addresses. -
send
allows the role to send a message to matching addresses. -
consume
allows the role to consume a message from a queue bound to matching addresses. -
manage
allows the role to invoke management operations by sending management messages to the management address.
Configuring Role-Based Security
To start using role-based security for a security-setting
, you first must create one. As an example, a security-setting
of news.europe.#
is created below. It would apply to any destination starting with news.europe.
, such as news.europe.fr
or news.europe.tech.uk
.
/subsystem=messaging-activemq/server=default/security-setting=news.europe.#:add() {"outcome" => "success"}
Next, you add a role to the security-setting
you created and declare permissions for it. In the example below, the dev
role is created and given permissions to consume from, and send to, queues, as well as to create and delete non-durable queues. Because the default is false
, you have to tell JBoss EAP only about the permissions you want to switch on.
/subsystem=messaging-activemq/server=default/security-setting=news.europe.#/role=dev:add(consume=true,delete-non-durable-queue=true,create-non-durable-queue=true,send=true) {"outcome" => "success"}
To further illustrate the use of permissions, the example below creates an admin
role and allows it to send management messages by switching on the manage
permission. The permissions for creating and deleting durable queues are switched on as well:
/subsystem=messaging-activemq/server=default/security-setting=news.europe.#/role=admin:add(manage=true,create-durable-queue=true,delete-durable-queue=true) {"outcome" => "success"}
To confirm the configuration of a security-setting
, use the management CLI. Remember to use the recursive=true
option to get the full display of permissions:
/subsystem=messaging-activemq/server=default:read-children-resources(child-type=security-setting,recursive=true) { "outcome" => "success", "result" => { "#" => {"role" => {"guest" => { "consume" => true, "create-durable-queue" => false, "create-non-durable-queue" => true, "delete-durable-queue" => false, "delete-non-durable-queue" => true, "manage" => false, "send" => true }}}, "news.europe.#" => {"role" => { "dev" => { "consume" => true, "create-durable-queue" => false, "create-non-durable-queue" => true, "delete-durable-queue" => false, "delete-non-durable-queue" => true, "manage" => false, "send" => true }, "admin" => { "consume" => false, "create-durable-queue" => true, "create-non-durable-queue" => false, "delete-durable-queue" => true, "delete-non-durable-queue" => false, "manage" => true, "send" => false } }} }
Above, the permissions for addresses that start with string news.europe.
are displayed in full by the management CLI. To summarize, only users who have the admin
role can create or delete durable queues, while only users with the dev
role can create or delete non-durable queues. Furthermore, users with the dev
role can send or consume messages, but admin
users cannot. They can, however, send management messages since their manage
permission is set to true
.
In cases where more than one match applies to a set of addresses the more specific match takes precedence. For example, the address news.europe.tech.uk.#
is more specific than news.europe.tech.#
. Because permissions are not inherited, you can effectively deny permissions in more specific security-setting
blocks by simply not specifying them. Otherwise it would not be possible to deny permissions in sub-groups of addresses.
The mapping between a user and what roles they have is handled by the security manager. JBoss EAP ships with a user manager that reads user credentials from a file on disk, and can also plug into JAAS or JBoss EAP security.
For more information on configuring the security manager, see the JBoss EAP Security Architecture guide.
7.2.1.1. Granting Unauthenticated Clients the guest Role Using the Legacy Security Subsystem
If you want JBoss EAP to automatically grant unauthenticated clients the guest
role make the following two changes:
Add a new
module-option
to theother
security domain. The new option,unauthenticatedIdentity
, will tell JBoss EAP to grantguest
access to unauthenticated clients. The recommended way to do this is by using the management CLI:/subsystem=security/security-domain=other/authentication=classic/login-module=RealmDirect:map-put(name=module-options,key=unauthenticatedIdentity,value=guest) { "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } }
Note that the server requires a reload after issuing the command. You can confirm the new option by using the following management CLI command:
/subsystem=security/security-domain=other/authentication=classic/login-module=RealmDirect:read-resource() { "outcome" => "success", "result" => { "code" => "RealmDirect", "flag" => "required", "module" => undefined, "module-options" => { "password-stacking" => "useFirstPass", "unauthenticatedIdentity" => "guest" } } }
Also, your server configuration file should look something like this after the command executes:
<subsystem xmlns="urn:jboss:domain:security:1.2"> <security-domains> <security-domain name="other" cache-type="default"> <authentication> ... <login-module code="RealmDirect" flag="required"> ... <module-option name="unauthenticatedIdentity" value="guest"/> ... </login-module> ... </authentication> </security-domain> ... </security-domains> </subsystem>
Uncomment the following line in the file
application-roles.properties
by deleting the#
character. The file is located inEAP_HOME/standalone/configuration/
orEAP_HOME/domain/configuration/
, depending on whether you are using standalone servers or a domain controller respectively.#guest=guest
Remote clients should now be able to access the server without needing to authenticate. They will be given the permissions associated with the guest
role.
7.3. Controlling JMS ObjectMessage Deserialization
Because an ObjectMessage
can contain potentially dangerous objects, ActiveMQ Artemis provides a simple class filtering mechanism to control which packages and classes are to be trusted and which are not. You can add objects whose classes are from trusted packages to a white list to indicate they can be deserialized without a problem. You can add objects whose classes are from untrusted packages to a black list to prevent them from being deserialized.
ActiveMQ Artemis filters objects for deserialization as follows.
- If both the white list and the black list are empty, which is the default, any serializable object is allowed to be deserialized.
- If an object’s class or package matches one of the entries in the black list, it is not allowed to be deserialized.
- If an object’s class or package matches an entry in the white list, is is allowed to be deserialized.
- If an object’s class or package matches an entry in both the black list and the white list, the one in black list takes precedence, meaning it is not allowed to be deserialized.
- If an object’s class or package matches neither the black list nor the white list, the object deserialization is denied, unless the white list is empty, meaning there is no white list specified.
An object is considered a match if its full name exactly matches one of the entries in the list, if its package matches one of the entries in the list, or if it is a subpackage of one of the entries in the list.
You can specify which objects can be deserialized on a connection-factory
and on a pooled-connection-factory
using the deserialization-white-list
and deserialization-black-list
attributes. The deserialization-white-list
attribute is used to define the list of classes or packages that are allowed to be deserialized. The deserialization-black-list
attribute is used to define the list of classes or packages that are not allowed to be deserialized.
The following commands create a black list for the RemoteConnectionFactory
connection factory and a white list for the activemq-ra
pooled connection factory for the default server.
/subsystem=messaging-activemq/server=default/connection-factory=RemoteConnectionFactory:write-attribute(name=deserialization-black-list,value=[my.untrusted.package,another.untrusted.package]) /subsystem=messaging-activemq/server=default/pooled-connection-factory=activemq-ra:write-attribute(name=deserialization-white-list,value=[my.trusted.package])
These commands generate the following configuration in the messaging-activemq
subsystem.
<connection-factory name="RemoteConnectionFactory" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector" ha="true" block-on-acknowledge="true" reconnect-attempts="-1" deserialization-black-list="my.untrusted.package another.untrusted.package"/> <pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" deserialization-white-list="my.trusted.package" transaction="xa"/>
For information about connection factories and pooled connection factories, see Configuring Connection Factories in this guide.
You can also specify which objects can be deserialized in an MDB by configuring the activation properties. The deserializationWhiteList
property is used to define the list of classes or packages that are allowed to be deserialized. The deserializationBlackList
property is used to define the list of classes or packages that are not allowed to be deserialized. For more information about activation properties, see Configuring MDBs Using a Deployment Descriptor in Developing EJB Applications for JBoss EAP.