Chapter 6. Security

This chapter covers the various security options available to administrators, and how they are configured. Administrators can use the information provided in this chapter to tailor the functions of the AMQ Broker security subsystems to their needs.

6.1. Accessing the AMQ Console

Starting with AMQ Broker 7.1.0, you can access the AMQ Console only from the local host by default. You must modify the configuration in BROKER_INSTANCE_DIR/etc/jolokia-access.xml to enable remote access. For more information, see Securing AMQ Console and AMQ Broker Connections.

6.2. Securing Network Connections

There are two basic use cases for transport layer security (TLS):

  • Server-side (or one-way); where only the server presents a certificate. This is the most common use case.
  • Client-side (or two-way); where both the server and the client present certificates. This is sometimes called mutual authentication.

6.2.1. Configuring Server-Side Certificates

One-way TLS is configured in the URL of the relevant acceptor in broker.xml. Here is a very basic acceptor configuration which does not use TLS:

<acceptor name="artemis">tcp://0.0.0.0:61616</acceptor>

Here is that same acceptor configured to use one-way TLS:

<acceptor name="artemis">tcp://0.0.0.0:61616?sslEnabled=true;keyStorePath=../etc/broker.keystore;keyStorePassword=1234!</acceptor>

This acceptor uses three additional parameters - sslEnabled, keyStorePath, and keyStorePassword. These, at least, are required to enable one-way TLS.

6.2.2. Configuring Client-Side Certificates

Two-way TLS uses the same sslEnabled, keyStorePath, and keyStorePassword properties as one-way TLS, but it adds needClientAuth to tell the client it should present a certificate of its own. For example:

<acceptor name="artemis">tcp://0.0.0.0:61616?sslEnabled=true;keyStorePath=../etc/broker.keystore;keyStorePassword=1234!;needClientAuth=true</acceptor>

This configuration assumes that the client’s certificate is signed by a trusted provider. If the client’s certificate is not signed by a trusted provider (it is self-signed, for example) then the server needs to import the client’s certificate into a trust-store and configure the acceptor with trustStorePath and trustStorePassword. For example:

<acceptor name="artemis">tcp://0.0.0.0:61616?sslEnabled=true;keyStorePath=../etc/broker.keystore;keyStorePassword=1234!;needClientAuth=true;trustStorePath=../etc/client.truststore;trustStorePassword=5678!</acceptor>
Note

Client-side Considerations

AMQ Broker supports multiple protocols, and each protocol and platform has different ways to specify TLS parameters. However, in the case of a client using the Core protocol (a bridge) the TLS parameters are configured on the connector URL much like on the broker’s acceptor.

TLS Configuration Details

Below are configuration details to be aware of:

OptionNote

sslEnabled

Must be true to enable TLS. Default is false.

keyStorePath

When used on an acceptor: This is the path to the TLS key store on the server which holds the server’s certificates (whether self-signed or signed by an authority).

When used on a connector: This is the path to the client-side TLS key store which holds the client certificates. This is only relevant for a connector if you are using two-way TLS (that is, mutual authentication). Although this value is configured on the server, it is downloaded and used by the client. If the client needs to use a different path from that set on the server then it can override the server-side setting by either using the customary javax.net.ssl.keyStore system property or the AMQ-specific org.apache.activemq.ssl.keyStore system property. The AMQ-specific system property is useful if another component on client is already making use of the standard, Java system property.

keyStorePassword

When used on an acceptor: This is the password for the server-side KeyStore.

When used on a connector: This is the password for the client-side KeyStore. This is only relevant for a connector if you are using two-way TLS (that is, mutual authentication). Although this value can be configured on the server, it is downloaded and used by the client. If the client needs to use a different password from that set on the server then it can override the server-side setting by either using the customary javax.net.ssl.keyStorePassword system property or the AMQ-specific org.apache.activemq.ssl.keyStorePassword system property. The AMQ-specific system property is useful if another component on client is already making use of the standard, Java system property.

trustStorePath

When used on an acceptor: This is the path to the server-side TLS key store 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 TLS (mutual authentication).

When used on a connector: This is the path to the client-side TLS key store which holds the public keys of all the servers that the client trusts. Although this value can be configured on the server, it is downloaded and used by the client. If the client needs to use a different path from that set on the server then it can override the server-side setting by either using the customary javax.net.ssl.trustStore system property or the AMQ-specific org.apache.activemq.ssl.trustStore system property. The AMQ-specific system property is useful if another component on client is already making use of the standard, Java system property.

trustStorePassword

When used on an acceptor: This is the password for the server-side trust store. This is only relevant for an acceptor if you are using two-way TLS (that is, mutual authentication).

When used on a connector: This is the password for the client-side TrustStore. Although this value can be configured on the server, it is downloaded and used by the client. If the client needs to use a different password from that set on the server then it can override the server-side setting by either using the customary javax.net.ssl.trustStorePassword system property or the AMQ-specific org.apache.activemq.ssl.trustStorePassword system property. The AMQ-specific system property is useful if another component on client is already making use of the standard, Java system property.

enabledCipherSuites

Whether used on an acceptor or connector this is a comma-separated list of cipher suites used for TLS communication. The default value is null which means the JVM’s default is used.

enabledProtocols

Whether used on an acceptor or connector this is a comma-separated list of protocols used for TLS communication. The default value is null which means the JVM’s default is used.

needClientAuth

This property is only for an acceptor. It indicates to a client connecting to this acceptor that two-way TLS is required. Valid values are true or false. Default is false.

6.2.3. Adding Certificate-based Authentication

