Chapter 5. Securing brokers


5.1. Securing connections

When brokers are connected to messaging clients, or brokers are connected to other brokers, you can secure these connections using Transport Layer Security (TLS).

There are two TLS configurations that you can use:

  • One-way TLS, where only the broker presents a certificate. This is the most common configuration.
  • Two-way (or mutual) TLS, where both the broker and the client (or other broker) present certificates.

The procedures in this section show how to configure both one-way and two-way TLS.

5.1.1. Configuring one-way TLS

The following procedure shows how to configure a given acceptor for one-way TLS.

  1. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  2. For a given acceptor, add the sslEnabled key and set the value to true. In addition, add the keyStorePath and keyStorePassword keys. Set values that correspond to your broker key store. For example:

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

5.1.2. Configuring two-way TLS

The following procedure shows how to configure two-way TLS.

Prerequisites

Procedure

  1. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  2. For the acceptor that you previously configured for one-way TLS, add the needClientAuth key. Set the value to true. For example:

    <acceptor name="artemis">tcp://0.0.0.0:61616?sslEnabled=true;keyStorePath=../etc/broker.keystore;keyStorePassword=1234!;needClientAuth=true</acceptor>
  3. The configuration in the preceding step 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 broker needs to import the client’s certificate into a trust store. In this case, add the trustStorePath and trustStorePassword keys. Set values that correspond to your broker trust store. 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

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 Core Protocol (a bridge), the TLS parameters are configured on the connector URL, much like on the broker’s acceptor.

5.1.3. TLS configuration options

The following table shows all of the available TLS configuration options.

OptionNote

sslEnabled

Specifies whether SSL is enabled for the connection. Must be set to true to enable TLS. The default value is false.

keyStorePath

When used on an acceptor: Path to the TLS keystore on the broker that holds the broker certificates (whether self-signed or signed by an authority).

When used on a connector: Path to the TLS keystore on the client that holds the client certificates. This is relevant for a connector only if you are using two-way TLS. Although you can configure this value on the broker, it is downloaded and used by the client. If the client needs to use a different path from that set on the broker, it can override the broker setting by using either the standard 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 the client is already making use of the standard Java system property.

keyStorePassword

When used on an acceptor: Password for the keystore on the broker.

When used on a connector: Password for the keystore on the client. This is relevant for a connector only if you are using two-way TLS. Although you can configure this value on the broker, it is downloaded and used by the client. If the client needs to use a different password from that set on the broker, then it can override the broker setting by using either the standard 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 the client is already making use of the standard Java system property.

trustStorePath

When used on an acceptor: Path to the TLS truststore on the broker that holds the keys of all clients that the broker trusts. This is relevant for an acceptor only if you are using two-way TLS.

When used on a connector: Path to TLS truststore on the client that holds the public keys of all brokers that the client trusts. Although you can configure this value on the broker, 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 using either using the standard 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 the client is already making use of the standard Java system property.

trustStorePassword

When used on an acceptor: Password for the truststore on the broker. This is relevant for an acceptor only if you are using two-way TLS.

When used on a connector: Password for the truststore on the client. Although you can configure this value on the broker, it is downloaded and used by the client. If the client needs to use a different password from that set on the broker, then it can override the broker setting by using either the standard 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 the 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 instructs a client connecting to the acceptor that two-way TLS is required. Valid values are true or false. The default value is false.

5.2. Authenticating clients

5.2.1. Client authentication methods

To configure client authentication on the broker, you can use the following methods:

User name- and password-based authentication

Directly validate user credentials using one of these options:

  • Check the credentials against a set of properties files stored locally on the broker. You can also configure a guest account that allows limited access to the broker and combine login modules to support more complex use cases.
  • Configure a Lightweight Directory Access Protocol (LDAP) login module to check client credentials against user data stored in a central X.500 directory server.
Certificate-based authentication
Configure two-way Transport Layer Security (TLS) to require both the broker and client to present certificates for mutual authentication. An administrator must also configure properties files that define approved client users and roles. These properties files are stored on the broker.
Kerberos-based authentication
Configure the broker to authenticate Kerberos security credentials for the client using the GSSAPI mechanism from the Simple Authentication and Security Layer (SASL) framework.

The sections that follow describe how to configure both user-and-password- and certificate-based authentication.

Additional resources

5.2.2. Configuring user and password authentication based on properties files

AMQ Broker supports a flexible role-based security model for applying security to queues based on their addresses. Queues are bound to addresses either one-to-one (for point-to-point messaging) or many-to-one (for publish-subscribe messaging). When a message is sent to an address, the broker looks up the set of queues that are bound to that address and routes the message to that set of queues.

When you require basic user and password authentication, use PropertiesLoginModule to define it. This login module checks user credentials against the following configuration files that are stored locally on the broker:

artemis-users.properties
Used to define users and corresponding passwords
artemis-roles.properties
Used to define roles and assign users to those roles
login.config
Used to configure login modules for user and password authentication and guest access

The artemis-users.properties file can contain hashed passwords, for security.

The following sections show how to configure:

5.2.2.1. Configuring basic user and password authentication

The following procedure shows how to configure basic user and password authentication.

