Red Hat Training

A Red Hat training course is available for Red Hat JBoss Enterprise Application Platform

Chapter 7. Configuring Security

7.1. Securing Remote Connections

JBoss EAP secures the messaging-activemq subsystem with the help of security realms and domains. See the JBoss EAP Security Architecture guide for more information on security realms and security domains. The messaging-activemq subsystem is pre-configured to use the security realm named ApplicationRealm and the security domain named other.

The ApplicationRealm is defined near the top of the configuration file.

<management>
  <security-realms>
      ...
       <security-realm name="ApplicationRealm">
          <authentication>
              <local default-user="$local" allowed-users="*" skip-group-loading="true"/>
              <properties
                path="application-users.properties"
                relative-to="jboss.server.config.dir" />
          </authentication>
          <authorization>
              <properties
                path="application-roles.properties"
                relative-to="jboss.server.config.dir" />
          </authorization>
       </security-realm>
  </security-realms>
  ...
</management>

As its name implies, ApplicationRealm is the default security realm for all application-focused subsystems in JBoss EAP such as the messaging-activemq, undertow, and ejb3 subsystems. ApplicationRealm uses the local filesystem to store usernames and hashed passwords. For convenience JBoss EAP includes a script that you can use to add users to the ApplicationRealm. See Default User Configuration in the JBoss EAP How To Configure Server Security guide for details.

The other security domain is the default security domain for the application-related subsystems like messaging-activemq. It is not explicitly declared in the configuration; however, you can confirm which security domain is used by the messaging-activemq subsystem with the following management CLI command:

/subsystem=messaging-activemq/server=default:read-attribute(name=security-domain)
{
    "outcome" => "success",
    "result" => "other"
}

You can also update which security domain is used:

/subsystem=messaging-activemq/server=default:write-attribute(name=security-domain, value=mySecurityDomain)

The JBoss EAP How To Configure Server Security guide has more information on how to create new security realms and domains. For now, it is worth noting how the other domain appears in the configuration:

<subsystem xmlns="urn:jboss:domain:security:1.2">
     <security-domains>
         <security-domain name="other" cache-type="default">
             <authentication>
                 <login-module code="Remoting" flag="optional">
                     <module-option name="password-stacking" value="useFirstPass"/>
                 </login-module>
                 <login-module code="RealmDirect" flag="required">
                     <module-option name="password-stacking" value="useFirstPass"/>
                 </login-module>
             </authentication>
         </security-domain>
         ...
     <security-domains>
 </subsystem>

The 'other' domain uses two login-modules as its means of authentication. The first module, Remoting, authenticates remote EJB invocations, while the RealmDirect module uses the information store defined in a given realm to authenticate users. In this case the default realm ApplicationRealm is used, since no realm is declared. Each module has its password-stacking option set to useFirstPass, which tells the login-module to store the principal name and password of the authenticated user. See the JBoss EAP Login Module Reference for more details on the login modules and their options.

Role-based access is configured at the address level, see Role Based Security for Addresses.

7.1.1. Securing the Transport

Using the default http-connector that comes bundled with JBoss EAP messaging and discussed in Configuring the Messaging Transports, JBoss EAP is a great convenience in terms of port management. However it is not secured without further configuration. Fortunately securing the messaging transport is as easy as enabling normal web traffic for SSL/TLS. The steps to do this are provided in Setting Up SSL/TLS for Applications in JBoss EAP How To Configure Server Security.

7.1.2. Securing a Remote Connector

If you are not using the default http-connector and have instead created your own remote-connector and remote-acceptor for TCP communications, you can configure each for SSL/TLS by using the properties in the table below. The properties appear in the configuration as part of the child <param> elements of the acceptor or connector.

Typically, a server owns its private SSL/TLS key and shares its public key with clients. In this scenario, the server defines the key-store-path and key-store-password parameters in a remote-acceptor. Since each client can have its trust store located at a different location, and be encrypted by a different password, specifying the tust-store-path and trust-store-password properties on the remote-connector is not recommended. Instead, configure these parameters on the client side using the system properties javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword. The only parameter which you need to configure for a remote-connector is ssl-enabled=true. However, if the server uses remote-connector to connect to another server, it makes sense in this case to set the trust-store-path and trust-store-password parameters of the remote-connector.

In the above use case, the remote-acceptor would be created using the following management CLI command:

/subsystem=messaging-activemq/server=default/remote-acceptor=mySslAcceptor:add(socket-binding=netty,params={ssl-enabled=true, key-store-path=path/to/server.jks, key-store-password=${VAULT::server-key::key-store-password::sharedKey}})

To create the remote-connector from the above use case, use the following management CLI command:

/subsystem=messaging-activemq/server=default/remote-connector=mySslConnector:add(socket-binding=netty,params={ssl-enabled=true})