The JAAS certificate authentication login module requires TLS to be in use and clients must be configured with their own certificates. In this scenario, authentication is actually performed during the TLS handshake, not directly by the JAAS certificate authentication plug-in.

The role of the plug-in is as follows:

  • To further constrain the set of acceptable users, because only the user Distinguished Names (DNs) explicitly listed in the relevant properties file are eligible to be authenticated.
  • To associate a list of groups with the received user identity, facilitating integration with authorization.
  • To require the presence of an incoming certificate (by default, the TLS layer is configured to treat the presence of a client certificate as optional).

The JAAS certificate login module stores a collection of certificate DNs in a pair of flat files. The files associate a username and a list of group IDs with each Distinguished Name.

The certificate login module is implemented by the org.apache.activemq.artemis.spi.core.security.jaas.TextFileCertificateLoginModule class.

Prerequisites

  • Certificate login configured in login.config file.
  • A valid artemis-users.properties file.
  • A valid artemis-roles.properties file.
  • The Subject DNs from the user certificate(s)

Procedure

  1. Obtain the Subject DNs from user certificates

    1. Export the certificate from the KeyStore file into a temporary file. Substitute your required values into the following command:

      keytool -export -file __FILENAME__ -alias broker-localhost -keystore broker.ks -storepass __PASSWORD__
    2. Print the contents of the exported certificate:

      keytool -printcert -file __FILENAME__

      The output is similar to that shown below:

      Owner: CN=localhost, OU=broker, O=Unknown, L=Unknown, ST=Unknown, C=Unknown 1
      Issuer: CN=localhost, OU=broker, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
      Serial number: 4537c82e
      Valid from: Thu Oct 19 19:47:10 BST 2006 until: Wed Jan 17 18:47:10 GMT 2007
      Certificate fingerprints:
               MD5:  3F:6C:0C:89:A8:80:29:CC:F5:2D:DA:5C:D7:3F:AB:37
               SHA1: F0:79:0D:04:38:5A:46:CE:86:E1:8A:20:1F:7B:AB:3A:46:E4:34:5C
      1
      The subject DN. The format used to enter the subject DN depends on your platform. The string above could also be represented as;
      Owner: `CN=localhost,\ OU=broker,\ O=Unknown,\ L=Unknown,\ ST=Unknown,\ C=Unknown`
  2. Configuring certificate-based authentication

    1. Open the login.config file and reference the user and roles properties files.
    2. Open the files declared in the previous step and supply the required information:

      Users and their corresponding DNs should be listed in the artemis-users.properties file. The available roles and the users who hold those roles are defined in the artemis-roles.properties file.

      Examples of the syntax of these files is shown below.

    3. Ensure your security domain alias (in this instance, activemq) is referenced in bootstrap.xml as shown below:

      <jaas-security domain="activemq"/>

Example Configuration

The following example shows how to configure certificate login module in the login.config file:

Example 6.1. login.config

activemq {
    org.apache.activemq.artemis.spi.core.security.jaas.TextFileCertificateLoginModule 1
        debug=true 2
        org.apache.activemq.jaas.textfiledn.user="artemis-users.properties" 3
        org.apache.activemq.jaas.textfiledn.role="artemis-roles.properties"; 4
};
1
Configure the JAAS realm. This example uses a single org.apache.activemq.artemis.spi.core.security.jaas.TextFileCertificateLoginModule
2
Toggle debugging on (true) or off (false). Default is false.
3
Define the file used to store user data (relative to the directory containing the login.config file).
4
Define the file used to store role data (relative to the directory containing the login.config file).

The artemis-users.properties file consists of a list of properties with the user=StringifiedSubjectDN (where the string encoding is specified by RFC 2253):

Example 6.2. artemis-users.properties

system=CN=system,O=Progress,C=US 1
user=CN=humble user,O=Progress,C=US
guest=CN=anon,O=Progress,C=DE
1
The user named system is mapped to the CN=system,O=Progress,C=US subject DN.

The artemis-roles.properties file follows the pattern of role=user where user can be either a single user or a comma-separated list of users:

Example 6.3. artemis-roles.properties

admins=system
users=system,user 1
guests=guest
1
Multiple users can be included as a comma-separated entry.

6.2.4. Adding Certificate-based Authentication for AMQP Clients

Use the SASL EXTERNAL mechanism configuration parameter to configure your AQMP client for certificate-based authentication when connecting to a broker.

The broker authenticates the TSL/SSL certificate of your AMQP client in the same way that it authenticates any certificate:

  • The broker reads the TLS/SSL certificate of the client to obtain an identity from the certificate’s subject.
  • The certificate subject is mapped to a broker identity by the certificate login module. The broker then authorizes the mapped user based on their roles.
Prerequisites

Before you can configure your AMQP clients to use certificate-based authentication, you must complete the following tasks:

Procedure

To enable your AMQP client to use certificate-based authentication, add configuration parameters to the URI that the client uses to connect to a broker.

  1. Open the resource containing the URI for editing:

    amqps://localhost:5500
  2. Add the parameter sslEnabled=true to enable TSL/SSL for the connection:

    amqps://localhost:5500?sslEnabled=true
  3. Add parameters related to the TrustStore and KeyStore of the client to enable the exchange of TSL/SSL certificates with the broker:

    amqps://localhost:5500?sslEnabled=true&trustStorePath=TRUST_STORE_PATH&trustStorePassword=TRUST_STORE_PASSWORD&keyStorePath=KEY_STORE_PATH&keyStorePassword=KEY_STORE_PASSWORD
  4. Add the parameter saslMechanisms=EXTERNAL to request that the broker authenticate the client by using the identity found in its TSL/SSL certificate:

    amqps://localhost:5500?sslEnabled=true&trustStorePath=TRUST_STORE_PATH&trustStorePassword=TRUST_STORE_PASSWORD&keyStorePath=KEY_STORE_PATH&keyStorePassword=KEY_STORE_PASSWORD&saslMechanisms=EXTERNAL