Procedure

  1. Open the <broker_instance_dir>/etc/login.config configuration file. By default, this file in a new AMQ Broker 7.9 instance include the following lines:

    activemq {
       org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule sufficient
           debug=false
           reload=true
           org.apache.activemq.jaas.properties.user="artemis-users.properties"
           org.apache.activemq.jaas.properties.role="artemis-roles.properties";
             };
    activemq
    Alias for the configuration.
    org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule
    The implementation class.
    sufficient

    Flag that specifies what level of success is required for the PropertiesLoginModule. The values that you can set are:

    • required: The login module is required to succeed. Authentication continues to proceed down the list of login modules configured under the given alias, regardless of success or failure.
    • requisite: The login module is required to succeed. A failure immediately returns control to the application. Authentication does not proceed down the list of login modules configured under the given alias.
    • sufficient: The login module is not required to succeed. If it is successful, control returns to the application and authentication does not proceed further. If it fails, the authentication attempt proceeds down the list of login modules configured under the given alias.
    • optional: The login module is not required to succeed. Authentication continues down the list of login modules configured under the given alias, regardless of success or failure.
    org.apache.activemq.jaas.properties.user
    Specifies the properties file that defines a set of users and passwords for the login module implementation.
    org.apache.activemq.jaas.properties.role
    Specifies the properties file that maps users to defined roles for the login module implementation.
  2. Open the <broker_instance_dir>/etc/artemis-users.properties configuration file.
  3. Add users and assign passwords to the users. For example:

    user1=secret
    user2=access
    user3=myPassword
  4. Open the <broker_instance_dir>/etc/artemis-roles.properties configuration file.
  5. Assign role names to the users you previously added to the artemis-users.properties file. For example:

    admin=user1,user2
    developer=user3
  6. Open the <broker_instance_dir>/etc/bootstrap.xml configuration file.
  7. If necessary, add your security domain alias (in this instance, activemq) to the file, as shown below:

    <jaas-security domain="activemq"/>

5.2.2.2. Configuring guest access

For a user who does not have login credentials, or whose credentials fail authentication, you can grant limited access to the broker using a guest account.

You can create a broker instance with guest access enabled using the command-line switch; --allow-anonymous (the converse of which is --require-login).

The following procedure shows how to configure guest access.

Prerequisites

Procedure

  1. Open the <broker_instance_dir>/etc/login.config configuration file that you previously configured for basic user and password authentication.
  2. After the properties login module configuration that you previously added, add a guest login module configuration. For example:

    activemq {
      org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule sufficient
          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
          debug=true
          org.apache.activemq.jaas.guest.user="guest"
          org.apache.activemq.jaas.guest.role="restricted";
    };
    org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule
    The implementation class.
    org.apache.activemq.jaas.guest.user
    The user name assigned to anonymous users.
    org.apache.activemq.jaas.guest.role
    The role assigned to anonymous users.

Based on the preceding configuration, user and password authentication module is activated if the user supplies credentials. Guest authentication is activated if the user supplies no credentials, or if the credentials supplied are incorrect.

5.2.2.2.1. Guest access example

The following example shows configuration of guest access for the use case where only those users with no credentials are logged in as guests. In this example, observe that the order of the login modules is reversed compared with the previous configuration procedure. Also, the flag attached to the properties login module is changed to requisite.

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

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

Based on the preceding configuration, the guest authentication module is activated if no login credentials are supplied.

For this use case, the credentialsInvalidate option must be set to true in the configuration of the guest login module.

The properties login module is activated if credentials are supplied. The credentials must be valid.

Additional resources

5.2.3. Configuring certificate-based authentication

The Java Authentication and Authorization Service (JAAS) certificate login module handles authentication and authorization for clients that are using Transport Layer Security (TLS). The module requires two-way Transport Layer Security (TLS) to be in use and clients to be configured with their own certificates. Authentication is performed during the TLS handshake, not directly by the JAAS certificate login module.

The role of the certificate login module is to:

  • Constrain the set of acceptable users. Only the user Distinguished Names (DNs) explicitly listed in the relevant properties file are eligible to be authenticated.
  • Associate a list of groups with the received user identity. This facilitates authorization.
  • Require the presence of an incoming client certificate (by default, the TLS layer is configured to treat the presence of a client certificate as optional).

The certificate login module stores a collection of certificate DNs in a pair of flat text files. The files associate a user name and a list of group IDs with each DN.

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

5.2.3.1. Configuring the broker to use certificate-based authentication

The following procedure shows how to configure the broker to use certificate-based authentication.

Prerequisites

Procedure

  1. Obtain the Subject Distinguished Names (DNs) from user certificates previously imported to the broker key store.

    1. Export the certificate from the key store file into a temporary file. For example:

      keytool -export -file <file_name> -alias broker-localhost -keystore broker.ks -storepass <password>
    2. Print the contents of the exported certificate:

      keytool -printcert -file <file_name>

      The output is similar to that shown below:

      Owner: CN=localhost, OU=broker, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
      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

      The Owner entry is 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. Configure certificate-based authentication.

    1. Open the <broker_instance_dir>/etc/login.config configuration file. Add the certificate login module and reference the user and roles properties files. For example:

      activemq {
          org.apache.activemq.artemis.spi.core.security.jaas.TextFileCertificateLoginModule
              debug=true
              org.apache.activemq.jaas.textfiledn.user="artemis-users.properties"
              org.apache.activemq.jaas.textfiledn.role="artemis-roles.properties";
      };
      org.apache.activemq.artemis.spi.core.security.jaas.TextFileCertificateLoginModule
      The implementation class.
      org.apache.activemq.jaas.textfiledn.user
      Specifies the properties file that defines a set of users and passwords for the login module implementation.
      org.apache.activemq.jaas.textfiledn.role
      Specifies the properties file that maps users to defined roles for the login module implementation.
    2. Open the <broker_instance_dir>/etc/artemis-users.properties configuration file. Users and their corresponding DNs are defined in this file. For example:

      system=CN=system,O=Progress,C=US
      user=CN=humble user,O=Progress,C=US
      guest=CN=anon,O=Progress,C=DE

      Based on the preceding configuration, for example, the user named system is mapped to the CN=system,O=Progress,C=US Subject DN.

    3. Open the <broker_instance_dir>/etc/artemis-roles.properties configuration file. The available roles and the users who hold those roles are defined in this file. For example:

      admins=system
      users=system,user
      guests=guest

      In the preceding configuration, for the users role, you list multiple users as a comma-separated list.

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

      <jaas-security domain="activemq"/>

5.2.3.2. Configuring certificate-based authentication for AMQP clients

Use the Simple Authentication and Security Layer (SASL) EXTERNAL mechanism configuration parameter to configure your AQMP client for certificate-based authentication when connecting to a broker.