The management CLI also allows you to add a parameter to an already existing remote-acceptor or remote-connector as well:

/subsystem=messaging-activemq/server=default/remote-connector=myOtherSslConnector:map-put(name=params,key=ssl-enabled,value=true)

Note that the remote-acceptor and remote-connector both reference a socket-binding to declare the port to be used for communication. See the Overview of the Messaging Subsystem Configuration for more information on socket bindings and their relationship to acceptors and connectors.

Table 7.1. SSL/TLS-related Configuration Properties for the NettyConnectorFactory

PropertyDescription

enabled-cipher-suites

Can be used to configure an acceptor or connector. This is a comma separated list of cipher suites used for SSL/TLS communication. The default value is null which means the JVM’s default will be used.

enabled-protocols

Can be used to configure an acceptor or connector. This is a comma separated list of protocols used for SSL/TLS communication. The default value is null which means the JVM’s default will be used.

key-store-password

When used on an acceptor, this is the password for the server-side keystore.

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 SSL/TLS. 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, it can override the server-side setting by either using the standard javax.net.ssl.keyStorePassword system property. Use the org.apache.activemq.ssl.keyStorePassword property if another component on the client is already making use of the standard system property.

key-store-path

When used on an acceptor, this is the path to the SSL/TLS key store on the server which holds the server’s certificates. Use for certificates either self-signed or signed by an authority.

When used on a connector, this is the path to the client-side SSL/TLS key store which holds the client certificates. This is only relevant for a connector if you are using two-way SSL/TLS.

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, it can override the server-side setting by using the standard javax.net.ssl.keyStore system property. Use the org.apache.activemq.ssl.keyStore system property if another component on the client is already making use of the standard property.

key-store-provider

Defines the format of the file in which keys are stored, PKCS11 or PKCS12 for example. The accepted values are JDK specific.

needs-client-auth

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

ssl-enabled

Must be true to enable SSL/TLS. Default is false.

trust-store-password

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 SSL/TLS.

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, it can override the server-side setting by using either the standard javax.net.ssl.trustStorePassword system property. Use the org.apache.activemq.ssl.trustStorePassword system property if another component on the client is already making use of the standard property.

trust-store-path

When used on an acceptor, this is the path to the server-side SSL/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 SSL/TLS.

When used on a connector, this is the path to the client-side SSL/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, it can override the server-side setting by using either the standard javax.net.ssl.trustStore system property. Use the org.apache.activemq.ssl.trustStore system property if another component on the client is already making use of the standard system property.

trust-store-provider

Defines the format of the file in which keys are stored, PKCS11 or PKCS12 for example. The accepted values are JDK specific.

7.2. Securing Destinations

In addition to securing remote connections into the messaging server, you can also configure security around specific destinations. This is done by adding a security constraint using the security-setting configuration element. JBoss EAP messaging comes with a security-setting configured by default, as shown in the output from the following management CLI command:

/subsystem=messaging-activemq/server=default:read-resource(recursive=true)
{
    "outcome" => "success",
    "result" => {
        ....
        "security-setting" => {"#" => {"role" => {"guest" => {
            "consume" => true,
            "create-durable-queue" => false,
            "create-non-durable-queue" => true,
            "delete-durable-queue" => false,
            "delete-non-durable-queue" => true,
            "manage" => false,
            "send" => true
        }}}}
    }
}

The security-setting option makes use of wildcards in the name field to handle which destinations to apply the security constraint. The value of a single # will match any address. For more information on using wildcards in security constraints, see Role Based Security for Addresses.

7.2.1. Role-Based Security for Addresses

JBoss EAP messaging contains a flexible role-based security model for applying security to queues, based on their addresses.

The core JBoss EAP messaging server consists mainly of sets of queues bound to addresses. When a message is sent to an address, the server first looks up the set of queues that are bound to that address and then routes the message to the bound queues.

JBoss EAP messaging has a set of permissions that can be applied against queues based on their address. An exact string match on the address can be used or a wildcard match can be used using the wildcard characters # and *. See Address Settings for more information on how to use the wildcard syntax.

You can create multiple roles for each security-setting, and there are 7 permission settings that can be applied to a role. Below is the complete list of the permissions available:

  • create-durable-queue allows the role to create a durable queue under matching addresses.
  • delete-durable-queue allows the role to delete a durable queue under matching addresses.
  • create-non-durable-queue allows the role to create a non-durable queue under matching addresses.
  • delete-non-durable-queue allows the role to delete a non-durable queue under matching addresses.
  • send allows the role to send a message to matching addresses.
  • consume allows the role to consume a message from a queue bound to matching addresses.
  • manage allows the role to invoke management operations by sending management messages to the management address.
Configuring Role-Based Security

To start using role-based security for a security-setting, you first must create one. As an example, a security-setting of news.europe.# is created below. It would apply to any destination starting with news.europe., such as news.europe.fr or news.europe.tech.uk.