Additional Resources

6.2.5. Using Multiple Login Modules

It is possible to combine login modules to accommodate more complex use cases. The most common reason to combine login modules is to support authentication for both anonymous users and users who submit credentials.

Prerequisites

The prerequisites for different authentication combinations differ based on the methods being implemented. Prerequisites for the most common multiple login scenario are:

  • A valid artemis-users.properties file
  • A valid artemis-roles.properties file
  • A login.config file configured for anonymous access

Procedure

  1. Edit the login.config file to add entries for the desired authentication modules.
  2. Set the parameters in each module entry as required for your environment.
  3. Ensure your security domain alias (in this instance, activemq) is referenced in bootstrap.xml as shown below:

    Example 6.4. bootstrap.xml

    <jaas-security domain="activemq"/>

Example Configuration

The following examples illustrate the cascading nature of multiple login configurations:

Example 6.5. login.config

activemq {
  org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule sufficient 1
      debug=true
      org.apache.activemq.jaas.properties.user="artemis-users.properties"
      org.apache.activemq.jaas.properties.role="artemis-roles.properties";

  org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient 2
      debug=true
      org.apache.activemq.jaas.guest.user="guest"
      org.apache.activemq.jaas.guest.role="restricted";
};
1
Password authentications module is activated if the user supplies credentials
2
Guest authentication module is activated if the user supplies no credentials or the credentials supplied are incorrect.

The following example shows how to configure a JAAS login entry for the use case where only those users with no credentials are logged in as guests. Note that the order of the login modules is reversed and the flag attached to the properties login module is changed to requisite.

Example 6.6. login.config

activemq {
    org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient 1
        debug=true
       credentialsInvalidate=true 2
       org.apache.activemq.jaas.guest.user="guest"
       org.apache.activemq.jaas.guest.role="guests";

    org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule requisite 3
        debug=true
        org.apache.activemq.jaas.properties.user="artemis-users.properties"
        org.apache.activemq.jaas.properties.role="artemis-roles.properties";
};
1
The guest authentication module is activated if no login credentials are supplied.
2
The credentialsInvalidate option must be set to true in the configuration of the guest login module.
3
The password login module is activated if credentials are supplied and the credentials must be valid.

6.2.6. Configure Multiple Security Settings for Address Groups and Sub-groups

Below is an example security block from a broker.xml file. The various configuration options based on this example are explained in this section.

<security-setting match="globalqueues.europe.#"> 1
   <permission type="createDurableQueue" roles="admin"/> 2
   <permission type="deleteDurableQueue" roles="admin"/> 3
   <permission type="createNonDurableQueue" roles="admin, guest, europe-users"/> 4
   <permission type="deleteNonDurableQueue" roles="admin, guest, europe-users"/> 5
   <permission type="send" roles="admin, europe-users"/> 6
   <permission type="consume" roles="admin, europe-users"/> 7
</security-setting>
1
The ‘#’ character signifies "any sequence of words". Words are delimited by the ‘.’ character. For a full description of the wildcard syntax, see AMQ Broker Wildcard Syntax. The above security block applies to any address that starts with the string globalqueues.europe.
2 3
Only users who have the admin role can create or delete durable queues bound to an address that starts with the string globalqueues.europe.
4 5
Any users with the roles admin, guest, or europe-users can create or delete temporary queues bound to an address that starts with the string globalqueues.europe.
6 7
Any users with the roles admin or europe-users can send messages to these addresses or consume messages from queues bound to an address that starts with the string globalqueues.europe.

The mapping between a user and what roles they have is handled by the security manager. AMQ Broker ships with a user manager that reads user credentials from a file on disk, and can also plug into JAAS or JBoss Application Server security.

There can be multiple security-setting elements in each XML file, or none, depending on requirements. When the broker.xml file contains multiple security-setting elements that can apply to a set of addresses, the most specific match takes precedence.

Let us look at an example of that, here’s another security-setting block:

<security-setting match="globalqueues.europe.orders.#">
   <permission type="send" roles="europe-users"/>
   <permission type="consume" roles="europe-users"/>
</security-setting>

In this security-setting block the match globalqueues.europe.orders.# is more specific than the previous match 'globalqueues.europe.\#'. So any addresses which match 'globalqueues.europe.orders.\#' will take their security settings only from the latter security-setting block.

Note that settings are not inherited from the former block. All the settings will be taken from the more specific matching block, so for the address globalqueues.europe.orders.plastics the only permissions that exist are send and consume for the role europe-users. The permissions createDurableQueue, deleteDurableQueue, createNonDurableQueue, deleteNonDurableQueue are not inherited from the other security-setting block.

By not inheriting permissions, 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.

6.2.7. Setting Resource Limits

Sometimes it is helpful to set particular limits on what certain users can do beyond the normal security settings related to authorization and authentication. For example, one can limit how many connections a user can create or how many queues a user can create.

6.2.7.1. Configuring Connection and Queue Limits

Here is an example of the XML used to set resource limits:

<resource-limit-settings>
   <resource-limit-setting match="myUser">
      <max-connections>5</max-connections>
      <max-queues>3</max-queues>
   </resource-limit-setting>