The broker authenticates the Transport Layer Security (TLS)/Secure Sockets Layer (SSL) certificate of your AMQP client in the same way that it authenticates any certificate:

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

The following procedure shows how to configure certificate-based authentication for AMQP clients. To enable your AMQP client to use certificate-based authentication, you must add configuration parameters to the URI that the client uses to connect to the broker.

Prerequisites

Procedure

  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 client trust store and key store 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

5.3. Authorizing clients

5.3.1. Client authorization methods

To authorize clients to perform operations on the broker such as creating and deleting addresses and queues, and sending and consuming messages, you can use the following methods:

User- and role-based authorization
Configure broker security settings for authenticated users and roles.
Configure LDAP to authorize clients
Configure the Lightweight Directory Access Protocol (LDAP) login module to handle both authentication and authorization. The LDAP login module checks incoming credentials against user data stored in a central X.500 directory server and sets permissions based on user roles.
Configure Kerberos to authorize clients
Configure the Java Authentication and Authorization Service (JAAS) Krb5LoginModule login module to pass credentials to PropertiesLoginModule or LDAPLoginModule login modules, which map the Kerberos-authenticated users to AMQ Broker roles.

5.3.2. Configuring user- and role-based authorization

5.3.2.1. Setting permissions

Permissions are defined against queues (based on their addresses) via the <security-setting> element in the broker.xml configuration file. You can define multiple instances of <security-setting> in the <security-settings> element of the configuration file. You can specify an exact address match or you can define a wildcard match using the number sign (#) and asterisk (*) wildcard characters.

Different permissions can be given to the set of queues that match an address. Those permissions are shown in the following table.

To allow users to…​Use this parameter…​

Create addresses

createAddress

Delete addresses

deleteAddress

Create a durable queue under matching addresses

createDurableQueue

Delete a durable queue under matching addresses

deleteDurableQueue

Create a non-durable queue under matching addresses

createNonDurableQueue

Delete a non-durable queue under matching addresses

deleteNonDurableQueue

Send a message to matching addresses

send

Consume a message from a queue bound to matching addresses

consume

Invoke management operations by sending management messages to the management address

manage

Browse a queue bound to the matching address

browse

For each permission, you specify a list of roles that are granted the permission. If a given user has any of the roles, they are granted the permission for that set of addresses.

The sections that follow show some configuration examples for permissions.

5.3.2.1.1. Configuring message production for a single address

The following procedure shows how to configure message production permissions for a single address.

Procedure

  1. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  2. Add a single <security-setting> element within the <security-settings> element. For the match key, specify an address. For example:

    <security-settings>
        <security-setting match="my.destination">
            <permission type="send" roles="producer"/>
        </security-setting>
    </security-settings>

    Based on the preceding configuration, members of the producer role have send permissions for address my.destination.

5.3.2.1.2. Configuring message consumption for a single address

The following procedure shows how to configure message consumption permissions for a single address.

Procedure

  1. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  2. Add a single <security-setting> element within the <security-settings> element. For the match key, specify an address. For example:

    <security-settings>
        <security-setting match="my.destination">
            <permission type="consume" roles="consumer"/>
        </security-setting>
    </security-settings>

    Based on the preceding configuration, members of the consumer role have consume permissions for address my.destination.

5.3.2.1.3. Configuring complete access on all addresses

The following procedure shows how to configure complete access to all addresses and associated queues.

Procedure

  1. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  2. Add a single <security-setting> element within the <security-settings> element. For the match key, to configure access to all addresses, specify the number sign (#) wildcard character. For example:

    <security-settings>
        <security-setting match="#">
            <permission type="createDurableQueue" roles="guest"/>
            <permission type="deleteDurableQueue" roles="guest"/>
            <permission type="createNonDurableQueue" roles="guest"/>
            <permission type="deleteNonDurableQueue" roles="guest"/>
            <permission type="createAddress" roles="guest"/>
            <permission type="deleteAddress" roles="guest"/>
            <permission type="send" roles="guest"/>
            <permission type="browse" roles="guest"/>
            <permission type="consume" roles="guest"/>
            <permission type="manage" roles="guest"/>
        </security-setting>
    </security-settings>

    Based on the preceding configuration, all permissions are granted to members of the guest role on all queues. This can be useful in a development scenario where anonymous authentication was configured to assign the guest role to every user.

Additional resources

5.3.2.1.4. Configuring multiple security settings

The following example procedure shows how to individually configure multiple security settings for a matching set of addresses. This contrasts with the preceding example in this section, which shows how to grant complete access to all addresses.

  1. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  2. Add a single <security-setting> element within the <security-settings> element. For the match key, include the number sign (#) wildcard character to apply the settings to a matching set of addresses. For example:

    <security-setting match="globalqueues.europe.#">
       <permission type="createDurableQueue" roles="admin"/>
       <permission type="deleteDurableQueue" roles="admin"/>
       <permission type="createNonDurableQueue" roles="admin, guest, europe-users"/>
       <permission type="deleteNonDurableQueue" roles="admin, guest, europe-users"/>
       <permission type="send" roles="admin, europe-users"/>
       <permission type="consume" roles="admin, europe-users"/>
    </security-setting>
    match=globalqueues.europe.#
    The number sign (#) wildcard character is interpreted by the broker as "any sequence of words". Words are delimited by a period (.). In this example, the security settings apply to any address that starts with the string globalqueues.europe.
    permission type="createDurableQueue"
    Only users that have the admin role can create or delete durable queues bound to an address that starts with the string globalqueues.europe.
    permission type="createNonDurableQueue"
    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.
    permission type="send"
    Any users with the roles admin or europe-users can send messages to queues bound to an address that starts with the string globalqueues.europe.
    permission type="consume"
    Any users with the roles admin or europe-users can consume messages from queues bound to an address that starts with the string globalqueues.europe.
  3. (Optional) To apply different security settings to a more narrow set of addresses, add another <security-setting> element. For the match key, specify a more specific text string. For example:

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

    In the second security-setting element, the globalqueues.europe.orders.# match is more specific than the globalqueues.europe.# match specified in the first security-setting element. For any addresses that match globalqueues.europe.orders.#, the permissions createDurableQueue, deleteDurableQueue, createNonDurableQueue, deleteNonDurableQueue are not inherited from the first security-setting element in the file. For example, for the address globalqueues.europe.orders.plastics, the only permissions that exist are send and consume for the role europe-users.

    Therefore, because permissions specified in one security-setting block are not inherited by another, you can effectively deny permissions in more specific security-setting blocks simply by not specifying those permissions.

5.3.2.1.5. Configuring a queue with a user

When a queue is automatically created, the queue is assigned the user name of the connecting client. This user name is included as metadata on the queue. The name is exposed by JMX and in the AMQ Broker management console.

The following procedure shows how to add a user name to a queue that you have manually defined in the broker configuration.

Procedure

  1. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  2. For a given queue, add the user key. Assign a value. For example:

    <address name="ExampleQueue">
        <anycast>
           <queue name="ExampleQueue" user="admin"/>
        </anycast>
    </address>

    Based on the preceding configuration, the admin user is assigned to queue ExampleQueue.

Note
  • Configuring a user on a queue does not change any of the security semantics for that queue - it is only used for metadata on that queue.
  • The mapping between users and what roles they have is handled by a component called the security manager. The security manager reads user credentials from a properties file stored on the broker. By default, AMQ Broker uses the org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager security manager. This default security manager provides integration with JAAS and Red Hat JBoss Enterprise Application Platform (JBoss EAP) security.

    To learn how to use a custom security manager, see Section 5.6.2, “Specifying a custom security manager”.

5.3.2.2. Configuring role-based access control

Role-based access control (RBAC) is used to restrict access to the attributes and methods of MBeans. RBAC enables administrators to grant the correct level of access to all users like web console, management interface, core messages, and so on, based on role.

5.3.2.2.1. Configuring role-based access

The following example procedure shows how to map roles to particular MBeans and their attributes and methods.

Prerequisites

Procedure

  1. Open the <broker_instance_dir>/etc/management.xml configuration file.
  2. Search for the role-access element and edit the configuration. For example:

    <role-access>
        <match domain="org.apache.activemq.artemis">
           <access method="list*" roles="view,update,amq"/>
           <access method="get*" roles="view,update,amq"/>
           <access method="is*" roles="view,update,amq"/>
           <access method="set*" roles="update,amq"/>
           <access method="*" roles="amq"/>
        </match>
    </role-access>
    • In this case, a match is applied to any MBean attribute that has the domain name org.apache.activemq.apache.
    • Access of the view, update, or amq role to a matching MBean attribute is controlled by which of the list*, get*, set*, is*, and * access methods that you add the role to. The method="*" (wildcard) syntax is used as a catch-all way to specify every other method that is not listed in the configuration. Each of the access methods in the configuration is converted to an MBean method call.
    • An invoked MBean method is matched against the methods listed in the configuration. For example, if you invoke a method called listMessages on an MBean with the org.apache.activemq.artemis domain, then the broker matches access back to the roles defined in the configuration for the list method.
    • You can also configure access by using the full MBean method name. For example:

      <access method="listMessages" roles="view,update,amq"/>
  3. Start or restart the broker.

    • On Linux: <broker_instance_dir>/bin/artemis run
    • On Windows: <broker_instance_dir>\bin\artemis-service.exe start

You can also match specific MBeans within a domain by adding a key attribute that matches an MBean property.

5.3.2.2.2. Role-based access examples

This section shows the following examples of applying role-based access control:

The following example shows how to use the key attribute to map roles to all queues in a specified domain.

<match domain="org.apache.activemq.artemis" key="subcomponent=queues">
   <access method="list*" roles="view,update,amq"/>
   <access method="get*" roles="view,update,amq"/>
   <access method="is*" roles="view,update,amq"/>
   <access method="set*" roles="update,amq"/>
   <access method="*" roles="amq"/>
</match>

The following example shows how to use the key attribute to map roles to a specific, named queue. In this example, the named queue is exampleQueue.

<match domain="org.apache.activemq.artemis" key="queue=exampleQueue">
   <access method="list*" roles="view,update,amq"/>
   <access method="get*" roles="view,update,amq"/>
   <access method="is*" roles="view,update,amq"/>
   <access method="set*" roles="update,amq"/>
   <access method="*" roles="amq"/>
</match>

The following example shows how to map roles to every queue whose name includes a specified prefix. In this example, an asterisk (*) wildcard operator is used to match all queue names that start with the prefix example.

<match domain="org.apache.activemq.artemis" key="queue=example*">
   <access method="list*" roles="view,update,amq"/>
   <access method="get*" roles="view,update,amq"/>
   <access method="is*" roles="view,update,amq"/>
   <access method="set*" roles="update,amq"/>
   <access method="*" roles="amq"/>
</match>

You might want to map roles differently for different sets of the same attribute (for example, different sets of queues). In this case, you can include multiple match elements in your configuration file. However, it is then possible to have multiple matches in the same domain.

For example, consider two <match> elements configured as follows:

<match domain="org.apache.activemq.artemis" key="queue=example*">

and

<match domain="org.apache.activemq.artemis" key="queue=example.sub*">

Based on this configuration, a queue named example.sub.queue in the org.apache.activemq.artemis domain matches both wildcard key expressions. Therefore, the broker needs a prioritization scheme to decide which set of roles to map to the queue; the roles specified in the first match element, or those specified in the second match element.

When there are multiple matches in the same domain, the broker uses the following prioritization scheme when mapping roles:

  • Exact matches are prioritized over wildcard matches
  • Longer wildcard matches are prioritized over shorter wildcard matches

In this example, because the longer wildcard expression matches the queue name of example.sub.queue most closely, the broker applies the role-mapping configured in the second <match> element.

Note

The default-access element is a catch-all element for every method call that is not handled using the role-access or whitelist configurations. The default-access and role-access elements have the same match element semantics.

5.3.2.2.3. Configuring the whitelist element

A whitelist is a set of pre-approved domains or MBeans that do not require user authentication. You can provide a list of domains, or list of MBeans, or both, that must bypass the authentication. For example, you might use the whitelist to specify any MBeans that are needed by the AMQ Broker management console to run.

The following example procedure shows how to configure the whitelist element.

Procedure

  1. Open the <broker_instance_dir>/etc/management.xml configuration file.
  2. Search for the whitelist element and edit the configuration:

    <whitelist>
       <entry domain="hawtio"/>
    </whitelist>

    In this example, any MBean with the domain hawtio is allowed access without authentication. You can also use wildcard entries of the form <entry domain="hawtio" key="type=*"/> for the MBean properties to match.

  3. Start or restart the broker.

    • On Linux: <broker_instance_dir>/bin/artemis run
    • On Windows: <broker_instance_dir>\bin\artemis-service.exe start

5.3.2.3. 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.

5.3.2.3.1. Configuring connection and queue limits

The following example procedure shows how to limit the number of connections and queues that a user can create.

  1. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  2. Add a resource-limit-settings element. Specify values for max-connections and max-queues. For example:

    <resource-limit-settings>
       <resource-limit-setting match="myUser">
          <max-connections>5</max-connections>
          <max-queues>3</max-queues>
       </resource-limit-setting>
    </resource-limit-settings>
    max-connections
    Defines how many connections the matched user can make to the broker. The default is -1, which means that there is no limit.
    max-queues
    Defines how many queues the matched user can create. The default is -1, which means that there is no limit.
Note

Unlike the match string that you can specify in the address-setting element of a broker configuration, the match string that you specify in resource-limit-settings cannot use wildcard syntax. Instead, the match string defines a specific user to which the resource limit settings are applied.

5.4. Using LDAP for authentication and authorization

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.

5.4.1. Configuring LDAP to authenticate clients

The following example procedure shows how to use LDAP to authenticate clients.

Procedure

  1. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  2. Within the security-settings element, add a security-setting element to configure permissions. For example:

    <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>

    The preceding configuration assigns specific permissions for all queues to members of the user role.

  3. Open the <broker_instance_dir>/etc/login.config file.
  4. Configure the LDAP login module, based on the directory service you are using.

    1. If you are using the Microsoft Active Directory directory service, add a configuration that resembles this example:

      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,OU=System,DC=example,DC=com"
           connectionPassword=redhat.123
           connectionProtocol=s
           connectionTimeout="5000"
           authentication=simple
           userBase="dc=example,dc=com"
           userSearchMatching="(CN={0})"
           userSearchSubtree=true
           readTimeout="5000"
           roleBase="dc=example,dc=com"
           roleName=cn
           roleSearchMatching="(member={0})"
           roleSearchSubtree=true
           ;
      };
      Note

      If you are using Microsoft Active Directory, and a value that you need to specify for an attribute of connectionUsername contains a space (for example, OU=System Accounts), then you must enclose the value in a pair of double quotes ("") and use a backslash (\) to escape each double quote in the pair. For example, connectionUsername="CN=Administrator,CN=Users,OU=\"System Accounts\",DC=example,DC=com".

    2. If you are using the ApacheDS directory service, add a configuration that resembles this example:

      activemq {
        org.apache.activemq.artemis.spi.core.security.jaas.LDAPLoginModule required
           debug=true
           initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
           connectionURL="ldap://localhost:10389"
           connectionUsername="uid=admin,ou=system"
           connectionPassword=secret
           connectionProtocol=s
           connectionTimeout=5000
           authentication=simple
           userBase="dc=example,dc=com"
           userSearchMatching="(uid={0})"
           userSearchSubtree=true
           userRoleName=
           readTimeout=5000
           roleBase="dc=example,dc=com"
           roleName=cn
           roleSearchMatching="(member={0})"
           roleSearchSubtree=true
           ;
      };
      debug
      Turn debugging on (true) or off (false). The default value is false.
      initialContextFactory
      Must always be set to com.sun.jndi.ldap.LdapCtxFactory
      connectionURL
      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.
      connectionUsername
      Distinguished Name (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.
      connectionPassword
      Password that matches the DN from connectionUsername. In the directory server, in the Directory Information Tree (DIT), the password is normally stored as a userPassword attribute in the corresponding directory entry.
      connectionProtocol
      Any value is supported but is effectively unused. This option must be set explicitly because it has no default value.
      connectionTimeout

      Specify the maximum time, in milliseconds, that the broker can take to connect to the directory server. If the broker cannot connect to the directory sever within this time, it aborts the connection attempt. If you specify a value of zero or less for this property, the timeout value of the underlying TCP protocol is used instead. If you do not specify a value, the broker waits indefinitely to establish a connection, or the underlying network times out.

      When connection pooling has been requested for a connection, then this property specifies the maximum time that the broker waits for a connection when the maximum pool size has already been reached and all connections in the pool are in use. If you specify a value of zero or less, the broker waits indefinitely for a connection to become available. Otherwise, the broker aborts the connection attempt when the maximum wait time has been reached.

      authentication
      Specifies 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).
      userBase
      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.
      userSearchMatching
      Specify an LDAP search filter, which is applied to the subtree selected by userBase. See the Section 5.4.1.1, “Search matching parameters” section below for more information.
      userSearchSubtree
      Specify the search depth for user entries, relative to the node specified by userBase. This option is a Boolean. Specifying a value of false means that the search tries to match one of the child entries of the userBase node (maps to javax.naming.directory.SearchControls.ONELEVEL_SCOPE). Specifying a value of true means that the search tries to match any entry belonging to the subtree of the userBase node (maps to javax.naming.directory.SearchControls.SUBTREE_SCOPE).
      userRoleName
      Name of the attribute of the user entry that contains a list of role names for the user. 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.
      readTimeout
      Specify the maximum time, in milliseconds, that the broker can wait to receive a response from the directory server to an LDAP request. If the broker does not receive a response from the directory server in this time, the broker aborts the request. If you specify a value of zero or less, or you do not specify a value, the broker waits indefinitely for a response from the directory server to an LDAP request.
      roleBase
      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.
      roleName
      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.
      roleSearchMatching
      Specify an LDAP search filter, which is applied to the subtree selected by roleBase. See the Section 5.4.1.1, “Search matching parameters” section below for more information.
      roleSearchSubtree

      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).

      Note

      Apache DS uses the OID portion of DN path. Microsoft Active Directory uses the CN portion. For example, you might use a DN path such as oid=testuser,dc=example,dc=com in Apache DS, while you might use a DN path such as cn=testuser,dc=example,dc=com in Microsoft Active Directory.

  5. Start or restart the broker (service or process).

5.4.1.1. Search matching parameters

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.

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 user name. For example, jdoe.

If this option is set to (member=uid={1}) and the received user name 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).

Additional resources

5.4.2. Configuring LDAP authorization

The LegacyLDAPSecuritySettingPlugin security settings plugin reads the security information previously handled in AMQ 6 by LDAPAuthorizationMap and cachedLDAPAuthorizationMap and converts this information to corresponding AMQ 7 security settings, where possible.

The security implementations for brokers in AMQ 6 and AMQ 7 do not match exactly. Therefore, the plugin performs some translation between the two versions to achieve near-equivalent functionality.

The following example shows how to configure the plugin.

Procedure

  1. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  2. Within the security-settings element, add the security-setting-plugin element. For example:

    <security-settings>
        <security-setting-plugin class-name="org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin">
            <setting name="initialContextFactory" value="com.sun.jndi.ldap.LdapCtxFactory"/>
            <setting name="connectionURL" value="ldap://localhost:1024"/>`ou=destinations,o=ActiveMQ,ou=system`
            <setting name="connectionUsername" value="uid=admin,ou=system"/>
            <setting name="connectionPassword" value="secret"/>
            <setting name="connectionProtocol" value="s"/>
            <setting name="authentication" value="simple"/>
        </security-setting-plugin>
    </security-settings>
    class-name
    The implementation is org.apache.activemq.artemis.core.server.impl.LegacyLDAPSecuritySettingPlugin.
    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).
    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 distinguished name (DN) of a particular node in the directory tree. For example, ldap://ldapserver:10389/ou=system. The default value is ldap://localhost:1024.
    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.
    connectionPassword
    The password that matches the DN from connectionUsername. In the directory server, in the Directory Information Tree (DIT), the password is normally stored as a userPassword attribute in the corresponding directory entry.
    connectionProtocol
    Currently unused. In the future, this option might allow you 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.
    authentication

    Specifies the authentication method used when binding to the LDAP server. Valid values for this parameter are simple (username and password) or none (anonymous). The default value is simple.

    Note

    Simple Authentication and Security Layer (SASL) authentication is not supported.