/subsystem=messaging-activemq/server=default/security-setting=news.europe.#:add()
{"outcome" => "success"}

Next, you add a role to the security-setting you created and declare permissions for it. In the example below, the dev role is created and given permissions to consume from, and send to, queues, as well as to create and delete non-durable queues. Because the default is false, you have to tell JBoss EAP only about the permissions you want to switch on.

/subsystem=messaging-activemq/server=default/security-setting=news.europe.#/role=dev:add(consume=true,delete-non-durable-queue=true,create-non-durable-queue=true,send=true)
{"outcome" => "success"}

To further illustrate the use of permissions, the example below creates an admin role and allows it to send management messages by switching on the manage permission. The permissions for creating and deleting durable queues are switched on as well:

/subsystem=messaging-activemq/server=default/security-setting=news.europe.#/role=admin:add(manage=true,create-durable-queue=true,delete-durable-queue=true)
{"outcome" => "success"}

To confirm the configuration of a security-setting, use the management CLI. Remember to use the recursive=true option to get the full display of permissions:

/subsystem=messaging-activemq/server=default:read-children-resources(child-type=security-setting,recursive=true)
{
    "outcome" => "success",
    "result" => {
        "#" => {"role" => {"guest" => {
            "consume" => true,
            "create-durable-queue" => false,
            "create-non-durable-queue" => true,
            "delete-durable-queue" => false,
            "delete-non-durable-queue" => true,
            "manage" => false,
            "send" => true
        }}},
        "news.europe.#" => {"role" => {
            "dev" => {
                "consume" => true,
                "create-durable-queue" => false,
                "create-non-durable-queue" => true,
                "delete-durable-queue" => false,
                "delete-non-durable-queue" => true,
                "manage" => false,
                "send" => true
            },
            "admin" => {
                "consume" => false,
                "create-durable-queue" => true,
                "create-non-durable-queue" => false,
                "delete-durable-queue" => true,
                "delete-non-durable-queue" => false,
                "manage" => true,
                "send" => false
            }
        }}
    }

Above, the permissions for addresses that start with string news.europe. are displayed in full by the management CLI. To summarize, only users who have the admin role can create or delete durable queues, while only users with the dev role can create or delete non-durable queues. Furthermore, users with the dev role can send or consume messages, but admin users cannot. They can, however, send management messages since their manage permission is set to true.

In cases where more than one match applies to a set of addresses the more specific match takes precedence. For example, the address news.europe.tech.uk.# is more specific than news.europe.tech.#. Because permissions are not inherited, you can effectively deny permissions in more specific security-setting blocks by simply not specifying them. Otherwise it would not be possible to deny permissions in sub-groups of addresses.

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

For more information on configuring the security manager, please see the JBoss EAP Security Architecture guide.

7.2.1.1. Granting Unauthenticated Clients the guest Role

If you want JBoss EAP to automatically grant unauthenticated clients the guest role make the following two changes:

  1. Add a new module-option to the other security domain. The new option, unauthenticatedIdentity, will tell JBoss EAP to grant guest access to unauthenticated clients. The recommended way to do this is by using the management CLI:

    /subsystem=security/security-domain=other/authentication=classic/login-module=RealmDirect:map-put(name=module-options,key=unauthenticatedIdentity,value=guest)
    {
       "outcome" => "success",
       "response-headers" => {
           "operation-requires-reload" => true,
           "process-state" => "reload-required"
       }
    }

    Note that the server requires a reload after issuing the command. You can confirm the new option by using the following management CLI command:

    /subsystem=security/security-domain=other/authentication=classic/login-module=RealmDirect:read-resource()
    {
        "outcome" => "success",
        "result" => {
            "code" => "RealmDirect",
            "flag" => "required",
            "module" => undefined,
            "module-options" => {
                "password-stacking" => "useFirstPass",
                "unauthenticatedIdentity" => "guest"
            }
        }
    }

    Also, your server configuration file should look something like this after the command executes:

    <subsystem xmlns="urn:jboss:domain:security:1.2">
      <security-domains>
        <security-domain name="other" cache-type="default">
           <authentication>
             ...
             <login-module code="RealmDirect" flag="required">
                ...
                <module-option name="unauthenticatedIdentity" value="guest"/>
                ...
             </login-module>
             ...
           </authentication>
        </security-domain>
      ...
      </security-domains>
    </subsystem>
  2. Uncomment the following line in the file application-roles.properties by deleting the # character. The file is located in EAP_HOME/standalone/configuration/ or EAP_HOME/domain/configuration/, depending on whether you are using standalone servers or a domain controller respectively.

    #guest=guest

Remote clients should now be able to access the server without needing to authenticate. They will be given the permissions associated with the guest role.