</resource-limit-settings>

Unlike the match from address-setting, this match does not use any wildcard syntax. It is a simple 1:1 mapping of the limits to a user.

  • max-connections. Defines how many connections the matched user can make to the broker. The default is -1, which means there is no limit.
  • max-queues. Defines how many queues the matched user can create. The default is -1, which means there is no limit.

6.3. Integrating with LDAP

6.3.1. Using LDAP for Authentication

The LDAP login module enables authentication and authorization by checking the incoming credentials against user data stored in a central X.500 directory server. It is implemented by org.apache.activemq.artemis.spi.core.security.jaas.LDAPLoginModule.

Procedure

  1. Open the BROKER_INSTANCE_DIR/etc/broker.xml file and add the following lines:

    <security-settings>
        <security-setting match="#">
            <permission type="createDurableQueue" roles="user"/>
            <permission type="deleteDurableQueue" roles="user"/>
            <permission type="createNonDurableQueue" roles="user"/>
            <permission type="deleteNonDurableQueue" roles="user"/>
            <permission type="send" roles="user"/>
            <permission type="consume" roles="user"/>
        </security-setting>
    </security-settings>
  2. Open the BROKER_INSTANCE_DIR/etc/login.config file.
  3. Locate and edit the appropriate alias block with the appropriate parameters (see the examples included below).
  4. Start or restart the broker (service or process).
Note

Apache DS uses the OID portion of DN path; however, Microsoft AD does not, and instead uses the CN portion.
For example; The DN path oid=testuser,dc=example,dc=com would be used in Apache DS, while cn=testuser,dc=example,dc=com would be used in Microsoft AD.

Example 6.7. Example Apache DS login.config configuration

activemq {
  org.apache.activemq.artemis.spi.core.security.jaas.LDAPLoginModule required
     debug=true 1
     initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory 2
     connectionURL="ldap://localhost:10389" 3
     connectionUsername="uid=admin,ou=system" 4
     connectionPassword=secret 5
     connectionProtocol=s 6
     authentication=simple 7
     userBase="dc=example,dc=com" 8
     userSearchMatching="(uid={0})" 9
     userSearchSubtree=true 10
     userRoleName= 11
     roleBase="dc=example,dc=com" 12
     roleName=cn 13
     roleSearchMatching="(member={0})" 14
     roleSearchSubtree=true 15
     ;
};

Example 6.8. Example Microsoft Active Directory login.config Configuration

activemq {
  org.apache.activemq.artemis.spi.core.security.jaas.LDAPLoginModule required
     debug=true
     initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
     connectionURL="LDAP://localhost:389"
     connectionUsername="CN=Administrator,CN=Users,DC=example,DC=com"
     connectionPassword=redhat.123
     connectionProtocol=s
     authentication=simple
     userBase="dc=example,dc=com"
     userSearchMatching="(CN={0})"
     userSearchSubtree=true
     roleBase="dc=example,dc=com"
     roleName=cn
     roleSearchMatching="(member={0})"
     roleSearchSubtree=true
     ;
};
1
Toggle debugging on (true) or off (false). Default is false.
2
The initialContextFactory parameter must always be set to com.sun.jndi.ldap.LdapCtxFactory
3
Specify the location of the directory server using an ldap URL, ldap://Host:Port. One can optionally qualify this URL, by adding a forward slash, /, followed by the DN of a particular node in the directory tree. The default port of Apache DS is 10389 while for Microsoft AD the default is 389.
4
The DN of the user that opens the connection to the directory server. For example, uid=admin,ou=system. Directory servers generally require clients to present username/password credentials in order to open a connection.
5
The password that matches the DN from connectionUsername. In the directory server, in the DIT, the password is normally stored as a userPassword attribute in the corresponding directory entry.
6
Any value is supported but is effectively unused. This option must be set explicitly because it has no default value.
7
Specify the authentication method used when binding to the LDAP server. This parameter can be set to either simple (which requires a username and password) or none (which allows anonymous access).
8
Select a particular subtree of the DIT to search for user entries. The subtree is specified by a DN, which specifies the base node of the subtree. For example, by setting this option to ou=User,ou=ActiveMQ,ou=system, the search for user entries is restricted to the subtree beneath the ou=User,ou=ActiveMQ,ou=system node.
9
Specify an LDAP search filter, which is applied to the subtree selected by userBase. See the Search Matching section below for more information.
10
Specify the search depth for user entries, relative to the node specified by userBase. This option is a boolean. A setting of false indicates it tries to match one of the child entries of the userBase node (maps to javax.naming.directory.SearchControls.ONELEVEL_SCOPE), while true indicates it tries to match any entry belonging to the subtree of the userBase node (maps to javax.naming.directory.SearchControls.SUBTREE_SCOPE).
11
Specify the name of the multi-valued attribute of the user entry that contains a list of role names for the user (where the role names are interpreted as group names by the broker’s authorization plug-in). If this option is omitted, no role names are extracted from the user entry.
12
If role data is stored directly in the directory server, one can use a combination of role options (roleBase, roleSearchMatching, roleSearchSubtree, and roleName) as an alternative to (or in addition to) specifying the userRoleName option. This option selects a particular subtree of the DIT to search for role/group entries. The subtree is specified by a DN, which specifies the base node of the subtree. For example, by setting this option to ou=Group,ou=ActiveMQ,ou=system, the search for role/group entries is restricted to the subtree beneath the ou=Group,ou=ActiveMQ,ou=system node.
13
Specify the attribute type of the role entry that contains the name of the role/group (such as C, O, OU, etc.). If this option is omitted the role search feature is effectively disabled.
14
Specify an LDAP search filter, which is applied to the subtree selected by roleBase. See the Search Matching section below for more information.
15
Specify the search depth for role entries, relative to the node specified by roleBase. If set to false (which is the default) the search tries to match one of the child entries of the roleBase node (maps to javax.naming.directory.SearchControls.ONELEVEL_SCOPE). If true it tries to match any entry belonging to the subtree of the roleBase node (maps to javax.naming.directory.SearchControls.SUBTREE_SCOPE).