Other settings not shown in the preceding configuration example 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 The default value is ou=destinations,o=ActiveMQ,ou=system.
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. The 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
Specifies whether to enable a listener that automatically receives updates made in the LDAP server and update the broker’s authorization configuration in real time. The default value is true.
mapAdminToManage

Specifies whether to map the legacy (that is, AMQ 6) admin permission to the AMQ 7 manage permission. See details of the mapping semantics in the table below. The default value is false.

The name of the queue or topic defined in LDAP serves as the "match" for the security setting, the permission value is mapped from the AMQ 6 type to the AMQ 7 type, and the role is mapped as-is. Because the name of the queue or topic defined in LDAP serves as the match for the security setting, the security setting may not be applied as expected to JMS destinations. This is because AMQ 7 always prefixes JMS destinations with "jms.queue." or "jms.topic.", as necessary.

AMQ 6 has three permission types - read, write, and admin. These permission types are described on the ActiveMQ website; Security.

AMQ 7 has the following permission types:

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

    This table shows how the security settings plugin maps AMQ 6 permission types to AMQ 7 permission types:

    AMQ 6 permission typeAMQ 7 permission type

    read

    consume, browse

    write

    send

    admin

    createAddress, deleteAddress, createDurableQueue, deleteDurableQueue, createNonDurableQueue, deleteNonDurableQueue, manage (if mapAdminToManage is set to true)

    As described below, there are some cases in which the plugin performs some translation between the AMQ 6 and AMQ 7 permission types to achieve equivalence:

    • The mapping does not include the AMQ 7 manage permission type by default because there is no analogous permission type in AMQ 6. However, if mapAdminToManage is set to true, the plugin maps the AMQ 6 admin permission to the AMQ 7 manage permission.
    • The admin permission type in AMQ 6 determines whether the broker automatically creates a destination if the destination does not exist and the user sends a message to it. AMQ 7 automatically allows automatic creation of a destination if the user has permission to send messages to the destination. Therefore, the plugin maps the legacy admin permission to the AMQ 7 permissions shown above, by default. The plugin also maps the AMQ 6 admin permission to the AMQ 7 manage permission if mapAdminToManage is set to true.
allowQueueAdminOnRead

Whether or not to map the legacy read permission to the createDurableQueue, createNonDurableQueue, and deleteDurableQueue permissions so that JMS clients can create durable and non-durable subscriptions without needing the admin permission. This was allowed in AMQ 6. The default value is false.

This table shows how the security settings plugin maps AMQ 6 permission types to AMQ 7 permission types when allowQueueAdminOnRead is true:

AMQ 6 permission typeAMQ 7 permission type

read

consume, browse, createDurableQueue, createNonDurableQueue, deleteDurableQueue

write

send

admin

createAddress, deleteAddress, deleteNonDurableQueue, manage (if mapAdminToManage is set to true)

5.4.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 encrypted.

Prerequisites

Procedure

The following procedure shows how to mask the value of the connectionPassword parameter 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>
    result: 3a34fd21b82bf2a822fa49a8d8fa115d
  2. Open the <broker_instance_dir>/etc/login.config file. Locate the connectionPassword parameter:

    connectionPassword = <password>
  3. Replace the plain-text password with the encrypted value:

    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

5.4.4. Mapping external roles

You can map roles from external authentication providers such as LDAP to roles used internally by the broker.

To map external roles, create role-mapping entries in a security-settings element in the broker.xml configuration file. For example:

<security-settings>
...
    <role-mapping from="cn=admins,ou=Group,ou=ActiveMQ,ou=system" to="my-admin-role"/>
    <role-mapping from="cn=users,ou=Group,ou=ActiveMQ,ou=system" to="my-user-role"/>