Search Matching

userSearchMatching

Before passing to the LDAP search operation, the string value provided in this configuration parameter is subjected to string substitution, as implemented by the java.text.MessageFormat class.

This means that the special string, {0}, is substituted by the username, as extracted from the incoming client credentials. After substitution, the string is interpreted as an LDAP search filter (the syntax is defined by the IETF standard RFC 2254).

For example, if this option is set to (uid={0}) and the received username is jdoe, the search filter becomes (uid=jdoe) after string substitution.

If the resulting search filter is applied to the subtree selected by the user base, ou=User,ou=ActiveMQ,ou=system, it would match the entry, uid=jdoe,ou=User,ou=ActiveMQ,ou=system.

A short introduction to the search filter syntax is available from Oracle’s JNDI tutorial

roleSearchMatching

This works in a similar manner to the userSearchMatching option, except that it supports two substitution strings.

The substitution string {0} substitutes the full DN of the matched user entry (that is, the result of the user search). For example, for the user, jdoe, the substituted string could be uid=jdoe,ou=User,ou=ActiveMQ,ou=system.

The substitution string {1} substitutes the received username. For example, jdoe.

If this option is set to (member=uid={1}) and the received username is jdoe, the search filter becomes (member=uid=jdoe) after string substitution (assuming ApacheDS search filter syntax).

If the resulting search filter is applied to the subtree selected by the role base, ou=Group,ou=ActiveMQ,ou=system, it matches all role entries that have a member attribute equal to uid=jdoe (the value of a member attribute is a DN).

This option must always be set, even if role searching is disabled, because it has no default value. If OpenLDAP is used, the syntax of the search filter is (member:=uid=jdoe).

6.3.2. Configure LDAP Authorization

The LegacyLDAPSecuritySettingPlugin security-setting-plugin will read the security information that was previously handled by LDAPAuthorizationMap and the cachedLDAPAuthorizationMap in Apache A-MQ 6 and turn it into corresponding security settings where possible.

The security implementations of the two brokers do not match perfectly so some translation must occur to achieve near equivalent functionality.

Here is an example of the plugin’s configuration:

<security-setting-plugin class-name="org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin"> 1
 <setting name="initialContextFactory" value="com.sun.jndi.ldap.LdapCtxFactory"/> 2
 <setting name="connectionURL" value="ldap://localhost:1024"/> 3
 <setting name="connectionUsername" value="uid=admin,ou=system"/> 4
 <setting name="connectionPassword" value="secret"/> 5
 <setting name="connectionProtocol" value="s"/> 6
 <setting name="authentication" value="simple"/> 7
</security-setting-plugin>
1
class-name. The implementation is org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin.
2
initialContextFactory. The initial context factory used to connect to LDAP. It must always be set to com.sun.jndi.ldap.LdapCtxFactory (that is, the default value).
3
connectionURL. Specifies the location of the directory server using an LDAP URL, ldap://Host:Port. You can optionally qualify this URL, by adding a forward slash, /, followed by the DN of a particular node in the directory tree. For example, ldap://ldapserver:10389/ou=system. The default is ldap://localhost:1024.
4
connectionUsername. The DN of the user that opens the connection to the directory server. For example, uid=admin,ou=system. Directory servers generally require clients to present username/password credentials in order to open a connection.
5
connectionPassword. The password that matches the DN from connectionUsername. In the directory server, in the DIT, the password is normally stored as a userPassword attribute in the corresponding directory entry.
6
connectionProtocol - any value is supported but is effectively unused. In the future, this option may allow one to select the Secure Socket Layer (SSL) for the connection to the directory server. This option must be set explicitly because it has no default value.
7
authentication. Specifies the authentication method used when binding to the LDAP server. Can take either of the values, simple (username and password, the default value) or none (anonymous). Note: Simple Authentication and Security Layer (SASL) authentication is currently not supported.

Other possible settings not shown in the example above are:

destinationBase
Specifies the DN of the node whose children provide the permissions for all destinations. In this case the DN is a literal value (that is, no string substitution is performed on the property value). For example, a typical value of this property is ou=destinations,o=ActiveMQ,ou=system (that is, the default value).
filter
Specifies an LDAP search filter, which is used when looking up the permissions for any kind of destination. The search filter attempts to match one of the children or descendants of the queue or topic node. The default value is (cn=*).
roleAttribute
Specifies an attribute of the node matched by filter whose value is the DN of a role. Default value is uniqueMember.
adminPermissionValue
Specifies a value that matches the admin permission. The default value is admin.
readPermissionValue
Specifies a value that matches the read permission. The default value is read.
writePermissionValue
Specifies a value that matches the write permission. The default value is write.
enableListener
Whether or not to enable a listener that will automatically receive updates made in the LDAP server and update the broker’s authorization configuration in real-time. The default value is true.

The name of the queue or topic defined in LDAP will serve as the "match" for the security-setting, the permission value will be mapped from the A-MQ 6 type to the AMQ 7 type, and the role will be mapped as-is. Since the name of the queue or topic coming from LDAP will server as the "match" for the security-setting the security-setting may not be applied as expected to JMS destinations since AMQ 7 always prefixes JMS destinations with "jms.queue." or "jms.topic." as necessary.