</security-settings>
Note
  • Role mapping is additive. That means the user will keep the original role(s) as well as the newly assigned role(s).
  • Role mapping only affects the roles authorizing queue access and does not provide a method to enable web console access.

5.5. Using Kerberos for authentication and authorization

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 Security (TLS) to secure your messaging applications. SASL provides user authentication, and TLS provides data integrity.

Important
  • 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.

  • 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.

The following procedures show how to configure Kerberos for authentication and authorization.

5.5.1. Configuring 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.

The following procedure shows how to configure an acceptor to use Kerberos.

Prerequisites

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

Procedure

  1. Stop the broker.

    1. On Linux:

      <broker_instance_dir>/bin/artemis stop
    2. On Windows:

      <broker_instance_dir>\bin\artemis-service.exe stop
  2. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  3. Add the name-value pair saslMechanisms=GSSAPI to the query string of the URL for the acceptor.

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

    The preceding configuration means that the acceptor uses the GSSAPI mechanism when authenticating Kerberos credentials.

  4. (Optional) The PLAIN and ANONYMOUS SASL mechanisms are also supported. To specify multiple mechanisms, use a comma-separated list. For example:

    <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. On Linux:

      <broker_instance_dir>/bin/artemis run
    2. On Windows:

      <broker_instance_dir>\bin\artemis-service.exe start