A-MQ 6 only has three permission types - read, write, and admin. These permission types are described on the ActiveMQ website; http://activemq.apache.org/security.html.

However, as described previously, AMQ 7 has 10 permission types:

  • createAddress
  • deleteAddress
  • createDurableQueue
  • deleteDurableQueue
  • createNonDurableQueue
  • deleteNonDurableQueue
  • send
  • consume
  • manage
  • browse

The list below shows how the old types are mapped to the new types:

  • read - consume, browse
  • write - send
  • admin - createDurableQueue, deleteDurableQueue, createNonDurableQueue, deleteNonDurableQueue, createAddress, deleteAddress

As mentioned, there are a few places where a translation was performed to achieve some equivalence:

  • This mapping does not include the AMQ 7 manage permission type since there is no type analogous for that in A-MQ 6.
  • The admin permission in A-MQ 6 relates to whether or not the broker will auto-create a destination if it does not exist and the user sends a message to it. AMQ 7 automatically allows the automatic creation of a destination if the user has permission to send message to it. Therefore, the plugin will map the admin permission to the four aforementioned permissions in AMQ 7.

6.3.3. Encrypting the Password in the login.config File

Because organizations frequently securely store data with LDAP, the login.config file can contain the configuration required for the broker to communicate with the organization’s LDAP server. This configuration file usually includes a password to log in to the LDAP server, so this password needs to be masked.

Prerequisites

Procedure

The following procedure explains how to mask the value of the connectionPassword found in the BROKER_INSTANCE_DIR/etc/login.config file.

  1. From a command prompt, use the mask utility to encrypt the password:

    $ BROKER_INSTANCE_DIR/bin/artemis mask PASSWORD

    The encrypted password is displayed on the screen:

    result: 3a34fd21b82bf2a822fa49a8d8fa115d
  2. Open the BROKER_INSTANCE_DIR/etc/login.config file and locate the connectionPassword:

    connectionPassword = PASSWORD
  3. Replace the plain text password with the encrypted value that you created in Step 1:

    connectionPassword = 3a34fd21b82bf2a822fa49a8d8fa115d
  4. Wrap the encrypted value with the identifier "ENC()":

    connectionPassword = "ENC(3a34fd21b82bf2a822fa49a8d8fa115d)"

The login.config file now contains a masked password. Because the password is wrapped with the "ENC()" identifier, AMQ Broker decrypts it before it is used.

Additional Resources

For more information about the configuration files included with AMQ Broker, see AMQ Broker configuration files and locations.

6.4. Integrating with Kerberos

When sending and receiving messages with the AMQP protocol, clients can send Kerberos security credentials that AMQ Broker authenticates by using the GSSAPI mechanism from the Simple Authentication and Security Layer (SASL) framework. Kerberos credentials can also be used for authorization by mapping an authenticated user to an assigned role configured in an LDAP directory or text-based properties file.

You can use SASL in tandem with Transport Layer Sockets (TLS) to secure your messaging applications. SASL provides user authentication, and TLS provides data integrity.

You must deploy and configure a Kerberos infrastructure before AMQ Broker can authenticate and authorize Kerberos credentials. See your operating system documentation for more information about deploying Kerberos. If your operating system is RHEL 7, for example, see the chapter Using Kerberos. A Kerberos Authentication Overview is available for Windows as well.

Note

You must deploy and configure a Kerberos infrastructure before AMQ Broker can authenticate and authorize Kerberos credentials.

Note

Users of an Oracle or IBM JDK should install the Java Cryptography Extension (JCE). See the documentation from the Oracle version of the JCE or the IBM version of the JCE for more information.

6.4.1. Enabling Network Connections to Use Kerberos

AMQ Broker integrates with Kerberos security credentials by using the GSSAPI mechanism from the Simple Authentication and Security Layer (SASL) framework. To use Kerberos in AMQ Broker, each acceptor authenticating or authorizing clients that use a Kerberos credential must be configured to used the GSSAPI mechanism.

Prerequisites

You must deploy and configure a Kerberos infrastructure before AMQ Broker can authenticate and authorize Kerberos credentials.

Procedure
  1. Stop the broker.

    1. If the broker is running on Linux:

      BROKER_INSTANCE_DIR/bin/artemis stop
    2. If the broker is running on Windows as a service:

      BROKER_INSTANCE_DIR\bin\artemis-service.exe stop
  2. Open the broker.xml configuration file located under BROKER_INSTANCE_DIR/etc
  3. Add the name-value pair saslMechanisms=GSSAPI to the query string of the URL for the acceptor, as shown in the following example:

    <acceptor name="amqp">
      tcp://0.0.0.0:5672?protocols=AMQP;saslMechanisms=GSSAPI
    </acceptor>

    The result is an acceptor that uses the GSSAPI mechanism when authenticating Kerberos credentials.

  4. (Optional) The PLAIN and ANONYMOUS SASL mechanisms are also supported. If you want to use these other mechanisms in addition to GSSAPI, add them to the list of saslMechanisms. Be sure to separate each value with a comma. In the following example, the name-value pair saslMechanisms=GSSAPI is modified to add the value PLAIN.

    <acceptor name="amqp">
      tcp://0.0.0.0:5672?protocols=AMQP;saslMechanisms=GSSAPI,PLAIN
    </acceptor>

    The result is an acceptor that uses both the GSSAPI and PLAIN SASL mechanisms.

  5. Start the broker.

    1. If the broker is running on Linux:

      BROKER_INSTANCE_DIR/bin/artemis run
    2. If the broker is running on Windows as a service:

      BROKER_INSTANCE_DIR\bin\artemis-service.exe start