Additional resources

5.5.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

Procedure

  1. Stop the broker.

    1. On Linux:

      <broker_instance_dir>/bin/artemis stop
    2. On Windows:

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

    amqp-sasl-gssapi {
        com.sun.security.auth.module.Krb5LoginModule required
        isInitiator=false
        storeKey=true
        useKeyTab=true
        principal="amqp/my_broker_host@example.com"
        debug=true;
    };
    amqp-sasl-gssapi
    By default, the GSSAPI mechanism implementation on the broker uses a JAAS configuration scope named amqp-sasl-gssapi to obtain its Kerberos acceptor credentials.
    Krb5LoginModule
    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.
    useKeyTab
    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.
    principal
    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. On Linux:

      <broker_instance_dir>/bin/artemis run
    2. On Windows:

      <broker_instance_dir>\bin\artemis-service.exe start

5.5.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, 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>

5.5.3. Authorizing clients with Kerberos credentials

AMQ Broker includes an implementation of the JAAS Krb5LoginModule login module 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 module, 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. On Linux:

      <broker_instance_dir>/bin/artemis stop
    2. On Windows:

      <broker_instance_dir>\bin\artemis-service.exe stop
  2. Open the <broker_instance_dir>/etc/login.config configuration file.
  3. Add configuration for the AMQ Broker Krb5LoginModule and the LDAPLoginModule. Verify the configuration options by referring to the documentation from your LDAP provider.

    An example configuration is shown below.

    org.apache.activemq.artemis.spi.core.security.jaas.Krb5LoginModule required
        ;
    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
        ;
    Note

    The version of the Krb5LoginModule shown in the preceding example 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. On Linux:

      <broker_instance_dir>/bin/artemis run
    2. On Windows:

      <broker_instance_dir>\bin\artemis-service.exe start

Additional resources

5.6. Specifying a security manager

The broker uses a component called the security manager to handle authentication and authorization.

AMQ Broker includes two security managers:

  • The ActiveMQJAASSecurityManager security manager. This security manager provides integration with JAAS and Red Hat JBoss Enterprise Application Platform (JBoss EAP) security. This is the default security manager used by AMQ Broker.
  • The ActiveMQBasicSecurityManager security manager. This basic security manager doesn’t support JAAS. Instead, it supports authentication and authorization through user name and password credentials. This security manager supports adding, removing, and updating users using the management API. All user and role data is stored in the broker bindings journal. This means that any changes made to a live broker are also available to its backup broker.

As an alternative to the included security managers, a system administrator might want more control over the implementation of broker security. In this case, it is also possible to specify a custom security manager in the broker configuration. A custom security manager is a user-defined class that implements the org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager5 interface.

The examples in the following sub-sections show how to configure the broker to use:

  • The basic security manager instead of the default JAAS security manager
  • A custom security manager

5.6.1. Using the basic security manager

In addition to the default ActiveMQJAASSecurityManager security manager, AMQ Broker also includes the ActiveMQBasicSecurityManager security manager.

When you use the basic security manager, all user and role data is stored in the bindings journal (or the bindings table, if you are using JDBC persistence). Therefore, if you have configured a live-backup broker group, any user management that you peform on the live broker is automatically reflected on the backup broker upon failover. This avoids the need to separately administer an LDAP server, which is the alternative way to achieve this behavior.

Before you configure and use the basic security manager, be aware of the following:

  • The basic security manager is not pluggable like the default JAAS security manager.
  • The basic security manager does not support JAAS. Instead, it supports only authentication and authorization through user name and password credentials.
  • AMQ Management Console requires JAAS. Therefore, if you use the basic security manager and want to use the console, you also need to configure the login.config configuration file for user and password authentication. For more information about configuring user and password authentication, see Section 5.2.2.1, “Configuring basic user and password authentication”.
  • In AMQ Broker, user management is provided by the broker management API. This management includes the ability to add, list, update, and remove users and roles. You can perform these functions using JMX, management messages, HTTP (using Jolokia or AMQ Management Console), and the AMQ Broker command-line interface. Because the broker directly store this data, the broker must be running in order to manage users. There is no way to manually modify the bindings data.
  • Any management access through HTTP (for example, using Jolokia or AMQ Management Console) is handled by the console JAAS login module. MBean access through JConsole or other remote JMX tools is handled by the basic security manager. Management messages are handled by the basic security manager.