See About Acceptors for more information about acceptors.

6.4.2. Authenticating Clients with Kerberos Credentials

AMQ Broker supports Kerberos authentication of AMQP connections that use the GSSAPI mechanism from the Simple Authentication and Security Layer (SASL) framework.

A broker acquires its Kerberos acceptor credentials by using the Java Authentication and Authorization Service (JAAS). The JAAS library included with your Java installation is packaged with a login module, Krb5LoginModule, that authenticates Kerberos credentials. See the documentation from your Java vendor for more information about their Krb5LoginModule. For example, Oracle provides information about their Krb5LoginModule login module as part of their Java 8 documentation.

Prerequisites

You must enable the GSSAPI mechanism of an acceptor before it can authenticate AMQP connections using Kerberos security credentials.

Procedure
  1. Stop the broker.

    1. If the broker is running on Linux:

      BROKER_INSTANCE_DIR/bin/artemis stop
    2. If the broker is running on Windows as a service:

      BROKER_INSTANCE_DIR\bin\artemis-service.exe stop
  2. Open the login.config configuration file located under BROKER_INSTANCE_DIR/etc.
  3. Add a configuration scope named amqp-sasl-gssapi to login.config. The following example shows configuration for the Krb5LoginModule found in Oracle and OpenJDK versions of the JDK.

    Note

    Verify the fully qualified class name of the Krb5LoginModule and its available options by referring to the documentation from your Java vendor.

    amqp-sasl-gssapi { 1
        com.sun.security.auth.module.Krb5LoginModule required 2
        isInitiator=false
        storeKey=true
        useKeyTab=true  3
        principal="amqp/my_broker_host@example.com" 4
        debug=true;
    };
    1
    By default, the GSSAPI mechanism implementation on the broker uses a JAAS configuration scope named amqp-sasl-gssapi to obtain its Kerberos acceptor credentials.
    2
    This version of the Krb5LoginModule is provided by the Oracle and OpenJDK versions of the JDK. Verify the fully qualified class name of the Krb5LoginModule and its available options by referring to the documentation from your Java vendor.
    3
    The Krb5LoginModule is configured to use a Kerberos keytab when authenticating a principal. Keytabs are generated using tooling from your Kerberos environment. See the documentation from your vendor for details about generating Kerberos keytabs.
    4
    The Principal is set to amqp/my_broker_host@example.com. This value must correspond to the service principal created in your Kerberos environment. See the documentation from your vendor for details about creating service principals.
  4. Start the broker.

    1. If the broker is running on Linux:

      BROKER_INSTANCE_DIR/bin/artemis run
    2. If the broker is running on Windows as a service:

      BROKER_INSTANCE_DIR\bin\artemis-service.exe start

See Network Connections and Kerberos, for more information about enabling the GSSAPI mechanism in AMQ Broker.

6.4.2.1. Using an Alternative Configuration Scope

You can specify an alternative configuration scope by adding the parameter saslLoginConfigScope to the URL of an AMQP acceptor. In the following configuration example, the parameter saslLoginConfigScope is given the value alternative-sasl-gssapi. The result is an acceptor that uses the alternative scope named alternative-sasl-gssapi, which was declared in the BROKER_INSTANCE_DIR/etc/login.config configuration file.

<acceptor name="amqp">
tcp://0.0.0.0:5672?protocols=AMQP;saslMechanisms=GSSAPI,PLAIN;saslLoginConfigScope=alternative-sasl-gssapi`
</acceptor>

6.4.3. Authorizing Clients with Kerberos Credentials

AMQ Broker is packaged with an implementation of the JAAS Krb5LoginModule for use by other security modules when mapping roles. The module adds a Kerberos-authenticated Peer Principal to the Subject’s principal set as an AMQ Broker UserPrincipal. The credentials can then be passed to a PropertiesLoginModule or LDAPLoginModule, which maps the Kerberos-authenticated Peer Principal to an AMQ Broker role.

Note

The Kerberos Peer Principal does not exist as a broker user, only as a role member.

Prerequisites

You must enable the GSSAPI mechanism of an acceptor before it can authorize AMQP connections using Kerberos security credentials.

Procedure
  1. Stop the broker.

    1. If the broker is running on Linux:

      BROKER_INSTANCE_DIR/bin/artemis stop
    2. If the broker is running on Windows as a service:

      BROKER_INSTANCE_DIR\bin\artemis-service.exe stop
  2. Open the login.config configuration file located under BROKER_INSTANCE_DIR/etc.
  3. Add configuration for the AMQ Broker Krb5LoginModule and the LDAPLoginModule.

    Note

    Verify the configuration options by referring to the documentation from your LDAP provider.

    org.apache.activemq.artemis.spi.core.security.jaas.Krb5LoginModule required
        ; 1
    org.apache.activemq.artemis.spi.core.security.jaas.LDAPLoginModule optional
        initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
        connectionURL="ldap://localhost:1024"
        authentication=GSSAPI
        saslLoginConfigScope=broker-sasl-gssapi
        connectionProtocol=s
        userBase="ou=users,dc=example,dc=com"
        userSearchMatching="(krb5PrincipalName={0})"
        userSearchSubtree=true
        authenticateUser=false
        roleBase="ou=system"
        roleName=cn
        roleSearchMatching="(member={0})"
        roleSearchSubtree=false
        ;
    1
    This version of the Krb5LoginModule is distributed with AMQ Broker and transforms the Kerberos identity into a broker identity that can be used by other AMQ modules for role mapping.
  4. Start the broker.

    1. If the broker is running on Linux:

      BROKER_INSTANCE_DIR/bin/artemis run
    2. If the broker is running on Windows as a service:

      BROKER_INSTANCE_DIR\bin\artemis-service.exe start