5.6.1.1. Configuring the basic security manager

The following procedure shows how to configure the broker to use the basic security manager.

Procedure

  1. Open the <broker-instance-dir>/etc/boostrap.xml configuration file.
  2. In the security-manager element, for the class-name attribute, specify the full ActiveMQBasicSecurityManager class name.

    <broker xmlns="http://activemq.org/schema">
       ...
       <security-manager class-name="org.apache.activemq.artemis.spi.core.security.ActiveMQBasicSecurityManager">
       </security-manager>
       ...
    </broker>
  3. Because you cannot manually modify the bindings data that holds user and role data, and because the broker must be running to manage users, it is advisable to secure the broker upon first boot. To achieve this, define a bootstrap user whose credentials can then be used to add other users.

    In the security-manager element, add the bootstrapUser, bootstrapPassword, and bootstrapRole properties and specify values. For example:

    <broker xmlns="http://activemq.org/schema">
       ...
       <security-manager class-name="org.apache.activemq.artemis.spi.core.security.ActiveMQBasicSecurityManager">
            <property key="bootstrapUser" value="myUser"/>
            <property key="bootstrapPassword" value="myPass"/>
            <property key="bootstrapRole" value="myRole"/>
       </security-manager>
       ...
    </broker>
    bootstrapUser
    Name of the bootstrap user.
    bootstrapPassword
    Passsword of the boostrap user. You can also specify an encrypted password.
    bootstrapRole

    Role of the boostrap user.

    Note

    If you define the preceding properties for the bootstrap user in your configuration, those credentials are set each time that you start the broker, regardless of any changes you make while the broker is running.

  4. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  5. In the broker.xml configuration file, locate the address-setting element that is defined by default for the activemq.management# address match. These default address settings are shown below.

    <address-setting match="activemq.management#">
        <dead-letter-address>DLQ</dead-letter-address>
        <expiry-address>ExpiryQueue</expiry-address>
        <redelivery-delay>0</redelivery-delay>
        <!--...-->
        <max-size-bytes>-1</max-size-bytes>
        <message-counter-history-day-limit>10</message-counter-history-day-limit>
        <address-full-policy>PAGE</address-full-policy>
        <auto-create-queues>true</auto-create-queues>
        <auto-create-addresses>true</auto-create-addresses>
        <auto-create-jms-queues>true</auto-create-jms-queues>
        <auto-create-jms-topics>true</auto-create-jms-topics>
    </address-setting>
  6. Within the address settings for the activemq.management# address match, for the bootstrap role name that you specified earlier in this procedure, add the following required permissions:

    • createNonDurableQueue
    • createAddress
    • consume
    • manage
    • send

    For example:

    <address-setting match="activemq.management#">
        ...
        <permission type="createNonDurableQueue" roles="myRole"/>
        <permission type="createAddress" roles="myRole"/>
        <permission type="consume" roles="myRole"/>
        <permission type="manage" roles="myRole"/>
        <permission type="send" roles="myRole"/>
    </address-setting>

Additional resources

5.6.2. Specifying a custom security manager

The following procedure shows how to specify a custom security manager in your broker configuration.

Procedure

  1. Open the <broker_instance_dir>/etc/boostrap.xml configuration file.
  2. In the security-manager element, for the class-name attribute, specify the class that is a user-defined implementation of the org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager5 interface. For example:

    <broker xmlns="http://activemq.org/schema">
       ...
       <security-manager class-name="com.foo.MySecurityManager">
          <property key="myKey1" value="myValue1"/>
          <property key="myKey2" value="myValue2"/>
       </security-manager>
       ...
    </broker>

Additional resources

5.6.3. Running the custom security manager example program

AMQ Broker includes an example program that demonstrates how to implement a custom security manager. In the example, the custom security manager logs details for authentication and authorization and then passes the details to an instance of ActiveMQJAASSecurityManager (that is, the default security manager).

The following procedure shows how to run the custom security manager example program.

Prerequisites

Procedure

  1. Navigate to the directory that contains the custom security manager example.

    $ cd <install_dir>/examples/features/standard/security-manager
  2. Run the example.

    $ mvn verify
Note

If you would prefer to manually create and start a broker instance when running the example program, replace the command in the preceding step with mvn -PnoServer verify.

Additional resources

5.7. Disabling security

Security is enabled by default. The following procedure shows how to disable broker security.

Procedure

  1. Open the <broker_instance_dir>/etc/broker.xml configuration file.
  2. In the core element, set the value of security-enabled to false.

    <security-enabled>false</security-enabled>
  3. If necessary, specify a new value, in milliseconds, for security-invalidation-interval. The value of this property specifies when the broker periodically invalidates secure logins. The default value is 10000.

5.8. 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.

5.9. 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.

5.9.1. About encrypted passwords

An encrypted, or 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 keyStorePassword and trustStorePassword parameters.

<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 with the following 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 Broker management console.

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

5.9.2. Encrypting a password in a configuration file

The following example shows how to mask the value of cluster-password in the broker.xml configuration file.

Procedure

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

    $ <broker_instance_dir>/bin/artemis mask <password>
    result: 3a34fd21b82bf2a822fa49a8d8fa115d
  2. Open the <broker_instance_dir>/etc/broker.xml configuration file containing the plain-text password that you want to mask:

    <cluster-password>
      <password>
    </cluster-password>
  3. Replace the plain-text password with the encrypted value:

    <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 an encrypted password. Because the password is wrapped with the ENC() identifier, AMQ Broker decrypts it before it is used.

Additional resources

Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.