See Network Connections and Kerberos for more information about enabling the GSSAPI mechanism in AMQ Broker.

See Users and Roles for more information about the PropertiesLoginModule.

See Integrating with LDAP for more information about the LDAPLoginModule.

6.5. Encrypting Passwords in Configuration Files

By default, AMQ Broker stores all passwords in configuration files as plain text. Be sure to secure all configuration files with the correct permissions to prevent unauthorized access. You can also encrypt, or mask, the plain text passwords to prevent unwanted viewers from reading them.

A masked password is the encrypted version of a plain text password. The encrypted version is generated by the mask command-line utility provided by AMQ Broker. For more information about the mask utility, see the command-line help documentation:

$ BROKER_INSTANCE_DIR/bin/artemis help mask

To mask a password, replace its plain text value with the encrypted one. The masked password must be wrapped by the identifier ENC() so that it is decrypted when the actual value is needed.

In the following example, the configuration file BROKER_INSTANCE_DIR/etc/bootstrap.xml contains masked passwords for the attributes keyStorePassword and trustStorePassword.

Example with bootstrap.xml

<web bind="https://localhost:8443" path="web"
     keyStorePassword="ENC(-342e71445830a32f95220e791dd51e82)"
     trustStorePassword="ENC(32f94e9a68c45d89d962ee7dc68cb9d1)">
    <app url="activemq-branding" war="activemq-branding.war"/>
</web>

You can use masked passwords only with the following configuration files.

Supported Configuration Files

  • broker.xml
  • bootstrap.xml
  • management.xml
  • artemis-users.properties
  • login.config (for use with the LDAPLoginModule)

Configuration files are found at BROKER_INSTANCE_DIR/etc.

Note

artemis-users.properties supports only masked passwords that have been hashed. When a user is created upon broker creation, artemis-users.properties contains hashed passwords by default. The default PropertiesLoginModule will not decode the passwords in artemis-users.properties file but will instead hash the input and compare the two hashed values for password verification. Changing the hashed password to a masked password does not allow access to the AMQ Console.

broker.xml, bootstrap.xml, management.xml, and login.config support passwords that are masked but not hashed.

Procedure

As an example, the following procedure explains how to mask the value of the cluster-password configuration element found in the file BROKER_INSTANCE_DIR/etc/broker.xml.

  1. From a command prompt, use the mask utility to encrypt a password:

    $ BROKER_INSTANCE_DIR/bin/artemis mask PASSWORD

    The encrypted password is displayed on the screen:

    result: 3a34fd21b82bf2a822fa49a8d8fa115d
  2. Open the configuration file containing the plain text password you want to mask:

    <cluster-password>
      PASSWORD
    </cluster-password>
  3. Replace the plain text password with the encrypted value that you created in Step 1:

    <cluster-password>
      3a34fd21b82bf2a822fa49a8d8fa115d
    </cluster-password>
  4. Wrap the encrypted value with the identifier ENC():

    <cluster-password>
      ENC(3a34fd21b82bf2a822fa49a8d8fa115d)
    </cluster-password>

The configuration file now contains a masked password. Because the password is wrapped with the ENC() identifier, AMQ Broker decrypts it before it is used.

Additional Resources

For more information about the configuration files included with AMQ Broker, see AMQ Broker configuration files and locations.

6.6. Tracking Messages from Validated Users

To enable tracking and logging the origins of messages (for example, for security-auditing purposes), you can use the _AMQ_VALIDATED_USER message key.

In the broker.xml configuration file, if the populate-validated-user option is set to true, then the broker adds the name of the validated user to the message using the _AMQ_VALIDATED_USER key. For JMS and STOMP clients, this message key maps to the JMSXUserID key.

Note

The broker cannot add the validated user name to a message produced by an AMQP JMS client. Modifying the properties of an AMQP message after it has been sent by a client is a violation of the AMQP protocol.

For a user authenticated based on his/her SSL certificate, the validated user name populated by the broker is the name to which the certificate’s Distinguished Name (DN) maps.

In the broker.xml configuration file, if security-enabled is false and populate-validated-user is true, then the broker populates whatever user name, if any, that the client provides. The populate-validated-user option is false by default.

You can configure the broker to reject a message that doesn’t have a user name (that is, the JMSXUserID key) already populated by the client when it sends the message. You might find this option useful for AMQP clients, because the broker cannot populate the validated user name itself for messages sent by these clients.

To configure the broker to reject messages without JMSXUserID set by the client, add the following configuration to the broker.xml configuration file:

<reject-empty-validated-user>true</reject-empty-validated-user>

By default, reject-empty-validated-user is set to false.

6.7. Disabling Security

Security is enabled by default. Broker security can be enabled or disabled by setting the <security-enabled> parameter in the <core> element of the broker.xml configuration file.

Procedure

  1. Open the broker.xml file.
  2. Locate the <security-enabled> parameter.
  3. Edit the entry as needed:

    • Set the parameter to false to disable security:

      <security-enabled>false</security-enabled>
  4. If necessary, change the security-invalidation-interval entry (which periodically invalidates secure logins) to a different value (in ms). The default is 10000.