Security Guide
Making it safe for your systems to work together
Copyright © 2011-2017 Red Hat, Inc. and/or its affiliates.
Abstract
Chapter 1. Security Architecture
Abstract
1.1. OSGi Container Security
Overview
Figure 1.1. OSGi Container Security Architecture

JAAS realms
karaf realm
karaf realm. Red Hat JBoss Fuse uses the karaf realm to provide authentication for remote administration of the OSGi runtime, for the Fuse Management Console, and for JMX management. The karaf realm uses a simple file-based repository, where authentication data is stored in the InstallDir/etc/users.properties file.
karaf realm in your own applications. Simply configure karaf as the name of the JAAS realm that you want to use. Your application then performs authentication using the data from the users.properties file.
Console port
ssh:ssh command. The console port is secured by a JAAS login feature that connects to the karaf realm. Users that try to connect to the console port will be prompted to enter a username and password that must match one of the accounts from the karaf realm.
JMX port
karaf realm.
Application bundles and JAAS security
1.2. Apache Camel Security
Overview
Figure 1.2. Apache Camel Security Architecture

Alternatives for Apache Camel security
- Endpoint security—part (a) shows a message sent between two routes with secure endpoints. The producer endpoint on the left opens a secure connection (typically using SSL/TLS) to the consumer endpoint on the right. Both of the endpoints support security in this scenario.With endpoint security, it is typically possible to perform some form of peer authentication (and sometimes authorization).
- Payload security—part (b) shows a message sent between two routes where the endpoints are both insecure. To protect the message from unauthorized snooping in this case, use a payload processor that encrypts the message before sending and decrypts the message after it is received.A limitation of payload security is that it does not provide any kind of authentication or authorization mechanisms.
Endpoint security
- JMS and ActiveMQ—SSL/TLS security and JAAS security for client-to-broker and broker-to-broker communication.
- Jetty—HTTP Basic Authentication and SSL/TLS security.
- CXF—SSL/TLS security and WS-Security.
- Crypto—creates and verifies digital signatures in order to guarantee message integrity.
- Netty—SSL/TLS security.
- MINA—SSL/TLS security.
- Cometd—SSL/TLS security.
- glogin and gauth—authorization in the context of Google applications.
Payload security
marshal() and unmarshal() operations
XMLSecurity data format
Crypto data format
Chapter 2. Securing the Container
Abstract
2.1. JAAS Authentication
Abstract
2.1.1. Default JAAS Realm
Overview
Default JAAS realm
karaf realm, which is used by default to secure all aspects of the container.
How to integrate an application with JAAS
karaf realm in your own applications. Simply configure karaf as the name of the JAAS realm that you want to use.
Default JAAS login modules
karaf default realm. In this default configuration, the karaf realm deploys four JAAS login modules, which are enabled simultaneously. To see the deployed login modules, enter the jaas:realms console command, as follows:
JBossFuse:karaf@root> jaas:realms
Index Realm Module Class
1 karaf org.apache.karaf.jaas.modules.properties.PropertiesLoginModule
2 karaf org.apache.karaf.jaas.modules.publickey.PublickeyLoginModule
3 karaf org.apache.karaf.jaas.modules.audit.FileAuditLoginModule
4 karaf org.apache.karaf.jaas.modules.audit.EventAdminAuditLoginModuleFileAuditLoginModule login module and the EventAdminAuditLoginModule login module are used to record an audit trail of successful and failed login attempts. These login modules do not authenticate users.
Configuring users in the properties login module
InstallDir/etc/users.properties file using a text editor and add a line with the following syntax:
Username=Password[,UserGroup|Role][,UserGroup|Role]...
jdoe user with password, topsecret, and role, Administrator, you could create an entry like the following:
jdoe=topsecret,Administrator
Administrator role gives full administrative privileges to the jdoe user.
Configuring user groups in the properties login module
InstallDir/etc/users.properties file using a text editor and add a line with the following syntax:
_g_\:GroupName=Role1,Role2,...
admingroup user group with the roles, SuperUser and Administrator, you could create an entry like the following:
_g_\:admingroup=SuperUser,Administrator
majorclanger user to the admingroup, by creating the following user entry:
majorclanger=secretpass,_g_:admingroup
Configuring the public key login module
InstallDir/etc/keys.properties file using a text editor and add a line with the following syntax:
Username=PublicKey[,UserGroup|Role][,UserGroup|Role]...
jdoe user with the Administrator role by adding the following entry to the InstallDir/etc/keys.properties file (on a single line):
jdoe=AAAAB3NzaC1kc3MAAACBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7
gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnfqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAAAAFQCX
YFCPFSMLzLKSuYKi64QL8Fgc9QAAAnEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6Ewo
FhO3zwkyjMim4TwWeotifI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoAAACB
AKKSU2PFl/qOLxIwmBZPPIcJshVe7bVUpFvyl3BbJDow8rXfskl8wO63OzP/qLmcJM0+JbcRU/53Jj7uyk31drV2qxhIOsLDC9dGCWj4
7Y7TyhPdXh/0dthTRBy6bqGtRPxGa7gJov1xm/UuYYXPIUR/3x9MAZvZ5xvE0kYXO+rx,Administratorid_rsa.pub file here. Insert just the block of symbols which represents the public key itself.
Configuring user groups in the public key login module
InstallDir/etc/keys.properties file using a text editor and add a line with the following syntax:
_g_\:GroupName=Role1,Role2,...
admingroup user group with the roles, SuperUser and Administrator, you could create an entry like the following:
_g_\:admingroup=SuperUser,Administrator
jdoe user to the admingroup, by creating the following user entry:
jdoe=AAAAB3NzaC1kc3MAAACBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7
gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnfqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAAAAFQCX
YFCPFSMLzLKSuYKi64QL8Fgc9QAAAnEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6Ewo
FhO3zwkyjMim4TwWeotifI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoAAACB
AKKSU2PFl/qOLxIwmBZPPIcJshVe7bVUpFvyl3BbJDow8rXfskl8wO63OzP/qLmcJM0+JbcRU/53Jj7uyk31drV2qxhIOsLDC9dGCWj4
7Y7TyhPdXh/0dthTRBy6bqGtRPxGa7gJov1xm/UuYYXPIUR/3x9MAZvZ5xvE0kYXO+rx,_g_:admingroupEncrypting the stored passwords
InstallDir/etc/users.properties file in plaintext format. To protect the passwords in this file, you must set the file permissions of the users.properties file so that it can be read only by administrators. To provide additional protection, you can optionally encrypt the stored passwords using a message digest algorithm.
InstallDir/etc/org.apache.karaf.jaas.cfg file and set the encryption properties as described in the comments. For example, the following settings would enable basic encryption using the MD5 message digest algorithm:
encryption.enabled = true
encryption.name = basic
encryption.prefix = {CRYPT}
encryption.suffix = {CRYPT}
encryption.algorithm = MD5
encryption.encoding = hexadecimalorg.apache.karaf.jaas.cfg file are applied only to the default karaf realm in a standalone container. The have no effect on a Fabric container and no effect on a custom realm.
Overriding the default realm
karaf realm by defining a higher ranking karaf realm. This ensures that all of the Red Hat JBoss Fuse security components switch to use your custom realm. For details of how to define and deploy custom JAAS realms, see Section 2.1.2, “Defining JAAS Realms”.
2.1.2. Defining JAAS Realms
Overview
jaas:config element for defining JAAS realms in a blueprint configuration file. The JAAS realms defined in this way are made available to all of the application bundles deployed in the container, making it possible to share the JAAS security infrastructure across the whole container.
Namespace
jaas:config element is defined in the http://karaf.apache.org/xmlns/jaas/v1.0.0 namespace. When defining a JAAS realm you will need to include the line shown in Example 2.1, “JAAS Blueprint Namespace”.
Example 2.1. JAAS Blueprint Namespace
xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"
Configuring a JAAS realm
jaas:config element is shown in Example 2.2, “Defining a JAAS Realm in Blueprint XML”.
Example 2.2. Defining a JAAS Realm in Blueprint XML
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0">
<jaas:config name="JaasRealmName"
[rank="IntegerRank"]>
<jaas:module className="LoginModuleClassName"
[flags="[required|requisite|sufficient|optional]"]>
Property=Value
...
</jaas:module>
...
<!-- Can optionally define multiple modules -->
...
</jaas:config>
</blueprint>jaas:config- Defines the JAAS realm. It has the following attributes:
name—specifies the name of the JAAS realm.rank—specifies an optional rank for resolving naming conflicts between JAAS realms . When two or more JAAS realms are registered under the same name, the OSGi container always picks the realm instance with the highest rank. If you decide to override the default realm,karaf, you should specify arankof100or more, so that it overrides all of the previously installedkarafrealms (in the context of Fabric, you need to override the defaultZookeeperLoginModule, which has a rank of99).
jaas:module- Defines a JAAS login module in the current realm.
jaas:modulehas the following attributes:className—the fully-qualified class name of a JAAS login module. The specified class must be available from the bundle classloader.flags—determines what happens upon success or failure of the login operation. Table 2.1, “Flags for Defining a JAAS Module” describes the valid values.Table 2.1. Flags for Defining a JAAS Module
Value Description requiredAuthentication of this login module must succeed. Always proceed to the next login module in this entry, irrespective of success or failure. requisiteAuthentication of this login module must succeed. If success, proceed to the next login module; if failure, return immediately without processing the remaining login modules. sufficientAuthentication of this login module is not required to succeed. If success, return immediately without processing the remaining login modules; if failure, proceed to the next login module. optionalAuthentication of this login module is not required to succeed. Always proceed to the next login module in this entry, irrespective of success or failure.
The contents of ajaas:moduleelement is a space separated list of property settings, which are used to initialize the JAAS login module instance. The specific properties are determined by the JAAS login module and must be put into the proper format.NoteYou can define multiple login modules in a realm.
Converting standard JAAS login properties to XML
PropertiesLogin realm using the Red Hat JBoss Fuse properties login module class, PropertiesLoginModule:
Example 2.3. Standard JAAS Properties
PropertiesLogin {
org.apache.activemq.jaas.PropertiesLoginModule required
org.apache.activemq.jaas.properties.user="users.properties"
org.apache.activemq.jaas.properties.group="groups.properties";
};jaas:config element in a blueprint file, is shown in Example 2.4, “Blueprint JAAS Properties”.
Example 2.4. Blueprint JAAS Properties
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
<jaas:config name="PropertiesLogin">
<jaas:module flags="required"
className="org.apache.activemq.jaas.PropertiesLoginModule">
org.apache.activemq.jaas.properties.user=users.properties
org.apache.activemq.jaas.properties.group=groups.properties
</jaas:module>
</jaas:config>
</blueprint>Example
LDAPLogin realm to use Red Hat JBoss Fuse's LDAPLoginModule class, which connects to the LDAP server located at ldap://localhost:10389.
Example 2.5. Configuring a JAAS Realm
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
<jaas:config name="LDAPLogin" rank="200">
<jaas:module flags="required"
className="org.apache.karaf.jaas.modules.ldap.LDAPLoginModule">
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
connection.username=uid=admin,ou=system
connection.password=secret
connection.protocol=
connection.url = ldap://localhost:10389
user.base.dn = ou=users,ou=system
user.filter = (uid=%u)
user.search.subtree = true
role.base.dn = ou=users,ou=system
role.filter = (uid=%u)
role.name.attribute = ou
role.search.subtree = true
authentication = simple
</jaas:module>
</jaas:config>
</blueprint>2.1.3. JAAS Properties Login Module
Overview
jaas:* console commands.
InstallDir/etc/users.properties file.
Supported credentials
Implementation classes
org.apache.karaf.jaas.modules.properties.PropertiesLoginModule- Implements the JAAS login module.
org.apache.karaf.jaas.modules.properties.PropertiesBackingEngineFactory- Must be exposed as an OSGi service. This service makes it possible for you to manage the user data using the
jaas:*console commands from the Apache Karaf shell (see chapter "JAAS Console Commands" in "Console Reference").
Options
users- Location of the user properties file.
Format of the user properties file
Username=Password[,UserGroup|Role][,UserGroup|Role]...
_g_\:GroupName=Role1[,Role2]...
bigcheese and guest, and the user groups, admingroup and guestgroup, as follows:
# Users bigcheese=cheesepass,_g_:admingroup guest=guestpass,_g_:guestgroup # Groups _g_\:admingroup=SuperUser,Administrator _g_\:guestgroup=Monitor
Sample Blueprint configuration
karaf realm using the properties login module, where the default karaf realm is overridden by setting the rank attribute to 200:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
<type-converters>
<bean class="org.apache.karaf.jaas.modules.properties.PropertiesConverter"/>
</type-converters>
<!--Allow usage of System properties, especially the karaf.base property-->
<ext:property-placeholder
placeholder-prefix="$[" placeholder-suffix="]"/>
<jaas:config name="karaf" rank="200">
<jaas:module flags="required"
className="org.apache.karaf.jaas.modules.properties.PropertiesLoginModule">
users= $[karaf.base]/etc/users.properties
</jaas:module>
</jaas:config>
<!-- The Backing Engine Factory Service for the PropertiesLoginModule -->
<service interface="org.apache.karaf.jaas.modules.BackingEngineFactory">
<bean class="org.apache.karaf.jaas.modules.properties.PropertiesBackingEngineFactory"/>
</service>
</blueprint>BackingEngineFactory bean as an OSGi service, so that the jaas:* console commands can manage the user data.
2.1.4. JAAS OSGi Config Login Module
Overview
etc/PersistentID.cfg or using any method of configuration that is supported by the OSGi Config Admin Service. The jaas:* console commands are not supported, however.
Supported credentials
Implementation classes
org.apache.karaf.jaas.modules.osgi.OsgiConfigLoginModule- Implements the JAAS login module.
jaas:* console commands.
Options
pid- The persistent ID of the OSGi configuration containing the user data. In the OSGi Config Admin standard, a persistent ID references a set of related configuration properties.
Location of the configuration file
PersistentID, is stored in the following file:
InstallDir/etc/PersistentID.cfg
Format of the configuration file
PersistentID.cfg configuration file is used to store username, password, and role data for the OSGi config login module. Each user is represented by a single line in the configuration file, where a line has the following form:
Username=Password[,Role][,Role]...
Sample Blueprint configuration
karaf realm using the OSGi config login module, where the default karaf realm is overridden by setting the rank attribute to 200:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
<jaas:config name="karaf" rank="200">
<jaas:module flags="required"
className="org.apache.karaf.jaas.modules.osgi.OsgiConfigLoginModule">
pid = org.jboss.example.osgiconfigloginmodule
</jaas:module>
</jaas:config>
</blueprint>InstallDir/etc/org.jboss.example.osgiconfigloginmodule.cfg, and it is not possible to edit the configuration using the jaas:* console commands.
2.1.5. JAAS Public Key Login Module
Overview
jaas:* console commands are not supported, however.
InstallDir/etc/keys.properties file.
Supported credentials
Implementation classes
org.apache.karaf.jaas.modules.publickey.PublickeyLoginModule- Implements the JAAS login module.
jaas:* console commands.
Options
users- Location of the user properties file for the public key login module.
Format of the keys properties file
keys.properties file is used to store username, public key, and role data for the public key login module. Each user is represented by a single line in the keys properties file, where a line has the following form:
Username=PublicKey[,UserGroup|Role][,UserGroup|Role]...
~/.ssh/id_rsa.pub in a UNIX system).
jdoe with the Administrator role, you would create an entry like the following:
jdoe=AAAAB3NzaC1kc3MAAACBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7
gB00b/JmYLdrmVClpJ+f6AR7ECLCT7up1/63xhv4O1fnfqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iIDGZ3RSAHHAAAAFQCX
YFCPFSMLzLKSuYKi64QL8Fgc9QAAAnEA9+GghdabPd7LvKtcNrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6Ewo
FhO3zwkyjMim4TwWeotifI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6Ae1UlZAFMO/7PSSoAAACB
AKKSU2PFl/qOLxIwmBZPPIcJshVe7bVUpFvyl3BbJDow8rXfskl8wO63OzP/qLmcJM0+JbcRU/53Jj7uyk31drV2qxhIOsLDC9dGCWj4
7Y7TyhPdXh/0dthTRBy6bqGtRPxGa7gJov1xm/UuYYXPIUR/3x9MAZvZ5xvE0kYXO+rx,Administratorid_rsa.pub file here. Insert just the block of symbols which represents the public key itself.
_g_\:GroupName=Role1[,Role2]...
Sample Blueprint configuration
karaf realm using the public key login module, where the default karaf realm is overridden by setting the rank attribute to 200:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
<!--Allow usage of System properties, especially the karaf.base property-->
<ext:property-placeholder
placeholder-prefix="$[" placeholder-suffix="]"/>
<jaas:config name="karaf" rank="200">
<jaas:module flags="required"
className="org.apache.karaf.jaas.modules.publickey.PublickeyLoginModule">
users = $[karaf.base]/etc/keys.properties
</jaas:module>
</jaas:config>
</blueprint>InstallDir/etc/keys.properties, and it is not possible to edit the configuration using the jaas:* console commands.
2.1.6. JAAS JDBC Login Module
Overview
jaas:* console commands (where the backing engine uses configured SQL queries to perform the relevant database updates).
PropertiesLoginModule with JDBCLoginModule to ensure access to the system.
Supported credentials
Implementation classes
org.apache.karaf.jaas.modules.jdbc.JDBCLoginModule- Implements the JAAS login module.
org.apache.karaf.jaas.modules.jdbc.JDBCBackingEngineFactory- Must be exposed as an OSGi service. This service makes it possible for you to manage the user data using the
jaas:*console commands from the Apache Karaf shell (see chapter "JAAS Console Commands" in "Console Reference").
Options
- datasource
- The JDBC data source, specified either as an OSGi service or as a JNDI name. You can specify a data source's OSGi service using the following syntax:
osgi:ServiceInterfaceName[/ServicePropertiesFilter]
The ServiceInterfaceName is the interface or class that is exported by the data source's OSGi service (usuallyjavax.sql.DataSource).Because multiple data sources can be exported as OSGi services in a container, it is usually necessary to specify a filter, ServicePropertiesFilter, to select the particular data source that you want. Filters on OSGi services are applied to the service property settings and follow a syntax that is borrowed from LDAP filter syntax. - query.password
- The SQL query that retrieves the user's password. The query can contain a single question mark character,
?, which is substituted by the username at run time. - query.role
- The SQL query that retrieves the user's roles. The query can contain a single question mark character,
?, which is substituted by the username at run time. - insert.user
- The SQL query that creates a new user entry. The query can contain two question marks,
?, characters: the first question mark is substituted by the username and the second question mark is substituted by the password at run time. - insert.role
- The SQL query that adds a role to a user entry. The query can contain two question marks,
?, characters: the first question mark is substituted by the username and the second question mark is substituted by the role at run time. - delete.user
- The SQL query that deletes a user entry. The query can contain a single question mark character,
?, which is substituted by the username at run time. - delete.role
- The SQL query that deletes a role from a user entry. The query can contain two question marks,
?, characters: the first question mark is substituted by the username and the second question mark is substituted by the role at run time. - delete.roles
- The SQL query that deletes multiple roles from a user entry. The query can contain a single question mark character,
?, which is substituted by the username at run time.
Example of setting up a JDBC login module
Create the database tables
users table and roles table:
CREATE TABLE users ( username VARCHAR(255) NOT NULL, password VARCHAR(255) NOT NULL, PRIMARY KEY (username) ); CREATE TABLE roles ( username VARCHAR(255) NOT NULL, role VARCHAR(255) NOT NULL, PRIMARY KEY (username,role) );
users table stores username/password data and the roles table associates a username with one or more roles.
Create the data source
javax.sql.DataSource type) using code like the following in a Blueprint file:
<blueprint xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="mysqlDatasource"
class="com.mysql.jdbc.jdbc2.optional.MysqlDataSource">
<property name="serverName" value="localhost"></property>
<property name="databaseName" value="DBName"></property>
<property name="port" value="3306"></property>
<property name="user" value="DBUser"></property>
<property name="password" value="DBPassword"></property>
</bean>
<service id="mysqlDS" interface="javax.sql.DataSource"
ref="mysqlDatasource">
<service-properties>
<entry key="osgi.jndi.service.name" value="jdbc/karafdb"/>
</service-properties>
</service>
</blueprint>Specify the data source as an OSGi service
datasource option of the JDBC login module can reference the data source's OSGi service using the following syntax:
osgi:javax.sql.DataSource/(osgi.jndi.service.name=jdbc/karafdb)
javax.sql.DataSource is the interface type of the exported OSGi service and the filter, (osgi.jndi.service.name=jdbc/karafdb), selects the particular javax.sql.DataSource instance whose osgi.jndi.service.name service property has the value, jdbc/karafdb.
karaf realm with a JDBC login module that references the sample MySQL data source:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
<!--Allow usage of System properties, especially the karaf.base property-->
<ext:property-placeholder
placeholder-prefix="$[" placeholder-suffix="]"/>
<jaas:config name="karaf" rank="200">
<jaas:module flags="required"
className="org.apache.karaf.jaas.modules.jdbc.JDBCLoginModule">
datasource = osgi:javax.sql.DataSource/(osgi.jndi.service.name=jdbc/karafdb)
query.password = SELECT password FROM users WHERE username=?
query.role = SELECT role FROM roles WHERE username=?
insert.user = INSERT INTO users VALUES(?,?)
insert.role = INSERT INTO roles VALUES(?,?)
delete.user = DELETE FROM users WHERE username=?
delete.role = DELETE FROM roles WHERE username=? AND role=?
delete.roles = DELETE FROM roles WHERE username=?
</jaas:module>
</jaas:config>
<!-- The Backing Engine Factory Service for the JDBCLoginModule -->
<service interface="org.apache.karaf.jaas.modules.BackingEngineFactory">
<bean class="org.apache.karaf.jaas.modules.jdbc.JDBCBackingEngineFactory"/>
</service>
</blueprint>JDBCBackingEngineFactory instance, which enables you to manage the user data using the jaas:* console commands.
2.1.7. JAAS LDAP Login Module
Overview
jaas:* console commands are not supported.
Supported credentials
Implementation classes
org.apache.karaf.jaas.modules.ldap.LDAPLoginModule- Implements the JAAS login module. It is preloaded in the container, so you do not need to install its bundle.
jaas:* console commands.
Options
authentication- Specifies the authentication method used when binding to the LDAP server. Valid values are
simple—bind with user name and password authentication, requiring you to set theconnection.usernameandconnection.passwordproperties.none—bind anonymously. In this case theconnection.usernameandconnection.passwordproperties can be left unassigned.
NoteThe connection to the directory server is used only for performing searches. In this case, an anonymous bind is often preferred, because it is faster than an authenticated bind (but you would also need to ensure that the directory server is sufficiently protected, for example by deploying it behind a firewall). connection.url- Specifies specify the location of the directory server using an ldap URL, ldap://Host:Port. You can optionally qualify this URL, by adding a forward slash,
/, followed by the DN of a particular node in the directory tree. To enable SSL security on the connection, you need to specify theldaps:scheme in the URL—for example, ldaps://Host:Port. You can also specify multiple URLs, as a space-separated list, for example:connection.url=ldap://10.0.0.153:2389 ldap://10.10.178.20:389
connection.username- Specifies the DN of the user that opens the connection to the directory server. For example,
uid=admin,ou=system. connection.password- Specifies the password that matches the DN from connection.username. In the directory server, the password is normally stored as a
userPasswordattribute in the corresponding directory entry. context.com.sun.jndi.ldap.connect.pool- If
true, enables connection pooling for LDAP connections. Default isfalse. context.com.sun.jndi.ldap.connect.timeout- Specifies the timeout for creating a TCP connection to the LDAP server, in units of milliseconds. We recommend that you set this property explicitly, because the default value is infinite, which can result in a hung connection attempt.
context.com.sun.jndi.ldap.read.timeout- Specifies the read timeout for an LDAP operation, in units of milliseconds. We recommend that you set this property explicitly, because the default value is infinite.
context.java.naming.referral- An LDAP referral is a form of indirection supported by some LDAP servers. The LDAP referral is an entry in the LDAP server which contains one or more URLs (usually referencing a node or nodes in another LDAP server). The
context.java.naming.referralproperty can be used to enable or disable referral following. It can be set to one of the following values:followto follow the referrals (assuming it is supported by the LDAP server),ignoreto silently ignore all referrals,throwto throw aPartialResultExceptionwhenever a referral is encountered.
disableCache- The user and role caches can be disabled by setting this property to
true. Default isfalse. initial.context.factory- Specifies the class of the context factory used to connect to the LDAP server. This must always be set to
com.sun.jndi.ldap.LdapCtxFactory. role.base.dn- Specifies the DN of the subtree of the DIT to search for role entries. For example,
ou=groups,ou=system. role.filter- Specifies the LDAP search filter used to locate roles. It is applied to the subtree selected by
role.base.dn. For example,(member=uid=%u). Before being passed to the LDAP search operation, the value is subjected to string substitution, as follows:%uis replaced by the user name extracted from the incoming credentials, and%dnis replaced by the RDN of the corresponding user in the LDAP server (which was found by matching against theuser.filterfilter).%fqdnis replaced by the DN of the corresponding user in the LDAP server (which was found by matching against theuser.filterfilter).
role.mapping- Specifies the mapping between LDAP groups and JAAS roles. If no mapping is specified, the default mapping is for each LDAP group to map to the corresponding JAAS role of the same name. The role mapping is specified with the following syntax:
ldap-group=jaas-role(,jaas-role)*(;ldap-group=jaas-role(,jaas-role)*)*
Where each LDAP group,ldap-group, is specified by its Common Name (CN). Note that therole.mappingoption must be set to a non-empty value.For example, given the LDAP groups,admin,devop, andtester, you could map them to JAAS roles, as follows:role.mapping=admin=Administrator;devop=Administrator,Deployer;tester=Monitor
Since JBoss Fuse 6.3.0 R4, it is also possible to specify an LDAP group using its full Distinguished Name (DN). For example:role.mapping=cn=admin,ou=groups,dc=example,dc=org=Administrator;cn=admin,ou=otherGroups,dc=example,dc=org=Administrator,Deployer
role.name.attribute- Specifies the attribute type of the role entry that contains the name of the role/group. If you omit this option, the role search feature is effectively disabled. For example,
cn. role.search.subtree- Specifies whether the role entry search scope includes the subtrees of the tree selected by
role.base.dn. Iftrue, the role lookup is recursive (SUBTREE). Iffalse, the role lookup is performed only at the first level (ONELEVEL). ssl- Specifies whether the connection to the LDAP server is secured using SSL. If connection.url starts with ldaps:// SSL is used regardless of this property.
ssl.provider- Specifies the SSL provider to use for the LDAP connection. If not specified, the default SSL provider is used.
ssl.protocol- Specifies the protocol to use for the SSL connection. You must set this property to
TLSv1, in order to prevent the SSLv3 protocol from being used (POODLE vulnerability). ssl.algorithm- Specifies the algorithm used by the trust store manager. For example,
PKIX. ssl.keystore- The ID of the keystore that stores the LDAP client's own X.509 certificate (required only if SSL client authentication is enabled on the LDAP server). The keystore must be deployed using a
jaas:keystoreelement (see the section called “Sample configuration for Apache DS”). ssl.keyalias- The keystore alias of the LDAP client's own X.509 certificate (required only if there is more than one certificate stored in the keystore specified by
ssl.keystore). ssl.truststore- The ID of the keystore that stores trusted CA certificates, which are used to verify the LDAP server's certificate (the LDAP server's certificate chain must be signed by one of the certificates in the truststore). The keystore must be deployed using a
jaas:keystoreelement. user.base.dn- Specifies the DN of the subtree of the DIT to search for user entries. For example,
ou=users,ou=system. user.filter- Specifies the LDAP search filter used to locate user credentials. It is applied to the subtree selected by
user.base.dn. For example,(uid=%u). Before being passed to the LDAP search operation, the value is subjected to string substitution, as follows:%uis replaced by the user name extracted from the incoming credentials.
user.search.subtree- Specifies whether the user entry search scope includes the subtrees of the tree selected by
user.base.dn. Iftrue, the user lookup is recursive (SUBTREE). Iffalse, the user lookup is performed only at the first level (ONELEVEL).
Sample configuration for Apache DS
karaf realm using the LDAP login module, where the default karaf realm is overridden by setting the rank attribute to 200, and the LDAP login module connects to an Apache Directory Server:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
<jaas:config name="karaf" rank="100">
<jaas:module className="org.apache.karaf.jaas.modules.ldap.LDAPLoginModule" flags="sufficient">
debug=true
<!-- LDAP Configuration -->
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
<!-- multiple LDAP servers can be specified as a space separated list of URLs -->
connection.url=ldap://10.0.0.153:2389 ldap://10.10.178.20:389
<!-- authentication=none -->
authentication=simple
connection.username=cn=Directory Manager
connection.password=directory
<!-- User Info -->
user.base.dn=dc=redhat,dc=com
user.filter=(&(objectClass=InetOrgPerson)(uid=%u))
user.search.subtree=true
<!-- Role/Group Info-->
role.base.dn=dc=redhat,dc=com
role.name.attribute=cn
<!--
The 'dc=redhat,dc=com' used in the role.filter
below is the user.base.dn.
-->
<!-- role.filter=(uniquemember=%dn,dc=redhat,dc=com) -->
role.filter=(&(objectClass=GroupOfUniqueNames)(UniqueMember=%fqdn))
role.search.subtree=true
<!-- role mappings - a ';' separated list -->
role.mapping=JBossAdmin=admin;JBossMonitor=Monitor,viewer
<!-- LDAP context properties -->
context.com.sun.jndi.ldap.connect.timeout=5000
context.com.sun.jndi.ldap.read.timeout=5000
<!-- LDAP connection pooling -->
<!-- http://docs.oracle.com/javase/jndi/tutorial/ldap/connect/pool.html -->
<!-- http://docs.oracle.com/javase/jndi/tutorial/ldap/connect/config.html -->
context.com.sun.jndi.ldap.connect.pool=true
<!-- How are LDAP referrals handled?
Can be `follow`, `ignore` or `throw`. Configuring `follow` may not work on all LDAP servers, `ignore` will
silently ignore all referrals, while `throw` will throw a partial results exception if there is a referral.
-->
context.java.naming.referral=ignore
<!-- SSL configuration -->
ssl=false
ssl.protocol=SSL
<!-- matches the keystore/truststore configured below -->
ssl.truststore=ks
ssl.algorithm=PKIX
<!-- The User and Role caches can be disabled - 6.3.0 179 and later -->
disableCache=true
</jaas:module>
</jaas:config>
<!-- Location of the SSL truststore/keystore
<jaas:keystore name="ks" path="file:///${karaf.home}/etc/ldap.truststore" keystorePassword="XXXXXX" />
-->
</blueprint>ldaps scheme in the connection.url setting.
ssl.protocol to TLSv1, in order to protect against the Poodle vulnerability (CVE-2014-3566)
Filter settings for different directory servers
| Directory Server | Typical Filter Settings |
|---|---|
|
389-DS
Red Hat DS
|
user.filter=(&(objectClass=InetOrgPerson)(uid=%u)) role.filter=(uniquemember=%fqdn) |
|
MS Active Directory
|
user.filter=(&(objectCategory=person)(samAccountName=%u)) role.filter=(uniquemember=%fqdn) |
|
Apache DS
|
user.filter=(uid=%u) role.filter=(member=uid=%u) |
|
OpenLDAP
|
user.filter=(uid=%u) role.filter=(member:=uid=%u) |
& symbol (representing the logical And operator) is escaped as & because the option settings will be embedded in a Blueprint XML file.
2.1.8. Encrypting Stored Passwords
Overview
Options
/etc/org.apache.karaf.jaas.cfg file or deploy your own blueprint file as described in the section called “Example of a login module with Jasypt encryption”.
encryption.enabled- Set to
true, to enable password encryption. encryption.name- Name of the encryption service, which has been registered as an OSGi service.
encryption.prefix- Prefix for encrypted passwords.
encryption.suffix- Suffix for encrypted passwords.
encryption.algorithm- Specifies the name of the encryption algorithm—for example,
MD5orSHA-1. You can specify one of the following encryption algorithms:MD2MD5SHA-1SHA-256SHA-384SHA-512
encryption.encoding- Encrypted passwords encoding:
hexadecimalorbase64. encryption.providerName(Jasypt only)- Name of the
java.security.Providerinstance that is to provide the digest algorithm. encryption.providerClassName(Jasypt only)- Class name of the security provider that is to provide the digest algorithm
encryption.iterations(Jasypt only)- Number of times to apply the hash function recursively.
encryption.saltSizeBytes(Jasypt only)- Size of the salt used to compute the digest.
encryption.saltGeneratorClassName(Jasypt only)- Class name of the salt generator.
role.policy- Specifies the policy for identifying role principals. Can have the values,
prefixorgroup. role.discriminator- Specifies the discriminator value to be used by the role policy.
Encryption services
encryption.name = basic, described in the section called “Basic encryption service”,encryption.name = jasypt, described in the section called “Jasypt encryption”.
- implement interface
org.apache.karaf.jaas.modules.EncryptionService - and expose your implementation as OSGI service.
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<service interface="org.apache.karaf.jaas.modules.EncryptionService">
<service-properties>
<entry key="name" value="jasypt" />
</service-properties>
<bean class="org.apache.karaf.jaas.jasypt.impl.JasyptEncryptionService"/>
</service>
...
</blueprint>
Basic encryption service
encryption.name property to the value, basic. In the basic encryption service, the message digest algorithms are provided by the SUN security provider (the default security provider in the Oracle JDK).
Jasypt encryption
jasypt-encryption feature, using the following console command:
JBossA-MQ:karaf@root> features:install jasypt-encryption
encryption.name property to the value, jasypt.
Example of a login module with Jasypt encryption
jasypt-encryption feature, you could deploy a properties login module with Jasypt encryption using the following Blueprint configuration:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
<type-converters>
<bean class="org.apache.karaf.jaas.modules.properties.PropertiesConverter"/>
</type-converters>
<!--Allow usage of System properties, especially the karaf.base property-->
<ext:property-placeholder
placeholder-prefix="$[" placeholder-suffix="]"/>
<jaas:config name="karaf" rank="200">
<jaas:module flags="required"
className="org.apache.karaf.jaas.modules.properties.PropertiesLoginModule">
users = $[karaf.base]/etc/users.properties
encryption.enabled = true
encryption.name = jasypt
encryption.algorithm = SHA-256
encryption.encoding = base64
encryption.iterations = 100000
encryption.saltSizeBytes = 16
</jaas:module>
</jaas:config>
<!-- The Backing Engine Factory Service for the PropertiesLoginModule -->
<service interface="org.apache.karaf.jaas.modules.BackingEngineFactory">
<bean class="org.apache.karaf.jaas.modules.properties.PropertiesBackingEngineFactory"/>
</service>
<!-- Enable automatic encryption of all user passwords
in InstallDir/etc/users.properties file.
No login required to activate.
Encrypted passwords appear in the
InstallDir/etc/users.properties file as values enclosed
by {CRYPT}...{CRYPT} prefix/suffix pairs -->
<bean init-method="init" destroy-method="destroy"
class="org.apache.karaf.jaas.modules.properties.AutoEncryptionSupport">
<argument>
<map>
<entry key="org.osgi.framework.BundleContext"
value-ref="blueprintBundleContext"/>
<entry key="users" value="$[karaf.base]/etc/users.properties"/>
<entry key="encryption.name" value="jasypt"/>
<entry key="encryption.enabled" value="true"/>
<entry key="encryption.prefix" value="{CRYPT}"/>
<entry key="encryption.suffix" value="{CRYPT}"/>
<entry key="encryption.algorithm" value="SHA-256"/>
<entry key="encryption.encoding" value="base64"/>
<entry key="encryption.iterations" value="100000"/>
<entry key="encryption.saltSizeBytes" value="16"/>
</map>
</argument>
</bean>
</blueprint>2.2. Role-Based Access Control
Abstract
Deployer or Administrator) to a user's credentials. For more advanced usage, you have the option of customizing the access control lists, in order to control exactly what each role can do. Finally, you have the option of applying custom ACLs to your own OSGi services.
2.2.1. Overview of Role-Based Access Control
Overview
etc/users.properties file). You also have the option of customizing access control, by editing the relevant Access Control List (ACL) files.
Mechanisms
- JMX Guard
- The JBoss Fuse container is configured with a JMX guard, which intercepts every incoming JMX invocation and filters the invocation through the configured JMX access control lists. The JMX guard is configured at the JVM level, so it intercepts every JMX invocation, without exception.
- OSGi Service Guard
- For any OSGi service, it is possible to configure an OSGi service guard. The OSGi service guard is implemented as a proxy object, which interposes itself between the client and the original OSGi service. An OSGi service guard must be explicitly configured for each OSGi service: it is not installed by default (except for the OSGi services that represent Karaf console commands, which are preconfigured for you).
Types of protection
- Fuse Management Console (Hawtio)
- Container access through the Fuse Management Console (Hawtio) is controlled by the JMX ACL files. The REST/HTTP service that provides the Fuse Management Console is implemented using Jolokia technology, which is layered above JMX. Hence, ultimately, all Fuse Management Console invocations pass through JMX and are regulated by JMX ACLs.
- JMX
- Direct access to the container's JMX port is regulated by the JMX ACLs. Moreover, any additional JMX ports opened by an application running in the container would also be regulated by the JMX ACLs, because the JMX guard is set at the JVM level.
- Karaf command console
- Access to the Karaf command console is regulated by the command console ACL files. Access control is applied no matter how the Karaf console is accessed. Whether accessing the command console through the Fuse Management Console or through the SSH protocol, access control is applied in both cases.NoteIn the special case where you start up the container directly at the command line (for example, using the
./bin/fusescript) and no user authentication is performed, you automatically get the roles specified by thekaraf.local.rolesproperty in theetc/system.propertiesfile. - OSGi services
- For any OSGi service deployed in the container, you can optionally enable an ACL file, which restricts method invocations to specific roles.
Adding roles to users
etc/users.properties file defines the admin user and grants the Administrator and SuperUser roles.
admin = secretpass,Administrator,SuperUser
admingroup user group as follows:
admin = secretpass, _g_:admingroup _g_\:admingroup = Administrator, SuperUser
Standard roles
Table 2.2. Standard Roles for Access Control
| Roles | Description |
|---|---|
Monitor, Operator, Maintainer | Grants read-only access to the container. |
Deployer, Auditor | Grants read-write access at the appropriate level for ordinary users, who want to deploy and run applications. But blocks access to sensitive container configuration settings. |
Administrator, SuperUser | Grants unrestricted access to the container. |
ACL files
etc/auth/ directory of the JBoss Fuse installation, as follows:
etc/auth/jmx.acl[.*].cfg- JMX ACL files.
etc/auth/org.apache.karaf.command.acl.*.cfg- Command console ACL files.
Customizing role-based access control
etc/auth/ directory of the JBoss Fuse installation. For more information see Customizing the JMX ACLs and Customizing the Command Console ACLs
Customizing ACLs in a fabric environment
/etc/auth are over-written by the content stored in profiles. Hence, to assign custom roles in a fabric environment, you can add ACL assignments to the acl profile or jboss-fuse-full profile. For example,
fabric:profile-edit --pid org.apache.karaf.command.acl.fabric/container-start="Deployer, Auditor, Administrator, SuperUser, admin, MyCustomRoleForStartingContainer" acls
Additional properties for controlling access
system.properties file under the etc directory provides the following additional properties for controlling access through the Karaf command console and the Fuse Management Console (Hawtio):
karaf.local.roles- Specifies the roles that apply when a user starts up the container console locally (for example, by running the
./bin/fusescript). hawtio.roles- Specifies the roles that are allowed to access the container through the Fuse Management Console. This constraint is applied in addition to the access control defined by the JMX ACL files.
karaf.secured.command.compulsory.roles- Specifies the default roles required to invoke a Karaf console command, in case the console command is not configured explicitly by a command ACL file,
etc/auth/org.apache.karaf.command.acl.*.cfg. A user must be configured with at least one of the roles from the list in order to invoke the command. The value is specified as a comma-separated list of roles.
2.2.2. Customizing the JMX ACLs
Overview
etc/auth/jmx.acl.*.cfg. This section explains how you can customize the JMX ACLs by editing these files yourself.
Architecture
Figure 2.1. Access Control Mechanism for JMX

How it works
MBeanServerBuilder object. The Apache Karaf launching scripts have been modified to include the following setting:
-Djavax.management.builder.initial=org.apache.karaf.management.boot.KarafMBeanServerBuilder
- For every non-local JMX invocation, the JVM-wide
MBeanServerBuildercalls into an OSGi bundle that contains the JMX Guard. - The JMX Guard looks up the relevant ACL for the MBean the user is trying to access (where the ACLs are stored in the OSGi Config Admin service).
- The ACL returns the list of roles that are allowed to make this particular invocation on the MBean.
- The JMX Guard checks the list of roles against the current security subject (the user that is making the JMX invocation), to see whether the current user has any of the required roles.
- If no matching role is found, the JMX invocation is blocked and a
java.lang.SecurityExceptionis raised.
Location of JMX ACL files
InstallDir/etc/auth directory, where the ACL file names obey the following convention:
etc/auth/jmx.acl[.*].cfg
jmx.acl[.*]. It just so happens that the standalone container stores OSGi PIDs as files, PID.cfg, under the etc/ directory by default.
Mapping MBeans to ACL file names
jmx.acl. For example, given the MBean whose Object Name is given by org.apache.activemq:type=Broker, the corresponding PID would be:
jmx.acl.org.apache.activemq.Broker
etc/auth/jmx.acl.org.apache.activemq.Broker.cfg
ACL file format
Pattern = Role1[,Role2][,Role3]...
Pattern is a pattern that matches a method invocation on an MBean, and the right-hand side of the equals sign is a comma-separated list of roles that give a user permission to make that invocation. In the simplest cases, the Pattern is simply a method name. For example, as in the following settings for the org.apache.activemq.Broker MBean (from the jmx.acl.org.apache.activemq.Broker.cfg file):
addConnector = Deployer, Auditor, Administrator, SuperUser removeConnector = Deployer, Auditor, Administrator, SuperUser enableStatistics = Deployer, Auditor, Administrator, SuperUser addNetworkConnector = Deployer, Auditor, Administrator, SuperUser
*, to match multiple method names. For example, the following entry gives permission to invoke all method names starting with set:
set* = Deployer, Auditor, Administrator, SuperUser
org.apache.karaf.config MBean package exploits this capability to prevent ordinary users from modifying sensitive configuration settings. The create method from this package is restricted, as follows:
create(java.lang.String)[/jmx[.]acl.*/] = Administrator, SuperUser create(java.lang.String)[/org[.]apache[.]karaf[.]command[.]acl.+/] = Administrator, SuperUser create(java.lang.String)[/org[.]apache[.]karaf[.]service[.]acl.+/] = Administrator, SuperUser create(java.lang.String) = Deployer, Auditor, Administrator, SuperUser
Deployer and Auditor roles generally have permission to invoke the create method, but only the Administrator and SuperUser roles have permission to invoke create with a PID argument matching jmx.acl.*, org.apache.karaf.command.acl.*, or org.apache.karaf.service.*.
etc/auth/jmx.acl.cfg file.
ACL file hierarchy
org.apache.activemq.Broker MBean could be affected by ACL settings at any of the following PID levels:
jmx.acl.org.apache.activemq.Broker jmx.acl.org.apache.activemq jmx.acl.org.apache jmx.acl.org jmx.acl
Root ACL definitions
jmx.acl.cfg, is a special case, because it supplies the default ACL settings for all MBeans. The root ACL has the following settings by default:
list* = viewer, Monitor, Operator, Maintainer,Deployer, Auditor, Administrator, SuperUser get* = viewer, Monitor, Operator, Maintainer,Deployer, Auditor, Administrator, SuperUser is* = viewer, Monitor, Operator, Maintainer,Deployer, Auditor, Administrator, SuperUser set* = admin, Administrator, SuperUser * = admin, Administrator, SuperUser
list*, get*, is*) are accessible to all standard roles, but the typical write method patterns and other methods (set* and *) are accessible only to the administrator roles, admin, Administrator, SuperUser.
Package ACL definitions
etc/auth/jmx.acl[.*].cfg apply to MBean packages. For example, the ACL for the org.apache.camel.endpoints MBean package is defined with the following permissions:
is* = Monitor, Operator, Maintainer, Deployer, Auditor, Administrator, SuperUser get* = Monitor, Operator, Maintainer, Deployer, Auditor, Administrator, SuperUser set* = Deployer, Auditor, Administrator, SuperUser
ACL for custom MBeans
jmx.acl.cfg. If you want to define a more fine-grained ACL for your MBean, create a new ACL file under etc/auth, using the standard JMX ACL file naming convention.
org.example:type=MyMBean, create a new ACL file under the etc/auth directory called:
jmx.acl.org.example.MyMBean.cfg
Dynamic configuration at run time
2.2.3. Customizing the Command Console ACLs
Overview
etc/auth/org.apache.karaf.command.acl.*.cfg. This section explains how you can customize the command console ACLs by editing these files yourself.
Architecture
Figure 2.2. Access Control Mechanism for OSGi Services

How it works
- The invocation does not go directly to the requested OSGi service. Instead, the request is routed to a replacement proxy service, which has the same service properties as the original service (and some extra ones).
- The service guard looks up the relevant ACL for the target OSGi service (where the ACLs are stored in the OSGi Config Admin service).
- The ACL returns the list of roles that are allowed to make this particular method invocation on the service.
- If no ACL is found for this command, the service guard defaults to the list of roles specified in the
karaf.secured.command.compulsory.rolesproperty in theetc/system.propertiesfile. - The service guard checks the list of roles against the current security subject (the user that is making the method invocation), to see whether the current user has any of the required roles.
- If no matching role is found, the method invocation is blocked and a
java.lang.SecurityExceptionis raised. - Alternatively, if a matching role is found, the method invocation is delegated to the original OSGi service.
Configuring default security roles
karaf.secured.command.compulsory.roles property in the etc/system.properties file (specified as a comma-separated list of roles).
Location of command console ACL files
InstallDir/etc/auth directory, with the prefix, org.apache.karaf.command.acl.
Mapping command scopes to ACL file names
etc/auth/org.apache.karaf.command.acl.CommandScope.cfg
CommandScope corresponds to the prefix for a particular group of Karaf console commands. For example, the features:install and features:uninstall commands belong to the features command scope, which has the corresponding ACL file, org.apache.karaf.command.acl.features.cfg.
ACL file format
Pattern = Role1[,Role2][,Role3]...
Pattern is a pattern that matches a Karaf console command from the current command scope, and the right-hand side of the equals sign is a comma-separated list of roles that give a user permission to make that invocation. In the simplest cases, the Pattern is simply an unscoped command name. For example, the org.apache.karaf.command.acl.features.cfg ACL file includes the following rules for the features commands:
list = Monitor, Operator, Maintainer, Deployer, Auditor, Administrator, SuperUser listRepositories = Monitor, Operator, Maintainer, Deployer, Auditor, Administrator, SuperUser listUrl = Monitor, Operator, Maintainer, Deployer, Auditor, Administrator, SuperUser info = Monitor, Operator, Maintainer, Deployer, Auditor, Administrator, SuperUser install = Administrator,SuperUser uninstall = Administrator,SuperUser
org.apache.karaf.command.acl.osgi.cfg ACL file exploits this capability to prevent ordinary users from invoking the osgi:start and osgi:stop commands with the -f (force) flag (which must be specified to manage system bundles). This restriction is coded as follows in the ACL file:
start[/.*[-][f].*/] = Administrator, SuperUser start = Deployer, Auditor, Administrator, SuperUser stop[/.*[-][f].*/] = Administrator, SuperUser stop = Deployer, Auditor, Administrator, SuperUser
Deployer and Auditor roles generally have permission to invoke the osgi:start and osgi:stop commands, but only the Administrator and SuperUser roles have permission to invoke these commands with the force option, -f.
etc/auth/org.apache.karaf.command.acl.osgi.cfg file.
Dynamic configuration at run time
2.2.4. Defining ACLs for OSGi Services
Overview
ACL file format
service.guard = (objectClass=InterfaceName)
service.guard is an LDAP search filter that is applied to the registry of OSGi service properties in order to pick out the matching OSGi service. The simplest type of filter, (objectClass=InterfaceName), picks out an OSGi service with the specified Java interface name, InterfaceName.
Pattern = Role1[,Role2][,Role3]...
Pattern is a pattern that matches a service method, and the right-hand side of the equals sign is a comma-separated list of roles that give a user permission to make that invocation. The syntax of these entries is essentially the same as the entries in a JMX ACL file—see the section called “ACL file format”.
How to define an ACL for a custom OSGi service
- It is customary to define an OSGi service using a Java interface (you could use a regular Java class, but this is not recommended). For example, consider the Java interface,
MyService, which we intend to expose as an OSGi service:package org.example; public interface MyService { void doit(String s); } - To expose the Java interface as an OSGi service, you would typically add a
serviceelement to an OSGi Blueprint XML file (where the Blueprint XML file is typically stored under thesrc/main/resources/OSGI-INF/blueprintdirectory in a Maven project). For example, assuming thatMyServiceImplis the class that implements theMyServiceinterface, you could expose theMyServiceOSGi service as follows:<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" default-activation="lazy"> <bean id="myserviceimpl" class="org.example.MyServiceImpl"/> <service id="myservice" ref="myserviceimpl" interface="org.example.MyService"/> </blueprint> - To define an ACL for the the OSGi service, you must create an OSGi Config Admin PID with the prefix,
org.apache.karaf.service.acl.For example, in the case of a standalone container (where the OSGi Config Admin PIDs are stored as.cfgfiles under theetc/auth/directory), you can create the following ACL file for theMyServiceOSGi service:etc/auth/org.apache.karaf.service.acl.myservice.cfg
NoteIt does not matter exactly how you name this file, as long as it starts with the required prefix,org.apache.karaf.service.acl. The corresponding OSGi service for this ACL file is actually specified by a property setting in this file (as you will see in the next step). - Specify the contents of the ACL file in a format like the following:
service.guard = (objectClass=InterfaceName) Pattern = Role1[,Role2][,Role3]...
Theservice.guardsetting specifies theInterfaceNameof the OSGi service (using the syntax of an LDAP search filter, which is applied to the OSGi service properties). The other entries in the ACL file consist of a methodPattern, which associates a matching method to the specified roles. For example, you could define a simple ACL for theMyServiceOSGi service with the following settings in theorg.apache.karaf.service.acl.myservice.cfgfile:service.guard = (objectClass=org.example.MyService) doit = Deployer, Auditor, Administrator, SuperUser
- Finally, in order to enable the ACL for this OSGi service, you must edit the
karaf.secured.servicesproperty in theetc/system.propertiesfile. The value of thekaraf.secured.servicesproperty has the syntax of an LDAP search filter (which gets applied to the OSGi service properties). In general, to enable ACLs for an OSGi service,ServiceInterface, you must modify this property as follows:karaf.secured.services=(|(objectClass=ServiceInterface)(...ExistingPropValue...))
For example, to enable theMyServiceOSGi service:karaf.secured.services=(|(objectClass=org.example.MyService)(&(osgi.command.scope=*)(osgi.command.function=*)))
CautionThe initial value of thekaraf.secured.servicesproperty has the settings to enable the command console ACLs. If you delete or corrupt these entries, the command console ACLs might stop working.
How to invoke an OSGi service secured with RBAC
MyService OSGi service using the Deployer role, you could use code like the following:
// Java
import javax.security.auth.Subject;
import org.apache.karaf.jaas.boot.principal.RolePrincipal;
// ...
Subject s = new Subject();
s.getPrincipals().add(new RolePrincipal("Deployer"));
Subject.doAs(s, new PrivilegedAction() {
public Object run() {
svc.doit("foo"); // invoke the service
}
}org.apache.karaf.jaas.boot.principal.RolePrincipal. If necessary, you could use your own custom role class instead, but in that case you would have to specify your roles using the syntax className:roleName in the OSGi service's ACL file.
How to discover the roles required by an OSGi service
org.apache.karaf.service.guard.roles. The value of this property is a java.util.Collection object, which contains a list of all the roles that could possibly invoke a method on that service.
2.3. Using Encrypted Property Placeholders
Overview
How to use encrypted property placeholders
- Download and install Jasypt, to gain access to the Jasypt
listAlgorithms.sh,encrypt.shanddecrypt.shcommand-line tools.NoteWhen installing the Jasypt command-line tools, don't forget to enable execute permissions on the script files, by runningchmod u+x ScriptName.sh. - Choose a master password and an encryption algorithm. To discover which algorithms are supported in your current Java environment, run the
listAlgorithms.shJasypt command-line tool, as follows:./listAlgorithms.sh DIGEST ALGORITHMS: [MD2, MD5, SHA, SHA-256, SHA-384, SHA-512] PBE ALGORITHMS: [PBEWITHMD5ANDDES, PBEWITHMD5ANDTRIPLEDES, PBEWITHSHA1ANDDESEDE, PBEWITHSHA1ANDRC2_40]
On Windows platforms, the script islistAlgorithms.bat. JBoss Fuse usesPBEWithMD5AndDESby default. - Use the Jasypt encrypt command-line tool to encrypt your sensitive configuration values (for example, passwords for use in configuration files). For example, the following command encrypts the
PlaintextValvalue, using the specified algorithm and master passwordMasterPass:./encrypt.sh input="PlaintextVal" algorithm=PBEWithMD5AndDES password=MasterPass
- Create a properties file with encrypted values. For example, suppose you wanted to store some LDAP credentials. You could create a file,
etc/ldap.properties, with the following contents:Example 2.6. Property File with an Encrypted Property
#ldap.properties ldap.password=ENC(amIsvdqno9iSwnd7kAlLYQ==) ldap.url=ldap://192.168.1.74:10389
The encrypted property values (as generated in the previous step) are identified by wrapping in theENC()function. - (Blueprint XML only) Add the requisite namespaces to your Blueprint XML file:
- Aries extensions—
http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0 - Apache Karaf Jasypt—
http://karaf.apache.org/xmlns/jasypt/v1.0.0
Example 2.7, “Encrypted Property Namespaces” shows a Blueprint file with the requisite namespaces.Example 2.7. Encrypted Property Namespaces
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0" xmlns:enc="http://karaf.apache.org/xmlns/jasypt/v1.0.0"> ... </blueprint>
- Configure the location of the properties file for the property placeholder and configure the Jasypt encryption algorithm .
- Blueprint XMLExample 2.8, “Jasypt Blueprint Configuration” shows how to configure the
ext:property-placeholderelement to read properties from theetc/ldap.propertiesfile. Theenc:property-placeholderelement configures Jasypt to use thePBEWithMD5AndDESencryption algorithm and to read the master password from theJASYPT_ENCRYPTION_PASSWORDenvironment variable.Example 2.8. Jasypt Blueprint Configuration
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0" xmlns:enc="http://karaf.apache.org/xmlns/jasypt/v1.0.0"> <ext:property-placeholder> <location>file:etc/ldap.properties</location> </ext:property-placeholder> <enc:property-placeholder> <enc:encryptor class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor"> <property name="config"> <bean class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig"> <property name="algorithm" value="PBEWithMD5AndDES" /> <property name="passwordEnvName" value="JASYPT_ENCRYPTION_PASSWORD" /> </bean> </property> </enc:encryptor> </enc:property-placeholder> ... </blueprint> - Spring XMLExample 2.9, “Jasypt Spring Configuration” shows how to configure Jasypt to use the
PBEWithMD5AndDESencryption algorithm and to read the master password from theJASYPT_ENCRYPTION_PASSWORDenvironment variable.TheEncryptablePropertyPlaceholderConfigurerbean is configured to read properties from theetc/ldap.propertiesfile and to read properties from theio.fabric8.mq.fabric.ConfigurationPropertiesclass (which defines thekaraf.baseproperty, for example).Example 2.9. Jasypt Spring Configuration
<bean id="environmentVariablesConfiguration" class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig"> <property name="algorithm" value="PBEWithMD5AndDES" /> <property name="passwordEnvName" value="JASYPT_ENCRYPTION_PASSWORD" /> </bean> <bean id="configurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor"> <property name="config" ref="environmentVariablesConfiguration" /> </bean> <bean id="propertyConfigurer" class="org.jasypt.spring31.properties.EncryptablePropertyPlaceholderConfigurer"> <constructor-arg ref="configurationEncryptor" /> <property name="location" value="file:${karaf.base}/etc/ldap.properties"/> <property name="properties"> <bean class="io.fabric8.mq.fabric.ConfigurationProperties"/> </property> </bean>
- Use the placeholders in your configuration file. The placeholders you use for encrypted properties are the same as you use for regular properties. Use the syntax
${prop.name}. - Make sure that the
jasypt-encryptionfeature is installed in the container. If necessary, install thejasypt-encryptionfeature with the following console command:JBossFuse:karaf@root> features:install jasypt-encryption
- Shut down the container, by entering the following command:
JBossFuse:karaf@root> shutdown
- Carefully restart the container and deploy your secure application, as follows:
- Open a command window (first command window) and enter the following commands to start the JBoss Fuse container in the background:
export JASYPT_ENCRYPTION_PASSWORD="your super secret master pass phrase" ./bin/start
- Open a second command window and start the client utility, to connect to the container running in the background:
./bin/client -u Username -p Password
WhereUsernameandPasswordare valid JAAS user credentials for logging on to the container console. - In the second command window, use the console to install your secure application that uses encrypted property placeholders. Check that the application has launched successfully (for example, using the
osgi:listcommand to check its status). - After the secure application has started up, go back to the first command window and unset the
JASYPT_ENCRYPTION_PASSWORDenvironment variable.ImportantUnsetting theJASYPT_ENCRYPTION_PASSWORDenvironment variable ensures there will be minimum risk of exposing the master password. The Jasypt library retains the master password in encrypted form in memory.
Blueprint XML example
Example 2.10. Jasypt Example in Blueprint XML
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"
xmlns:enc="http://karaf.apache.org/xmlns/jasypt/v1.0.0">
<ext:property-placeholder>
<location>file:etc/ldap.properties</location>
</ext:property-placeholder>
<enc:property-placeholder>
<enc:encryptor class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="config">
<bean class="org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig">
<property name="algorithm" value="PBEWithMD5AndDES" />
<property name="passwordEnvName" value="JASYPT_ENCRYPTION_PASSWORD" />
</bean>
</property>
</enc:encryptor>
</enc:property-placeholder>
<jaas:config name="karaf" rank="200">
<jaas:module className="org.apache.karaf.jaas.modules.ldap.LDAPLoginModule" flags="required">
initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory
debug=true
connectionURL=${ldap.url}
connectionUsername=cn=mqbroker,ou=Services,ou=system,dc=jbossfuse,dc=com
connectionPassword=${ldap.password}
connectionProtocol=
authentication=simple
userRoleName=cn
userBase = ou=User,ou=ActiveMQ,ou=system,dc=jbossfuse,dc=com
userSearchMatching=(uid={0})
userSearchSubtree=true
roleBase = ou=Group,ou=ActiveMQ,ou=system,dc=jbossfuse,dc=com
roleName=cn
roleSearchMatching= (member:=uid={1})
roleSearchSubtree=true
</jaas:module>
</jaas:config>
</blueprint>${ldap.password} placeholder is replaced with the decrypted value of the ldap.password property from the etc/ldap.properties properties file.
2.4. Enabling Remote JMX SSL
Overview
Prerequisites
- Set your
JAVA_HOMEenvironment variable - Configure a JBoss Fuse user with the
AdministratorroleEdit the<installDir>/jboss-fuse-6.3.0.redhat-187/etc/users.propertiesfile and add the following entry, on a single line:admin=YourPassword,Administrator
This creates a new user with username,admin, password,YourPassword, and theAdministratorrole.
Create the jbossweb.keystore file
etc/ directory of your JBoss Fuse installation:
cd <installDir>/jboss-fuse-6.3.0.redhat-187/etc
-dname value (Distinguished Name) appropriate for your application, type this command:
$JAVA_HOME/bin/keytool -genkey -v -alias jbossalias -keyalg RSA -keysize 1024 -keystore jbossweb.keystore -validity 3650 -keypass JbossPassword -storepass JbossPassword -dname "CN=127.0.0.1, OU=RedHat Software Unit, O=RedHat, L=Boston, S=Mass, C=USA"
Generating 1,024 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 3,650 days
for: CN=127.0.0.1, OU=RedHat Software Unit, O=RedHat, L=Boston, ST=Mass, C=USA
New certificate (self-signed):
[
[
Version: V3
Subject: CN=127.0.0.1, OU=RedHat Software Unit, O=RedHat, L=Boston, ST=Mass, C=USA
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 1024 bits
modulus: 1123086025790567043604962990501918169461098372864273201795342440080393808
1594100776075008647459910991413806372800722947670166407814901754459100720279046
3944621813738177324031064260382659483193826177448762030437669318391072619867218
036972335210839062722456085328301058362052369248473659880488338711351959835357
public exponent: 65537
Validity: [From: Thu Jun 05 12:19:52 EDT 2014,
To: Sun Jun 02 12:19:52 EDT 2024]
Issuer: CN=127.0.0.1, OU=RedHat Software Unit, O=RedHat, L=Boston, ST=Mass, C=USA
SerialNumber: [ 4666e4e6]
Certificate Extensions: 1
[1]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: AC 44 A5 F2 E6 2F B2 5A 5F 88 FE 69 60 B4 27 7D .D.../.Z_..i`.'.
0010: B9 81 23 9C ..#.
]
]
]
Algorithm: [SHA256withRSA]
Signature:
0000: 01 1D 95 C0 F2 03 B0 FD CF 3A 1A 14 F5 2E 04 E5 .........:......
0010: DD 18 DD 0E 24 60 00 54 35 AE FE 36 7B 38 69 4C ....$`.T5..6.8iL
0020: 1E 85 0A AF AE 24 1B 40 62 C9 F4 E5 A9 02 CD D3 .....$.@b.......
0030: 91 57 60 F6 EF D6 A4 84 56 BA 5D 21 11 F7 EA 09 .W`.....V.]!....
0040: 73 D5 6B 48 4A A9 09 93 8C 05 58 91 6C D0 53 81 s.kHJ.....X.l.S.
0050: 39 D8 29 59 73 C4 61 BE 99 13 12 89 00 1C F8 38 9.)Ys.a........8
0060: E2 BF D5 3C 87 F6 3F FA E1 75 69 DF 37 8E 37 B5 ...<..?..ui.7.7.
0070: B7 8D 10 CC 9E 70 E8 6D C2 1A 90 FF 3C 91 84 50 .....p.m....<..P
]
[Storing jbossweb.keystore]<installDir>/jboss-fuse-6.3.0.redhat-187/etc now contains the file jbossweb.keystore.
Create and deploy the keystore.xml file
- Using your favorite xml editor, create and save the
keystore.xmlfile in the<installDir>/jboss-fuse-6.3.0.redhat-187/etcdirectory. - Include this text in the file:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"> <jaas:keystore name="sample_keystore" rank="1" path="file:etc/jbossweb.keystore" keystorePassword="JbossPassword" keyPasswords="jbossalias=JbossPassword" /> </blueprint> - Deploy the
keystore.xmlfile to the container, by copying it into the<installDir>/jboss-fuse-6.3.0.redhat-187/deploydirectory (the hot deploy directory).NoteSubsequently, if you need to undeploy thekeystore.xmlfile, you can do so by deleting thekeystore.xmlfile from thedeploy/directory while the Karaf container is running.
Add the required properties to org.apache.karaf.management.cfg
<installDir>/jboss-fuse-6.3.0.redhat-187/etc/org.apache.karaf.management.cfg file to include these properties at the end of the file:
secured = true secureProtocol = TLSv1 keyAlias = jbossalias keyStore = sample_keystore trustStore = sample_keystore
secureProtocol to TLSv1, in order to protect against the Poodle vulnerability (CVE-2014-3566)
Restart the JBoss Fuse container
Testing the Secure JMX connection
- Open a command prompt and make sure you are in the
etc/directory of your JBoss Fuse installation:cd <installDir>/jboss-fuse-6.3.0.redhat-187/etc
- Open a terminal, and start up JConsole by entering this command:
jconsole -J-Djavax.net.debug=ssl -J-Djavax.net.ssl.trustStore=jbossweb.keystore -J-Djavax.net.ssl.trustStoreType=JKS -J-Djavax.net.ssl.trustStorePassword=JbossPassword
Where the-J-Djavax.net.ssl.trustStoreoption specifies the location of thejbossweb.keystorefile (make sure this location is specified correctly, or the SSL/TLS handshake will fail). The-J-Djavax.net.debug=sslsetting enables logging of SSL/TLS handshake messages, so you can verify that SSL/TLS has been successfully enabled.ImportantType the entire command on the same command line. - When JConsole opens, select the option Remote Process in the New Connection wizard.
- Under the Remote Process option, enter the following value for the
service:jmx:<protocol>:<sap>connection URL:service:jmx:rmi://localhost:44444/jndi/rmi://localhost:1099/karaf-root
And fill in the Username, and Password fields with valid JAAS credentials (as set in theetc/users.propertiesfile):Username: admin Password:
YourPassword
Chapter 3. Securing the Jetty HTTP Server
Abstract
etc/org.ops4j.pax.web.cfg configuration file. In particular, you can add SSL/TLS security to the Fuse Management Console in this way.
Jetty server
http://Host:8181), the Jetty container can host multiple services, for example:
- Fuse Management Console (by default,
http://Host:8181/hawtio) - Apache CXF Web services endpoints (by default,
http://Host:8181/cxf, if the host and port are left unspecified in the endpoint configuration) - Some Apache Camel endpoints
Create X.509 certificate and private key
Enabling SSL/TLS for Jetty in a standalone container
- Open
etc/org.ops4j.pax.web.cfgin a text editor. - Replace the original content of the
etc/org.ops4j.pax.web.cfgfile with the following settings:# Configures the SMX Web Console to use SSL org.ops4j.pax.web.config.file=etc/jetty.xml org.osgi.service.http.enabled=false org.osgi.service.http.port=8181 org.ops4j.pax.web.session.cookie.httpOnly=true org.osgi.service.http.secure.enabled=true org.osgi.service.http.port.secure=8443 org.ops4j.pax.web.ssl.keystore=etc/alice.ks org.ops4j.pax.web.ssl.password=alicepass org.ops4j.pax.web.ssl.keypassword=alicepass
Where the new settings disable the existing insecure HTTP port (on 8181) and enable a new secure HTTPS port (on 8443). - Customize the SSL/TLS settings in
etc/org.ops4j.pax.web.cfgas follows:org.osgi.service.http.port.secure- Specifies the TCP port number of the secure HTTPS port.
org.ops4j.pax.web.ssl.keystore- The location of the Java keystore file on the file system. Relative paths are resolved relative to the
KARAF_HOMEenvironment variable (by default, the install directory). org.ops4j.pax.web.ssl.password- The store password that unlocks the Java keystore file.
org.ops4j.pax.web.ssl.keypassword- The key password that decrypts the private key stored in the keystore (usually the same as the store password).
- Restart the JBoss Fuse container, in order for the configuration changes to take effect.
Customizing allowed TLS protocols and cipher suites
etc/org.ops4j.pax.web.cfg file:
org.ops4j.pax.web.ssl.protocols.included- Specifies a list of allowed TLS/SSL protocols.
org.ops4j.pax.web.ssl.protocols.excluded- Specifies a list of disallowed TLS/SSL protocols.
org.ops4j.pax.web.ssl.ciphersuites.included- Specifies a list of allowed TLS/SSL cipher suites.
org.ops4j.pax.web.ssl.ciphersuites.excluded- Specifies a list of disallowed TLS/SSL cipher suites.
Connect to the secure console
https://Host:8443/hawtio
https: scheme, instead of http:, in this URL.
Advanced Jetty security configuration
etc/jetty.xml file. This approach gives you access to the full Jetty security API:
- Open
etc/org.ops4j.pax.web.cfgin a text editor. - Disable the insecure HTTP port by adding the org.osgi.service.http.enabled and setting it to
false; and enable the secure HTTPS port by adding the org.osgi.service.http.secure.enabled and setting it totrue. Change the value oforg.ops4j.pax.web.config.fileto reference the file,etc/jetty-ssl.xml(which you will create in the next step).Theetc/org.ops4j.pax.web.cfgfile should now have the following contents:# Configures the SMX Web Console to use SSL org.ops4j.pax.web.config.file=etc/jetty-ssl.xml org.osgi.service.http.enabled=false org.osgi.service.http.port=8181 org.ops4j.pax.web.session.cookie.httpOnly=true org.osgi.service.http.secure.enabled=true
- Create a new file,
etc/jetty-ssl.xml, with the following contents:<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd"> <Configure id="Server" class="org.eclipse.jetty.server.Server"> <!-- ========================================================== --> <!-- Set connectors --> <!-- ========================================================== --> <!-- One of each type! --> <!-- ========================================================== --> <!-- Use this connector for many frequently idle connections and for threadless continuations. --> <New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration"> <Set name="secureScheme">https</Set> <Set name="securePort"> <Property name="jetty.secure.port" default="8443" /> </Set> <Set name="outputBufferSize">32768</Set> <Set name="requestHeaderSize">8192</Set> <Set name="responseHeaderSize">8192</Set> <Set name="sendServerVersion">true</Set> <Set name="sendDateHeader">false</Set> <Set name="headerCacheSize">512</Set> </New> <!-- ========================================================== --> <!-- Configure Authentication Realms --> <!-- Realms may be configured for the entire server here, or --> <!-- they can be configured for a specific web app in a context --> <!-- configuration (see $(jetty.home)/contexts/test.xml for an --> <!-- example). --> <!-- ========================================================== --> <Call name="addBean"> <Arg> <New class="org.eclipse.jetty.jaas.JAASLoginService"> <Set name="name">karaf</Set> <Set name="loginModuleName">karaf</Set> <Set name="roleClassNames"> <Array type="java.lang.String"> <Item> org.apache.karaf.jaas.boot.principal.RolePrincipal </Item> </Array> </Set> </New> </Arg> </Call> <New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration"> <Arg><Ref refid="httpConfig"/></Arg> <Call name="addCustomizer"> <Arg> <New class="org.eclipse.jetty.server.SecureRequestCustomizer"/> </Arg> </Call> </New> <New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory"> <Set name="KeyStorePath"> /home/jdoe/Programs/JBossFuse/jboss-fuse-6.3.0.redhat-187/etc/alice.ks </Set> <Set name="KeyStorePassword">alicepass</Set> <Set name="KeyManagerPassword">alicepass</Set> <!--Set name="TrustStorePath"> <Property name="jetty.base" default="." /> <Property name="jetty.truststore" default="quickstarts/switchyard/demos/policy-security-basic/connector.jks"/> </Set> <Set name="TrustStorePassword"> <Property name="jetty.truststore.password" default="changeit"/> </Set--> <Set name="EndpointIdentificationAlgorithm"></Set> <Set name="NeedClientAuth"> <Property name="jetty.ssl.needClientAuth" default="false"/> </Set> <Set name="WantClientAuth"> <Property name="jetty.ssl.wantClientAuth" default="false"/> </Set> <!-- Disable SSLv3 to protect against POODLE bug --> <Set name="ExcludeProtocols"> <Array type="java.lang.String"> <Item>SSLv3</Item> </Array> </Set> <Set name="ExcludeCipherSuites"> <Array type="String"> <Item>SSL_RSA_WITH_DES_CBC_SHA</Item> <Item>SSL_DHE_RSA_WITH_DES_CBC_SHA</Item> <Item>SSL_DHE_DSS_WITH_DES_CBC_SHA</Item> <Item>SSL_RSA_EXPORT_WITH_RC4_40_MD5</Item> <Item>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</Item> <Item>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</Item> <Item>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</Item> </Array> </Set> </New> <Call id="httpsConnector" name="addConnector"> <Arg> <New class="org.eclipse.jetty.server.ServerConnector"> <Arg name="server"><Ref refid="Server" /></Arg> <Arg name="acceptors" type="int"> <Property name="ssl.acceptors" default="-1"/> </Arg> <Arg name="selectors" type="int"> <Property name="ssl.selectors" default="-1"/> </Arg> <Arg name="factories"> <Array type="org.eclipse.jetty.server.ConnectionFactory"> <Item> <New class="org.eclipse.jetty.server.SslConnectionFactory"> <Arg name="next">http/1.1</Arg> <Arg name="sslContextFactory"> <Ref refid="sslContextFactory"/> </Arg> </New> </Item> <Item> <New class="org.eclipse.jetty.server.HttpConnectionFactory"> <Arg name="config"><Ref refid="sslHttpConfig"/></Arg> </New> </Item> </Array> </Arg> <Set name="name">0.0.0.0:8443</Set> <Set name="host"><Property name="jetty.host" /></Set> <Set name="port"> <Property name="https.port" default="8443" /> </Set> <Set name="idleTimeout"> <Property name="https.timeout" default="30000"/> </Set> <Set name="soLingerTime"> <Property name="https.soLingerTime" default="-1"/> </Set> <Set name="acceptorPriorityDelta"> <Property name="ssl.acceptorPriorityDelta" default="0"/> </Set> <Set name="selectorPriorityDelta"> <Property name="ssl.selectorPriorityDelta" default="0"/> </Set> <Set name="acceptQueueSize"> <Property name="https.acceptQueueSize" default="0"/> </Set> </New> </Arg> </Call> </Configure>ImportantThe preceding configuration explicitly disables the SSLv3 protocol, in order to safeguard against the Poodle vulnerability (CVE-2014-3566). For more details, see Disabling SSLv3 in JBoss Fuse 6.x and JBoss A-MQ 6.x. - (Optional) If you prefer, you can use a system property to help you specify the location of the Java keystore file. For example, instead of setting the
KeyStorePathproperty explicitly (in the precedingetc/jetty-ssl.xmlconfiguration):<Set name="KeyStorePath">/home/jdoe/Documents/jetty.ks</Set>
You could use thekaraf.homesystem property to specify the location of the keystore file relative to the JBoss Fuse install directory:<Set name="KeyStorePath"> <SystemProperty name="karaf.home"/>/etc/jetty.ks </Set> - Customize the properties of the
SslContextFactoryinstance defined in theetc/jetty-ssl.xmlfile, as follows:KeyStorePath- The location of the Java keystore file on the file system. Relative paths are resolved relative to the
KARAF_HOMEenvironment variable (by default, the install directory). KeyStorePassword- The store password that unlocks the Java keystore file.
KeyManagerPassword- The key password that decrypts the private key stored in the keystore (usually the same as the store password).
- Restart the JBoss Fuse container, in order for the configuration changes to take effect.NoteThe Apache Karaf container does not automatically detect changes in the
etc/jetty-ssl.xmlfile. Hence, if you make subsequent edits to theetc/jetty-ssl.xmlfile, you must also update theetc/org.ops4j.pax.web.cfgfile (by making a trivial edit or using the UNIXtouchcommand), in order to force Apache Karaf to reload theetc/jetty-ssl.xmlfile.
Enabling SSL/TLS for Jetty in a Fabric
- Under the root container's installation directory, create the new directory,
etc/certs. - In the
etc/certsdirectory, create a new self-signed certificate and private key using the Javakeytoolutility, as follows:keytool -genkeypair -keyalg RSA -dname "CN=Hostname" -ext SubjectAlternativeName=ip:PUBLIC_IP -validity 365 -keystore alice.ks -alias alice -keypass KeyPass -storepass StorePass
After executing this command, the key pair is stored in thealice.kskeystore file under the alias,alice. Pay particular attention to theHostnamevalue and thePUBLIC_IPvalue: the specifiedHostnamemust be the name of the host where the root container is deployed andPUBLIC_IPis the public IP address. The other Fabric containers will check that the certificate's Common Name (CN) matches the root container's host name during the SSL/TLS handshake.For a more detailed explanation of key pairs and instructions for (optionally) signing the resulting certificate with a Certificate Authority (CA), see Appendix A, Managing Certificates.NoteIf there are multiple containers (Fabric servers) in the Fabric ensemble, you must create and deploy a separate key pair for each container in the ensemble, where the specifiedHostnamematches the respective container host. The other containers in the Fabric must then be configured to trust all of the ensemble certificates (which you could do, for example, by adding all of the ensemble certificates to a trust store file accessible to the other containers). - Start up the root container:
./bin/fuse
- Create a new fabric, by entering a console command like the following:
JBossFuse:karaf@root> fabric:create --new-user AdminUser --new-user-password AdminPass --new-user-role Administrator --global-resolver manualip --resolver manualip --manual-ip Hostname --zookeeper-password ZooPass --wait-for-provisioning
ImportantTheHostnamevalue specifed infabric:createmust be exactly the sameHostnamevalue that was assigned to the CN field of the certificate in step 2. Otherwise, when you create a new child container, the hostname check will fail during the SSL/TLS handshake and the child container will fail to provision.NoteIn a production system (and for any long-running demonstration system), the Fabric server must be deployed on a host that has a static IP address. - Edit the Jetty Web server properties for the
org.ops4j.pax.webpersistent ID in thedefaultprofile. You can edit these properties either from the Fuse Management Console (by navigating tohttp://localhost:8181/hawtioin your browser) or using the built-in editor at the console:JBossFuse:karaf@root> profile-edit --resource org.ops4j.pax.web.properties default
Add the following settings to the existing content of theorg.ops4j.pax.web.propertiesresource:... org.osgi.service.http.enabled=false org.osgi.service.http.secure.enabled=true org.osgi.service.http.port.secure=${port:8443,8543} org.ops4j.pax.web.ssl.keystore=AbsolutePathToKeystoreFile org.ops4j.pax.web.ssl.password=StorePass org.ops4j.pax.web.ssl.keypassword=KeyPassCustomize theorg.ops4j.pax.websettings as follows:org.osgi.service.http.enabled- Set to
false, to disable the insecure Jetty HTTP port. org.osgi.service.http.secure.enabled- Set to
true, to enable the secure Jetty HTTPS port. org.osgi.service.http.port.secure- Specifies the TCP port number of the secure HTTPS port. You should use the Fabric port service (see section "The Port Service" in "Fabric Guide"), which enables you to specify a range of ports for this setting,
${port:8443,8543}. This ensure that any child containers are automatically allocated unique port numbers. org.ops4j.pax.web.ssl.keystore- The location of the Java keystore file on the file system. This should be specified as an absolute pathname, to ensure that both the root container and child containers can locate the keystore file (child containers evaluate relatives paths differently from the root container). For example, a typical setting might look like this:
org.ops4j.pax.web.ssl.keystore=/opt/servers/jboss-fuse-6.3.0.redhat-187/etc/certs/alice.ks
org.ops4j.pax.web.ssl.password- The store password that unlocks the Java keystore file.
org.ops4j.pax.web.ssl.keypassword- The key password that decrypts the private key stored in the keystore (usually the same as the store password).
- Create a truststore file for the child containers. There are a few different approaches you can take when creating the truststore:
- The simplest option is to use the keystore file—for example,
etc/certs/alice.ks—directly as the truststore. - If you need to trust multiple certificates, extract the
alicecertificate from thealice.kstruststore and add it to an existing truststore file which contains all of the other certificates you want to trust. - If you signed the
alicecertificate with a CA, you can add the CA certificate to the truststore file.
- The current instructions apply to a fabric that has only one container in its ensemble (the root container). If you set up a fabric with three ensemble servers, however, you would need to make sure that you configure the truststores so that each ensemble server trusts the other two. For example, with three ensemble servers:
- Add public keys from servers 1 and 2 to truststore for server 3.
- Add public keys from servers 2 and 3 to truststore for server 1.
- Add public keys from servers 3 and 1 to truststore for server 2.
Alternatively, if you have set up a certificate authority (CA), a more practical approach would be to sign all of the certificates with the same CA certificate and then put the CA certificate into the truststore (that is, in this case only the CA certificate needs to be in the truststore and the same truststore can be used on all of the hosts). - Shut down the root container (for example, by entering
shutdown -fat the console) and specify the truststore and truststore password on the root container. To specify the truststore as a JVM argument, edit the root container'setc/setenvfile and add the following line:EXTRA_JAVA_OPTS="-Djavax.net.ssl.trustStore=/opt/servers/jboss-fuse-6.3.0.redhat-187/etc/certs/alice.ks -Djavax.net.ssl.trustStorePassword=StorePass"
Where this example assumes you are using thealice.ksfile directly as the truststore. - Restart the root container. Search the log (for example, by entering the
log:displayconsole command) and look for a line like the following:17:37:35,576 | INFO | pool-3-thread-1 | JettyServerImpl | 117 - org.ops4j.pax.web.pax-web-jetty - 4.2.6 | Pax Web available at [0.0.0.0]:[8453]
This gives you the port number of the secure Jetty Web server. You can login to the Fuse Management Console using this port—for example, using a URL like the following (not forgetting to specify the scheme ashttps):https://Host:8543
- You can now create a new child container with Jetty security enabled, by specifying the truststore and truststore password as JVM arguments when you create the child container. For example, assuming that you are using the
alice.ksfile directly as a truststore, you can create a secure child container with a command like the following:JBossFuse:karaf@root> container-create-child --jvm-opts='-Djavax.net.ssl.trustStore=/opt/servers/jboss-fuse-6.3.0.redhat-187/etc/certs/alice.ks -Djavax.net.ssl.trustStorePassword=StorePass' --profile fabric root child
- Check the provision status of the new child using the
fabric:container-listconsole command (or by monitoring the Container tab of the Fuse Management Console). If the child fails to provision, check the logs of both the root container and the child container for errors.
References
etc/jetty-ssl.xml file and configuring it as described in the Jetty security documentation:
Chapter 4. Securing the Camel ActiveMQ Component
Abstract
4.1. Secure ActiveMQ Connection Factory
Overview
Programming the security properties
ActiveMQSslConnectionFactory JMS connection factory. Programming the JMS connection factory is the correct approach to use in the context of the containers such as OSGi, J2EE, Tomcat, and so on, because these settings are local to the application using the JMS connection factory instance.
Defining a secure connection factory
Example 4.1. Defining a Secure Connection Factory Bean
<bean id="jmsConnectionFactory"
class="org.apache.activemq.ActiveMQSslConnectionFactory">
<property name="brokerURL" value="ssl://localhost:61617" />
<property name="userName" value="Username"/>
<property name="password" value="Password"/>
<property name="trustStore" value="/conf/client.ts"/>
<property name="trustStorePassword" value="password"/>
</bean>ActiveMQSslConnectionFactory class:
brokerURL- The URL of the remote broker to connect to, where this example connects to an SSL-enabled OpenWire port on the local host. The broker must also define a corresponding transport connector with compatible port settings.
userNameandpassword- Any valid JAAS login credentials,
UsernameandPassword. trustStore- Location of the Java keystore file containing the certificate trust store for SSL connections. The location is specified as a classpath resource. If a relative path is specified, the resource location is relative to the
org/jbossfuse/exampledirectory on the classpath. trustStorePassword- The password that unlocks the keystore file containing the trust store.
keyStore and keyStorePassword properties, but these would only be needed, if SSL mutual authentication is enabled (where the client presents an X.509 certificate to the broker during the SSL handshake).
4.2. Example Camel ActiveMQ Component Configuration
Overview
Prerequisites
camel-activemq feature, which defines the bundles required for the Camel ActiveMQ component, is not installed by default. To install the camel-activemq feature, enter the following console command:
JBossFuse:karaf@root> features:install camel-activemq
Sample Camel ActiveMQ component
activemqssl bean ID, which means it is associated with the activemqssl scheme (which you use when defining endpoints in a Camel route).
<?xml version="1.0" encoding="UTF-8"?>
<beans ... >
...
<!--
Configure the activemqssl component:
-->
<bean id="jmsConnectionFactory"
class="org.apache.activemq.ActiveMQSslConnectionFactory">
<property name="brokerURL" value="ssl://localhost:61617" />
<property name="userName" value="Username"/>
<property name="password" value="Password"/>
<property name="trustStore" value="/conf/client.ts"/>
<property name="trustStorePassword" value="password"/>
</bean>
<bean id="pooledConnectionFactory"
class="org.apache.activemq.pool.PooledConnectionFactory">
<property name="maxConnections" value="8" />
<property name="maximumActive" value="500" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="pooledConnectionFactory"/>
<property name="transacted" value="false"/>
<property name="concurrentConsumers" value="10"/>
</bean>
<bean id="activemqssl"
class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="configuration" ref="jmsConfig"/>
</bean>
</beans>Sample Camel route
security.test queue on the broker, using the activemqssl scheme to reference the Camel ActiveMQ component defined in the preceding example:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
...
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="timer://myTimer?fixedRate=true&period=5000"/>
<transform><constant>Hello world!</constant></transform>
<to uri="activemqssl:security.test"/>
</route>
</camelContext>
...
</beans>Chapter 5. Securing the Camel Jetty Component
Abstract
5.1. Enabling SSL/TLS Security
Overview
sslSocketConnectorProperties property, which configures SSL/TLS. You must also change the protocol scheme on the Jetty URI from http to https.
Tutorial steps
Generate a Maven project
maven-archetype-quickstart archetype creates a generic Maven project, which you can then customize for whatever purpose you like. To generate a Maven project with the coordinates, org.jbossfuse.example:jetty-security, enter the following command:
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DgroupId=org.jbossfuse.example -DartifactId=jetty-security
ProjectDir/jetty-security, containing the files for the generated project.
Customize the POM file
jetty-security/pom.xml file and replace its contents with the following XML code:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.jbossfuse.example</groupId>
<artifactId>jetty-security</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>jetty-security</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>
${project.groupId}.${project.artifactId}
</Bundle-SymbolicName>
<Import-Package>*</Import-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>Install sample keystore files
clientKeystore.jks key pair and the serviceKeystore.jks key pair using the Java keytool utility, as follows:
keytool -genkeypair -keyalg RSA -dname "CN=Client, OU=Engineering, O=Red Hat, ST=Dublin, C=IE" -validity 365 -alias client -keypass KeyPass -keystore clientKeystore.jks -storepass StorePass keytool -genkeypair -keyalg RSA -dname "CN=Service, OU=Engineering, O=Red Hat, ST=Dublin, C=IE" -validity 365 -alias service -keypass KeyPass -keystore serviceKeystore.jks -storepass StorePass
clientKeystore.jks certificate and the serviceKeystore.jks certificate to the EsbInstallDir/etc/certs directory (where you will need to create the etc/certs sub-directory). After copying, you should have the following directory structure under EsbInstallDir/etc/:
EsbInstallDir/etc/
|
\--certs/
|
\--clientKeystore.jks
serviceKeystore.jksclientKeystore.jks, and serviceKeystore.jks are the keystores that are used in this demonstration.
Configure Jetty with SSL/TLS
ProjectDir/jetty-security/src/main/resources/META-INF/spring
spring directory that you just created, use your favourite text editor to create the file, jetty-spring.xml, containing the following XML configuration:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core-5.4.0.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="jetty" class="org.apache.camel.component.jetty9.JettyHttpComponent9">
<property name="sslContextParameters" ref="sslContextParameters" />
</bean>
<sslContextParameters id="sslContextParameters" xmlns="http://camel.apache.org/schema/spring">
<secureSocketProtocols>
<!-- Do NOT enable SSLv3 (POODLE vulnerability) -->
<secureSocketProtocol>TLSv1</secureSocketProtocol>
<secureSocketProtocol>TLSv1.1</secureSocketProtocol>
<secureSocketProtocol>TLSv1.2</secureSocketProtocol>
</secureSocketProtocols>
<keyManagers keyPassword="KeyPass">
<keyStore resource="etc/certs/serviceKeystore.jks" password="StorePass"/>
</keyManagers>
<trustManagers>
<keyStore resource="etc/certs/serviceKeystore.jks" password="StorePass"/>
</trustManagers>
</sslContextParameters>
<camelContext trace="true" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="jetty:https://0.0.0.0:8282/services?matchOnUriPrefix=true"/>
<transform>
<constant><html><body>Hello from Fuse ESB server</body></html></constant>
</transform>
</route>
</camelContext>
</beans>jetty bean defines a new instance of the Apache Camel Jetty component, overriding the default component defined in the camel-jetty JAR file. This Jetty component is configured using the sslContextParameters element, as follows:
secureSocketProtocols- Explicitly lists the SSL/TLS protocols supported by the Jetty server.ImportantThis configuration explicitly disables the SSLv3 protocol, in order to safeguard against the Poodle vulnerability (CVE-2014-3566). For more details, see Disabling SSLv3 in JBoss Fuse 6.x and JBoss A-MQ 6.x.
keyManagers/@keyPassword- The password that decrypts the private key stored in the keystore (usually having the same value as
password). keyManagers/keyStore/@resource- The location of the Java keystore file (in JKS format) containing the Jetty server's own X.509 certificate and private key. This location is specified on the filesystem (not on the classpath), relative to the directory where the OSGi container is started.
keyManagers/keyStore/@password- The keystore password that unlocks the keystore.
trustManagers/@resource- The location of the Java keystore file containing one or more trusted certificates (that is, the CA certificates that have been used to sign X.509 certificates from trusted clients). This location is specified on the filesystem (not on the classpath), relative to the directory where the OSGi container is started.Strictly speaking, this property is not needed, if clients do not send certificates to the Jetty service.
trustManagers/@password- The keystore password that unlocks the
truststoretrust store.
uri attribute of the from element). Make sure that the scheme of the URI matches the secure Jetty component, jetty, that you have just created. You must also change the protocol scheme from http to https.
https. This is such a small change, it is easy to forget.
Build the bundle
ProjectDir/jetty-security, and enter the following command:
mvn install -Dmaven.test.skip=true
Install the camel-jetty feature
./bin/fuse
camel-jetty feature, which defines the bundles required for the Camel/Jetty component, is not installed by default. To install the camel-jetty feature, enter the following console command:
JBossFuse:karaf@root> features:install camel-jetty
Deploy the bundle
JBossFuse:karaf@root> osgi:install -s mvn:org.jbossfuse.example/jetty-security/1.0-SNAPSHOT
Test the bundle
curl command at a comand-line prompt:
curl https://localhost:8282/services -k
https: instead of http: in the URL!
-k flag allows curl to skip the SSL certificate check (that is, checking that the received server certificate is signed by a local CA certificate), so that the server identity is not verified. You should receive the following HTTP response:
<html><body>Hello from Fuse ESB server</body></html>
Uninstall the bundle
JBossFuse:karaf@root> osgi:uninstall BundleID
5.2. BASIC Authentication with JAAS
Overview
karaf.
Prerequisites
Authentication steps
Add the Jetty security handler configuration
jetty-security project, edit the jetty-spring.xml file from the src/main/resources/META-INF/spring directory. To configure the Jetty security handler with BASIC authentication, add the following bean definitions:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
...
<!-- -->
<bean id="loginService" class="org.eclipse.jetty.jaas.JAASLoginService">
<property name="name" value="Your Services Realm"/>
<property name="loginModuleName" value="karaf"/>
<property name="roleClassNames">
<list>
<value>org.apache.karaf.jaas.boot.principal.RolePrincipal</value>
</list>
</property>
</bean>
<bean id="identityService" class="org.eclipse.jetty.security.DefaultIdentityService"/>
<bean id="constraint" class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="BASIC"/>
<property name="roles" value="Administrator"/>
<property name="authenticate" value="true"/>
</bean>
<bean id="constraintMapping" class="org.eclipse.jetty.security.ConstraintMapping">
<property name="constraint" ref="constraint"/>
<property name="pathSpec" value="/*"/>
</bean>
<bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler">
<property name="authenticator">
<bean class="org.eclipse.jetty.security.authentication.BasicAuthenticator"/>
</property>
<property name="constraintMappings">
<list>
<ref bean="constraintMapping"/>
</list>
</property>
<property name="loginService" ref="loginService"/>
<property name="identityService" ref="identityService"/>
</bean>
...
</beans>- HTTP BASIC authentication—the
constraintbean enables HTTP BASIC authentication on the Jetty security handler. Therolesproperty (ofString[]type) is used to define which roles have access to the Jetty container. In this example, this property is set toAdministrator, so only users with theAdministratorrole can access this Jetty container. - JAAS login service—the
loginServicebean specifies that the requisite authentication data is extracted from a JAAS realm. TheloginModuleNameproperty specifies that the Jetty login service uses thekarafJAAS realm, which is the OSGi container's default JAAS realm (see Section 1.1, “OSGi Container Security”).
Modify Camel Jetty endpoint
securityHandler bean, you must modify the Jetty endpoint URI in the Apache Camel route, so that it hooks into the security handler. To add the security handler to the Jetty endpoint, set the handlers option equal to the security handler's bean ID, as shown in the following example:
<beans ...>
<camelContext trace="true" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="jetty:https://0.0.0.0:8282/services?handlers=securityHandler&matchOnUriPrefix=true"/>
<transform>
<constant><html><body>Hello from Fuse ESB server</body></html></constant>
</transform>
</route>
</camelContext>
</beans>& entity, instead of the plain & character, in the context of an XML file.
Add required package imports to POM
jetty-security project's POM file, jetty-security/pom.xml. Further down the POM file, in the configuration of the Maven bundle plug-in, modify the bundle instructions to import additional Java packages, as follows:
<project ... >
...
<build>
...
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>
${project.groupId}.${project.artifactId}
</Bundle-SymbolicName>
<Import-Package>
javax.security.auth,
javax.security.auth.callback,
javax.security.auth.login,
javax.security.auth.spi,
org.apache.karaf.jaas.modules,
org.apache.karaf.jaas.boot.principal,
org.eclipse.jetty.jaas,
org.eclipse.jetty.security,
*
</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
...
</project>Build the bundle
ProjectDir/jetty-security, and enter the following command:
mvn clean install -Dmaven.test.skip=true
Install the required features
./bin/fuse
camel-jetty feature using the following console command:
karaf@root> features:install camel-jetty
Deploy the bundle
JBossFuse:karaf@root> osgi:install -s mvn:org.jbossfuse.example/jetty-security/1.0-SNAPSHOT
Test the bundle
curl command at a comand-line prompt:
curl https://0.0.0.0:8282/services -k --user Username:Password
https: instead of http: in the URL!
--user option is needed to specify the BASIC authentication credentials. For the Username and Password values, specify valid JAAS credentials (the valid credentials you can use for this step are specified in the EsbInstallDir/etc/users.properties file). You should now receive the following HTTP reply message:
<html><body>Hello from Fuse ESB server</body></html>
Chapter 6. Configuring Transport Security for Camel Components
Abstract
org.apache.util.jsse.SSLContextParameters. To configure TLS settings, you pass an instance of this class to a Camel component. You can configure an SSLContextParameters object by using pure Java or by using Spring or Blueprint XML.
SSLContextParameters object:
<sslContextParameters id="sslContextParameters" xmlns="http://camel.apache.org/schema/spring">
<keyManagers keyPassword="secret1">
<keyStore resource="./my_keystore.jks" password="secret2" />
</keyManagers>
<trustManagers>
<keyStore resource="./my_truststore.jks" password="secret2" />
</trustManagers>
</sslContextParameters>sslContextParameters element with keyManagers and trustManagers child elements. The keyManagers element configures the key store while the trustManagers element configures the trust store. For details about key stores and trust stores, see the Apache Camel documentation for the JSSE utility.
sslContextParameters bean in your endpoint URI. The following route runs a netty4 HTTPS endpoint. The ssl option is required. For example:
<route>
<from uri="netty4:https://localhost:8080/early?sslContextParametersRef=#sslContextParameters&ssl=true"/>
<transform>
<constant>Hi</constant>
</transform>
</route>@Override
protected JndiRegistry createRegistry() throws Exception {
KeyStoreParameters ksp = new KeyStoreParameters();
ksp.setResource("./my_keystore.jks");
ksp.setPassword("secret1");
KeyManagersParameters kmp = new KeyManagersParameters();
kmp.setKeyPassword("secret2");
kmp.setKeyStore(ksp);
KeyStoreParameters tsp = new KeyStoreParameters();
tsp.setResource("./my_truststore.jks");
tsp.setPassword("secret2");
TrustManagersParameters tmp = new TrustManagersParameters();
tmp.setKeyStore(tsp);
SSLContextParameters sslContextParameters = new SSLContextParameters();
sslContextParameters.setKeyManagers(kmp);
sslContextParameters.setTrustManagers(tmp);
JndiRegistry registry = super.createRegistry();
registry.bind("sslContextParameters", sslContextParameters);
return registry;
}netty4 HTTPS endpoint looks like the following. The ssl option is required.
from("netty4:https://localhost:8080/early?sslContextParametersRef=
#sslContextParameters&ssl=true").transform().constant("Hi");
sslContextParameters object that contains a trusted certificate. The following example reuses the server sslContextParameters object. In this example, the URI syntax is the same for the producer. For example:
String reply =
template.requestBody(
"netty4:https://localhost:8080/early?ssl=true&sslContextParametersRef=
sslContextParameters", "Hi Camel!", String.class);sslContextParameters object that contains a valid trust store then the server does not allow a connection and Camel throws an execution exception - CamelExecutionException.
Chapter 7. Securing the Camel CXF Component
Abstract
7.1. The Camel CXF Proxy Demonstration
Overview
Figure 7.1. Camel CXF Proxy Overview

RealWebServiceBean, receives details of an incident (for example, a traffic accident) and returns a tracking code to the client. Instead of sending its requests directly to the real Web service, however, the WS client connects to a Camel CXF endpoint, which is interposed between the WS client and the real Web service. The Apache Camel route performs some processing on the WSDL message (using the enrichBean) before forwarding it to the real Web service.
Modifications
- SSL/TLS security is enabled on the connection between the WS client and the Camel CXF endpoint.
- The Apache Camel route and the
RealWebServiceBeanbean are both deployed into the OSGi container.
Obtaining the demonstration code
InstallDir/extras directory. Using a standard archive utility, expand the Camel archive file and extract the contents to a convenient location on your filesystem.
CamelInstallDir/examples/camel-example-cxf-proxy
Obtaining the sample certificates
wsdl_first_http example. This demonstration is available from the standalone distribution of Apache CXF, which is included in the InstallDir/extras directory. Using a standard archive utility, expand the CXF archive file and extract the contents to a convenient location on your filesystem.
wsdl_first_http demonstration in the following directory:
CXFInstallDir/samples/wsdl_first_http
Physical part of the WSDL contract
wsdl:service and wsdl:port elements. These elements specify the transport details that are needed to connect to a specific Web services endpoint. For the purposes of this demonstration, this is the most interesting part of the contract and it is shown in Example 7.1, “The ReportIncidentEndpointService WSDL Service”.
Example 7.1. The ReportIncidentEndpointService WSDL Service
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
...
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://reportincident.example.camel.apache.org">
...
<!-- Service definition -->
<wsdl:service name="ReportIncidentEndpointService">
<wsdl:port name="ReportIncidentEndpoint" binding="tns:ReportIncidentBinding">
<soap:address location="http://localhost:9080/camel-example-cxf-proxy/webservices/incident"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>soap:address element's location attribute) is not important here, because the application code overrides the default value of the address URL.
WSDL addressing details
- WSDL service name
- The full QName of the WSDL service is as follows:
{http://reportincident.example.camel.apache.org}ReportIncidentEndpointService - WSDL port name
- The full QName of the WSDL port is as follows:
{http://reportincident.example.camel.apache.org}ReportIncidentEndpoint - Address URL
- The address URL of the proxy Web service endpoint (which uses the HTTPS protocol) is as follows:
https://localhost:9080/camel-example-cxf-proxy/webservices/incident
NoteThe preceding address is specified when thereportIncidentbean is created using acxf:cxfEndpointelement in the bundle's Spring configuration file,src/main/resources/META-INF/spring/camel-config.xml.The address URL of the real Web service endpoint (using the HTTP protocol) is as follows:http://localhost:9081/real-webservice
NoteThe preceding address is specified when therealWebServicebean is created in the bundle's Spring configuration file,src/main/resources/META-INF/spring/camel-config.xml.
7.2. Securing the Web Services Proxy
Overview
httpj:engine-factory element). There is just one slightly subtle aspect to this, however: you need to understand how the Camel CXF endpoint gets associated with the SSL/TLS configuration details.
Implicit configuration
httpj:engine-factory element in Spring) does not explicitly reference the WS endpoints it contains and the WS endpoints do not explicitly reference the Jetty container either. The connection between the Jetty container and its contained endpoints is established implicitly, in that they are both configured to use the same TCP port, as illustrated by Figure 7.2, “WS Endpoint Implicitly Configured by httpj:engine-factory Element”.
Figure 7.2. WS Endpoint Implicitly Configured by httpj:engine-factory Element

httpj:engine-factory element is established as follows:
- The Spring container loads and parses the file containing the
httpj:engine-factoryelement. - When the
httpj:engine-factorybean is created, a corresponding entry is created in the registry, storing a reference to the bean. Thehttpj:engine-factorybean is also used to initialize a Jetty container that listens on the specified TCP port. - When the WS endpoint is created, it scans the registry to see if it can find a
httpj:engine-factorybean with the same TCP port as the TCP port in the endpoint's address URL. - If one of the beans matches the endpoint's TCP port, the WS endpoint installs itself into the corresponding Jetty container. If the Jetty container has SSL/TLS enabled, the WS endpoint shares those security settings.
Steps to add SSL/TLS security to the Jetty container
Add certificates to the bundle resources
InstallDir/extras/ directory), you will find the sample certificates in the CXFInstallDir/samples/wsdl_first_https/src/main/config directory.
clientKeystore.jks and serviceKeystore.jks keystores from the CXFInstallDir/samples/wsdl_first_https/src/main/config directory to the CamelInstallDir/examples/camel-example-cxf-proxy/src/main/resources/certs directory (you must first create the certs sub-directory).
Modify POM to switch off resource filtering
.jks files in Maven, open the project POM file, CamelInstallDir/examples/camel-example-cxf-proxy/pom.xml, with a text editor and add the following resources element as a child of the build element:
<?xml version="1.0" encoding="UTF-8"?>
...
<project ...>
...
<build>
<plugins>
...
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/*.jks</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*.jks</include>
</includes>
</resource>
</resources>
</build>
</project>Instantiate the CXF Bus
httpj:engine-factory element in the next step). Edit the camel-config.xml file in the src/main/resources/META-INF/spring directory, adding the cxfcore:bus element as a child of the beans element, as follows:
<beans ... >
...
<cxfcore:bus/>
...
</beans>cxfcore: namespace prefix will be defined in a later step.
Add the httpj:engine-factory element to Spring configuration
camel-config.xml file in the src/main/resources/META-INF/spring directory, adding the httpj:engine-factory element as shown in Example 7.2, “httpj:engine-factory Element with SSL/TLS Enabled”.
required attribute of the sec:clientAuthentication element is set to false, which means that a connecting client is not required to present an X.509 certificate to the server during the SSL/TLS handshake (although it may do so, if it has such a certificate).
Example 7.2. httpj:engine-factory Element with SSL/TLS Enabled
<beans ... >
...
<httpj:engine-factory bus="cxf">
<httpj:engine port="${proxy.port}">
<httpj:tlsServerParameters secureSocketProtocol="TLSv1">
<sec:keyManagers keyPassword="skpass">
<sec:keyStore resource="certs/serviceKeystore.jks" password="sspass" type="JKS"/>
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore resource="certs/serviceKeystore.jks" password="sspass" type="JKS"/>
</sec:trustManagers>
<sec:cipherSuitesFilter>
<sec:include>.*_WITH_3DES_.*</sec:include>
<sec:include>.*_WITH_DES_.*</sec:include>
<sec:exclude>.*_WITH_NULL_.*</sec:exclude>
<sec:exclude>.*_DH_anon_.*</sec:exclude>
</sec:cipherSuitesFilter>
<sec:clientAuthentication want="true" required="false"/>
</httpj:tlsServerParameters>
</httpj:engine>
</httpj:engine-factory>
</beans>secureSocketProtocol to TLSv1 on the server side, in order to protect against the Poodle vulnerability (CVE-2014-3566)
Define the cxfcore:, sec: and httpj: prefixes
cxfcore:, sec: and httpj: namespace prefixes, which appear in the definitions of the cxfcore:bus element and the httpj:engine-factory element, by adding the following highlighted lines to the beans element in the camel-config.xml file:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:cxfcore="http://cxf.apache.org/core"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http-jetty/configuration http://cxf.apache.org/schemas/configuration/http-jetty.xsd
">http://cxf.apache.org/configuration/security schema and the http://cxf.apache.org/transports/http-jetty/configuration schema in the xsi:schemaLocation attribute. These will not automatically be provided by the OSGi container.
Modify proxy address URL to use HTTPS
cxf:cxfEndpoint element in the camel-config.xml file. By default, this proxy endpoint is configured to use the HTTP protocol. You must modify the address URL to use the secure HTTPS protocol instead, however. In the camel-config.xml file, edit the address attribute of the cxf:cxfEndpoint element, replacing the http: prefix by the https: prefix, as shown in the following fragment:
<beans ...>
...
<cxf:cxfEndpoint id="reportIncident"
address="https://localhost:${proxy.port}/camel-example-cxf-proxy/webservices/incident"
endpointName="s:ReportIncidentEndpoint"
serviceName="s:ReportIncidentEndpointService"
wsdlURL="etc/report_incident.wsdl"
xmlns:s="http://reportincident.example.camel.apache.org"/>
...
</beans>${proxy.port} (which has the value 9080 by default). This TCP port value is the same as the value set for the Jetty container (configured by the http:engine-factory element), thus ensuring that this endpoint is deployed into the Jetty container. The attributes of the cxf:cxfEndpoint specify the WSDL addressing details as described in the section called “WSDL addressing details”:
-
serviceName - Specifies the WSDL service name.
-
endpointName - Specifies the WSDL port name.
-
address - Specifies the address URL of the proxy Web service.
7.3. Deploying the Apache Camel Route
Overview
RealWebServicesBean bean) is ready for deployment into the OSGi container.
Prerequisites
Steps to deploy the Camel route
Build the demonstration
CamelInstallDir/examples/camel-example-cxf-proxy, and enter the following command:
mvn install -Dmaven.test.skip=true
Start the OSGi container
./fuse
Install the required features
camel-cxf feature, which defines the bundles required for the Camel/CXF component, is not installed by default. To install the camel-cxf feature, enter the following console command:
JBossFuse:karaf@root> features:install camel-cxf
camel-http feature, which defines the bundles required for the Camel/HTTP component. To install the camel-http feature, enter the following console command:
JBossFuse:karaf@root> features:install camel-http
Deploy the bundle
camel-example-cxf-proxy bundle, by entering the following console command:
JBossFuse:karaf@root> install -s mvn:org.apache.camel/camel-example-cxf-proxy/2.17.0.redhat-630187
install, rather than using hot deploy, so that you can see the bundle output on the console screen.
mvn URL handler, see section "Mvn URL Handler" in "Deploying into Apache Karaf" for details of how to set it up.
Check the console output
JBossFuse:karaf@root> Starting real web service... Started real web service at: http://localhost:9081/real-webservice
7.4. Securing the Web Services Client
Overview
src/test directory. This means that the client can easily be run using the Maven command, mvn test. To enable SSL/TLS security on the client, the Java implementation of the test client is completely replaced and a Spring file, containing the SSL/TLS configuration, is added to the src/test/resources/META-INF/spring directory. Before describing the steps you need to perform to set up the client, this section explains some details of the client's Java code and Spring configuration.
Implicit configuration
https:, most of the configuration to enable SSL/TLS security on a client proxy is contained in a http:conduit element in Spring configuration. The way in which this configuration is applied to the client proxy, however, is potentially confusing, for the following reason: the http:conduit element does not explicitly reference the client proxy and the client proxy does not explicitly reference the http:conduit element. The connection between the http:conduit element and the client proxy is established implicitly, in that they both reference the same WSDL port, as illustrated by Figure 7.3, “Client Proxy Implicitly Configured by http:conduit Element”.
Figure 7.3. Client Proxy Implicitly Configured by http:conduit Element

http:conduit element is established as follows:
- The client loads and parses the Spring configuration file containing the
http:conduitelement. - When the
http:conduitbean is created, a corresponding entry is created in the registry, which stores a reference to the bean under the specified WSDL port name (where the name is stored in QName format). - When the JAX-WS client proxy is created, it scans the registry to see if it can find a
http:conduitbean associated with the proxy's WSDL port name. If it finds such a bean, it automatically injects the configuration details into the proxy.
Certificates needed on the client side
clientKeystore.jks keystore file from the src/main/resources/certs directory. This keystore contains two entries, as follows:
- Trusted cert entry
- A trusted certificate entry containing the CA certificate that issued and signed both the server certificate and the client certificate.
- Private key entry
- A private key entry containing the client's own X.509 certificate and private key. In fact, this certificate is not strictly necessary to run the current example, because the server does not require the client to send a certificate during the TLS handshake (see Example 7.2, “httpj:engine-factory Element with SSL/TLS Enabled”).
Loading Spring definitions into the client
org.apache.cxf.bus.spring.SpringBusFactory class.
META-INF/spring/cxf-client.xml, and create an Apache CXF Bus object that incorporates those definitions:
// Java
import org.apache.cxf.bus.spring.SpringBusFactory;
...
protected void startCxfBus() throws Exception {
bf = new SpringBusFactory();
Bus bus = bf.createBus("META-INF/spring/cxf-client.xml");
bf.setDefaultBus(bus);
}Creating the client proxy
JaxWsProxyFactoryBean, to create a proxy.
// Java
import javax.xml.ws.Service;
import org.apache.camel.example.reportincident.ReportIncidentEndpoint;
...
// create the webservice client and send the request
Service s = Service.create(SERVICE_NAME);
s.addPort(
PORT_NAME,
"http://schemas.xmlsoap.org/soap/",
ADDRESS_URL
);
ReportIncidentEndpoint client =
s.getPort(PORT_NAME, ReportIncidentEndpoint.class);JaxWsProxyFactoryBean approach to create a proxy, because a proxy created in this way fails to find the HTTP conduit settings specified in the Spring configuration file.
SERVICE_NAME and PORT_NAME constants are the QNames of the WSDL service and the WSDL port respectively, as defined in Example 7.1, “The ReportIncidentEndpointService WSDL Service”. The ADDRESS_URL string has the same value as the proxy Web service address and is defined as follows:
private static final String ADDRESS_URL = "https://localhost:9080/camel-example-cxf-proxy/webservices/incident";
https, which selects HTTP over SSL/TLS.
Steps to add SSL/TLS security to the client
Create the Java client as a test case
ReportIncidentRoutesTest.java, in the src/test/java/org/apache/camel/example/reportincident sub-directory of the examples/camel-example-cxf-proxy demonstration.
CamelInstallDir/examples/camel-example-cxf-proxy demonstration, go to the src/test/java/org/apache/camel/example/reportincident sub-directory, move the existing ReportIncidentRoutesTest.java file to a backup location, then create a new ReportIncidentRoutesTest.java file and paste the code from Example 7.3, “ReportIncidentRoutesTest Java client” into this file.
Example 7.3. ReportIncidentRoutesTest Java client
// Java
package org.apache.camel.example.reportincident;
import org.apache.camel.spring.Main;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.junit.Test;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBusFactory;
import org.apache.camel.example.reportincident.ReportIncidentEndpoint;
import org.apache.camel.example.reportincident.ReportIncidentEndpointService;
import static org.junit.Assert.assertEquals;
/**
* Unit test of our routes
*/
public class ReportIncidentRoutesTest {
private static final QName SERVICE_NAME
= new QName("http://reportincident.example.camel.apache.org", "ReportIncidentEndpointService");
private static final QName PORT_NAME =
new QName("http://reportincident.example.camel.apache.org", "ReportIncidentEndpoint");
private static final String WSDL_URL = "file:src/main/resources/etc/report_incident.wsdl";
// should be the same address as we have in our route
private static final String ADDRESS_URL = "https://localhost:9080/camel-example-cxf-proxy/webservices/incident";
protected SpringBusFactory bf;
protected void startCxfBus() throws Exception {
bf = new SpringBusFactory();
Bus bus = bf.createBus("META-INF/spring/cxf-client.xml");
bf.setDefaultBus(bus);
}
@Test
public void testRendportIncident() throws Exception {
startCxfBus();
runTest();
}
protected void runTest() throws Exception {
// create input parameter
InputReportIncident input = new InputReportIncident();
input.setIncidentId("123");
input.setIncidentDate("2008-08-18");
input.setGivenName("Claus");
input.setFamilyName("Ibsen");
input.setSummary("Bla");
input.setDetails("Bla bla");
input.setEmail("davsclaus@apache.org");
input.setPhone("0045 2962 7576");
// create the webservice client and send the request
Service s = Service.create(SERVICE_NAME);
s.addPort(PORT_NAME, "http://schemas.xmlsoap.org/soap/", ADDRESS_URL);
ReportIncidentEndpoint client = s.getPort(PORT_NAME, ReportIncidentEndpoint.class);
OutputReportIncident out = client.reportIncident(input);
// assert we got a OK back
assertEquals("OK;456", out.getCode());
}
}Add the http:conduit element to Spring configuration
http:conduit element for the ReportIncidentEndpoint WSDL port. The http:conduit element is configured to enable SSL/TLS security for any client proxies that use the specified WSDL port.
src/test/resources/META-INF/spring sub-directory, use your favorite text editor to create the file, cxf-client.xml, and then paste the contents of Example 7.4, “http:conduit Element with SSL/TLS Enabled” into the file.
Example 7.4. http:conduit Element with SSL/TLS Enabled
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns:http="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://cxf.apache.org/configuration/security http://cxf.apache.org/schemas/configuration/security.xsd
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
">
<http:conduit name="{http://reportincident.example.camel.apache.org}ReportIncidentEndpoint.http-conduit">
<http:tlsClientParameters disableCNCheck="true" secureSocketProtocol="TLSv1">
<sec:keyManagers keyPassword="ckpass">
<sec:keyStore password="cspass" type="JKS"
resource="certs/clientKeystore.jks" />
</sec:keyManagers>
<sec:trustManagers>
<sec:keyStore password="cspass" type="JKS"
resource="certs/clientKeystore.jks" />
</sec:trustManagers>
<sec:cipherSuitesFilter>
<sec:include>.*_WITH_3DES_.*</sec:include>
<sec:include>.*_WITH_DES_.*</sec:include>
<sec:exclude>.*_WITH_NULL_.*</sec:exclude>
<sec:exclude>.*_DH_anon_.*</sec:exclude>
</sec:cipherSuitesFilter>
</http:tlsClientParameters>
</http:conduit>
</beans>- The
http:andsec:namespace prefixes are needed to define thehttp:conduitelement. In thexsi:schemaLocationelement, it is also essential to specify the locations of the correspondinghttp://cxf.apache.org/configuration/securityandhttp://cxf.apache.org/transports/http/configurationnamespaces. - The
disableCNCheckattribute of thehttp:tlsClientParameterselement is set totrue. This means that the client does not check whether the Common Name in the server's X.509 certificate matches the server hostname. For more details, see Appendix A, Managing Certificates.ImportantDisabling the CN check is not recommended in a production deployment. - In the
sec:keystoreelements, the certificate locations are specified using theresourceattribute, which finds the certificates on the classpath. When Maven runs the test, it automatically makes the contents ofsrc/main/resourcesavailable on the classpath, so that the certificates can be read from thesrc/main/resources/certsdirectory.NoteYou also have the option of specifying a certificate location using thefileattribute, which looks in the filesystem. But theresourceattribute is more suitable for use with applications packaged in bundles. - The
sec:cipherSuitesFilterelement is configured to exclude cipher suites matching.*_WITH_NULL_.*and.*_DH_anon_.*. These cipher suites are effectively incomplete and are not intended for normal use.ImportantIt is recommended that you always exclude the ciphers matching.*_WITH_NULL_.*and.*_DH_anon_.*. - The
secureSocketProtocolattribute should be set to TLSv1, to match the server protocol and to ensure that the SSLv3 protocol is not used (POODLE security vulnerability (CVE-2014-3566)).
Run the client
CamelInstallDir/examples/camel-example-cxf-proxy, and enter the following Maven command:
mvn test
Incident was 123, changed to 456 Invoked real web service: id=456 by Claus Ibsen
Chapter 8. Securing the Management Console
Abstract
Access-Control-Allow-Origin header for the JBoss Fuse Management Console permits unrestricted sharing. To restrict access to the JBoss Fuse Management Console, create an access management file which contains a list of the allowed origin URLs. To implement the restrictions, add a system property that references the access management file
8.1. Controlling Access to the Fuse Management Console
access-management.xml in <installDir>/etc/. The access management file must contain <allow-origin> sections within a <cors> section. The <allow-origin> section can contain the origin URL provided by browsers with the Origin: header, or a wildcard specification with *. For example:
<cors> <!-- Allow cross origin access from www.jolokia.org ... --> <allow-origin>http://www.jolokia.org</allow-origin> <!-- ... and all servers from jmx4perl.org with any protocol --> <allow-origin>*://*.jmx4perl.org</allow-origin> <!-- optionally allow access to web console from localhost --> <allow-origin>http://localhost:8181/*</allow-origin> <!-- Check for the proper origin on the server side, too --> <strict-checking/> </cors>
./bin/setenv, adding the path to the access management file.
export EXTRA_JAVA_OPTS='-Djolokia.policyLocation=file:etc/access-management.xml'
./bin/fuse is executed, the access management file is referenced and used to restrict access to the JBoss Fuse Management Console.
Chapter 9. LDAP Authentication Tutorial
Abstract
9.1. Tutorial Overview
Goals
- Install 389 Directory Server
- Add user entries to the LDAP server
- Add groups to manage security roles
- Configure JBoss Fuse to use LDAP authentication
- Configure JBoss Fuse to use roles for authorization
- Configure SSL/TLS connections to the LDAP server
9.2. Set-up a Directory Server and Console
Overview
Prerequisites
fedoraproject.org site.
Install 389 Directory Server
- On Red Hat Enterprise Linux and Fedora platforms, use the standard
yumpackage management utility to install 389 Directory Server. Enter the following command at a command prompt (you must have administrator privileges on your machine):sudo yum install 389-ds
NoteThe required389-dsand389-consoleRPM packages are available for Fedora, RHEL6+EPEL, and CentOS7+EPEL platforms. At the time of writing, the389-consolepackage is not yet available for RHEL 7. - After installing the 389 directory server packages, enter the following command to configure the directory server:
sudo setup-ds-admin.pl
The script is interactive and prompts you to provide the basic configuration settings for the 389 directory server. When the script is complete, it automatically launches the 389 directory server in the background. - For more details about how to install 389 Directory Server, see the Download page.
Install 389 Management Console
- On Red Hat Enterprise Linux and Fedora platforms—use the standard
yumpackage management utility to install the 389 Management Console. Enter the following command at a command prompt (you must have administrator privileges on your machine):sudo yum install 389-console
Connect the console to the server
- Enter the following command to start up the 389 Management Console:
389-console
- A login dialog appears. Fill in the LDAP login credentials in the User ID and Password fields, and customize the hostname in the Administration URL field to connect to your 389 management server instance (port
9830is the default port for the 389 management server instance).
- The 389 Management Console window appears. Select the Servers and Applications tab.
- In the left-hand pane, drill down to the Directory Server icon.

- Select the Directory Server icon in the left-hand pane and click Open, to open the 389 Directory Server Console.
- In the 389 Directory Server Console, click the Directory tab, to view the Directory Information Tree (DIT).
- Expand the root node,
YourDomain(usually named after a hostname, and shown aslocaldomainin the following screenshot), to view the DIT.
9.3. Add User Entries to the Directory Server
Overview
Alternative to adding user entries
roles.mapping property in the LDAPLoginModule configuration, instead of creating new entries. For details, see Section 2.1.7, “JAAS LDAP Login Module”.
Goals
Adding user entries
- Ensure that the LDAP server and console are running. See Section 9.2, “Set-up a Directory Server and Console”.
- In the Directory Server Console, click on the Directory tab, and drill down to the People node, under the
YourDomainnode (whereYourDomainis shown aslocaldomainin the following screenshots).
- Right-click the People node, and select → from the context menu, to open the Create New User dialog.
- Select the tab in the left-hand pane of the Create New User dialog.
- Fill in the fields of the User tab, as follows:
- Set the First Name field to
John. - Set the Last Name field to
Doe. - Set the User ID field to
jdoe. - Enter the password,
secret, in the Password field. - Enter the password,
secret, in the Confirm Password field.
- Click .
- In Step 5.e, use
janedoefor the new user's User ID and use the password,secret, for the password fields. - In Step 5.e, use
criderfor the new user's User ID and use the password,secret, for the password fields.
Adding groups for the roles
- In the Directory tab of the Directory Server Console, drill down to the Groups node, under the
YourDomainnode. - Right-click the Groups node, and select → from the context menu, to open the Create New Group dialog.
- Select the tab in the left-hand pane of the Create New Group dialog.
- Fill in the fields of the General tab, as follows:
- Set the Group Name field to
Administrator. - Optionally, enter a description in the Description field.

- Select the tab in the left-hand pane of the Create New Group dialog.

- Click Add to open the Search users and groups dialog.
- In the Search field, select
Usersfrom the drop-down menu, and click the Search button.
- From the list of users that is now displayed, select
John Doe. - Click , to close the Search users and groups dialog.
- Click , to close the Create New Group dialog.
- In Step 8, select
Jane Doe. - In Step 8, select
Camel Rider.
9.4. Enable LDAP Authentication in the OSGi Container
Overview
karaf realm, so that the container authenticates credentials based on user entries stored in the X.500 directory server.
References
- LDAPLoginModule options—are described in detail in Section 2.1.7, “JAAS LDAP Login Module”.
- Configurations for other directory servers—this tutorial covers only 389-DS. For details of how to configure other directory servers, such as Microsoft Active Directory, see the section called “Filter settings for different directory servers”.
Procedure for standalone OSGi container
- Ensure that the X.500 directory server is running.
- Start Red Hat JBoss Fuse by entering the following command in a terminal window:
./bin/fuse
- Create a file called
ldap-module.xml. - Copy Example 9.1, “JAAS Realm for Standalone” into
ldap-module.xml.Example 9.1. JAAS Realm for Standalone
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0" xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"> <jaas:config name="karaf" rank="200"> <jaas:module flags="required" className="org.apache.karaf.jaas.modules.ldap.LDAPLoginModule"> initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory connection.url=ldap://Hostname:Port connection.username=cn=Directory Manager connection.password=LDAPPassword connection.protocol= user.base.dn=ou=People,dc=localdomain user.filter=(&(objectClass=inetOrgPerson)(uid=%u)) user.search.subtree=true role.base.dn=ou=Groups,dc=localdomain role.name.attribute=cn role.filter=(uniquemember=%fqdn) role.search.subtree=true authentication=simple </jaas:module> </jaas:config> </blueprint>You must customize the following settings in theldap-module.xmlfile:- connection.url
- Set this URL to the actual location of your directory server instance. Normally, this URL has the format,
ldap://Hostname:Port. For example, the default port for the 389 Directory Server is IP port389. - connection.username
- Specifies the username that is used to authenticate the connection to the directory server. For 389 Directory Server, the default is usually
cn=Directory Manager. - connection.password
- Specifies the password part of the credentials for connecting to the directory server.
- authentication
- You can specify either of the following alternatives for the authentication protocol:
simpleimplies that user credentials are supplied and you are obliged to set theconnection.usernameandconnection.passwordoptions in this case.noneimplies that authentication is not performed. There is no need to set theconnection.usernameandconnection.passwordoptions in this case.
This login module creates a JAAS realm calledkaraf, which is the same name as the default JAAS realm used by JBoss Fuse. By redefining this realm with arankattribute value greater than0, it overrides the standardkarafrealm which has the rank0(but note that in the context of Fabric, the defaultkarafrealm has a rank of99, so you need to define a new realm with rank100or greater to override the default realm in a fabric).For more details about how to configure JBoss Fuse to use LDAP, see Section 2.1.7, “JAAS LDAP Login Module”.ImportantWhen setting the JAAS properties above, do not enclose the property values in double quotes. - To deploy the new LDAP module, copy the
ldap-module.xmlinto the JBoss Fusedeploy/directory.The LDAP module is automatically activated.NoteSubsequently, if you need to undeploy the LDAP module, you can do so by deleting theldap-module.xmlfile from thedeploy/directory while the Karaf container is running.
Procedure for a Fabric
- Ensure that the X.500 directory server is running.
- If your local Fabric container is not already running, start it now, by entering the following command in a terminal window:
./bin/fuse
NoteIf the Fabric container you want to connect to is running on a remote host, you can connect to it using theclientcommand-line utility in theInstallDir/bindirectory. - Create a new version of the Fabric profile data, by entering the following console command:
JBossFuse:karaf@root> version-create Created version: 1.1 as copy of: 1.0
NoteIn effect, this command creates a new branch named1.1in the Git repository underlying the ZooKeeper registry. - Create the new profile resource,
ldap-module.xml(a Blueprint configuration file), in version1.1of thedefaultprofile, as follows:JBossFuse:karaf@root> profile-edit --resource ldap-module.xml default 1.1
The built-in profile editor opens automatically, which you can use to edit the contents of theldap-module.xmlresource. - Copy Example 9.2, “JAAS Realm for Fabric” into the
ldap-module.xmlresource, customizing the configuration properties, as necessary.Example 9.2. JAAS Realm for Fabric
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0" xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"> <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.0.0"> <command name="jasypt/encrypt"> <action class="io.fabric8.fabric.jaas.EncryptPasswordCommand" /> </command> </command-bundle> <!-- AdminConfig property place holder for the org.apache.karaf.jaas --> <cm:property-placeholder persistent-id="io.fabric8.fabric.jaas" update-strategy="reload"> <cm:default-properties> <cm:property name="encryption.name" value="" /> <cm:property name="encryption.enabled" value="true" /> <cm:property name="encryption.prefix" value="{CRYPT}" /> <cm:property name="encryption.suffix" value="{CRYPT}" /> <cm:property name="encryption.algorithm" value="MD5" /> <cm:property name="encryption.encoding" value="hexadecimal" /> </cm:default-properties> </cm:property-placeholder> <jaas:config name="karaf" rank="200"> <jaas:module className="io.fabric8.jaas.ZookeeperLoginModule" flags="sufficient"> path = /fabric/authentication/users encryption.name = ${encryption.name} encryption.enabled = ${encryption.enabled} encryption.prefix = ${encryption.prefix} encryption.suffix = ${encryption.suffix} encryption.algorithm = ${encryption.algorithm} encryption.encoding = ${encryption.encoding} </jaas:module> <jaas:module className="org.apache.karaf.jaas.modules.ldap.LDAPLoginModule" flags="sufficient"> initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory connection.url=ldap://Hostname:Port connection.username=cn=Directory Manager connection.password=LDAPPassword connection.protocol= user.base.dn=ou=People,dc=localdomain user.filter=(&(objectClass=inetOrgPerson)(uid=%u)) user.search.subtree=true role.base.dn=ou=Groups,dc=localdomain role.name.attribute=cn role.filter=(uniquemember=%fqdn) role.search.subtree=true authentication=simple </jaas:module> </jaas:config> <!-- The Backing Engine Factory Service for the ZookeeperLoginModule --> <service interface="org.apache.karaf.jaas.modules.BackingEngineFactory"> <bean class="io.fabric8.jaas.ZookeeperBackingEngineFactory" /> </service> </blueprint>You must customize the following settings in theldap-module.xmlfile:- connection.url
- Set this URL to the actual location of your directory server instance. Normally, this URL has the format,
ldap://Hostname:Port. You must be sure to use a hostname that is accessible to all of the containers in the fabric (hence, you cannot uselocalhostas the hostname here). The default port for the 389 Directory Server is IP port389. - connection.username
- Specifies the username that is used to authenticate the connection to the directory server. For 389 Directory Server, the default is usually
cn=Directory Manager. - connection.password
- Specifies the password part of the credentials for connecting to the directory server.
- authentication
- You can specify either of the following alternatives for the authentication protocol:
simpleimplies that user credentials are supplied and you are obliged to set theconnection.usernameandconnection.passwordoptions in this case.noneimplies that authentication is not performed. There is no need to set theconnection.usernameandconnection.passwordoptions in this case.
This login module creates a JAAS realm calledkaraf, which is the same name as the default JAAS realm used by Red Hat JBoss Fuse. By redefining this realm with arankof200, it overrides all of the previously installedkarafrealms (in the context of Fabric, you need to override the defaultZookeeperLoginModule, which has a rank of99).ImportantPay particular attention to the value of therankto ensure that it is higher than all previously installedkarafrealms. If therankis not sufficiently high, the new realm will not be used by the fabric.ImportantWhen setting the JAAS properties above, do not enclose the property values in double quotes.ImportantIn a Fabric, the Zookeeper login module must be enabled, in addition to the LDAP login module. This is because Fabric uses the Zookeeper login module internally, to support authentication between ensemble servers. With the configuration shown here, Fabric tries to authenticate first of all against the Zookeeper login module and, if that step fails, it tries to authenticate against the LDAP login module. - Save and close the
ldap-module.xmlresource by typing Ctrl-S and Ctrl-X. - Edit the agent properties of version 1.1 of the
defaultprofile, adding an instruction to deploy the Blueprint resource file defined in the previous step. Enter the following console command:JBossFuse:karaf@root> profile-edit default 1.1
The built-in profile editor opens automatically. Add the following line to the agent properties:bundle.ldap-realm=blueprint:profile:ldap-module.xml
Save and close the agent properties by typing Ctrl-S and Ctrl-X. - The new LDAP realm is not activated, until you upgrade a container to use the new version,
1.1. To activate LDAP on a single container (for example, on a container calledroot), enter the following console command:JBossFuse:karaf@root> container-upgrade 1.1 root
To activate LDAP on all containers in the fabric, enter the following console command:JBossFuse:karaf@root> container-upgrade --all 1.1
ImportantIt is advisable to upgrade just a single container initially, to make sure that everything is working properly. This is particularly important, if you have only remote access to the fabric: if you upgrade all of the containers at once, you might not be able to reconnect to the fabric. - To check that the LDAP realm is activated, enter the following console command:
JBossFuse:karaf@root> jaas-realms Index Realm Module Class 1 karaf org.apache.karaf.jaas.modules.ldap.LDAPLoginModuleIf the output of this command lists theZookeperLoginModule, this means the LDAP realm is not yet activated. It might take a minute or so for activation of the LDAP realm to complete.
Test the LDAP authentication
client utility, as follows:
- Open a new command prompt.
- Change directory to the JBoss Fuse
InstallDir/bindirectory. - Enter the following command to log on to the running container instance using the identity
jdoe:client -u jdoe -p secretYou should successfully log into the container's remote console. At the command console, typejaas:followed by the [Tab] key (to activate content completion):JBossFuse:jdoe@root> jaas: jaas:cancel jaas:groupadd jaas:groupcreate jaas:groupdel jaas:grouproleadd jaas:grouproledel jaas:groups jaas:manage jaas:pending jaas:realms jaas:roleadd jaas:roledel jaas:update jaas:useradd jaas:userdel jaas:users
You should see thatjdoehas access to all of thejaascommands (which is consistent with theAdministratorrole). - Log off the remote console by entering the logout command.
- Enter the following command to log on to the running container instance using the identity
janedoe:client -u janedoe -p secretYou should successfully log into the container's remote console. At the command console, typejaas:followed by the [Tab] key (to activate content completion):JBossFuse:janedoe@root> jaas: jaas:cancel jaas:groupadd jaas:groupcreate jaas:groupdel jaas:grouproleadd jaas:grouproledel jaas:groups jaas:manage jaas:pending jaas:realms jaas:roleadd jaas:roledel jaas:useradd jaas:userdel jaas:users
You should see thatjanedoehas access to almost all of thejaascommands, except forjaas:update(which is consistent with theDeployerrole). - Log off the remote console by entering the logout command.
- Enter the following command to log on to the running container instance using the identity
crider:client -u crider -p secretYou should successfully log into the container's remote console. At the command console, typejaas:followed by the [Tab] key (to activate content completion):JBossFuse:janedoe@root> jaas: jaas:groupcreate jaas:groups jaas:realms
You should see thatcriderhas access to only three of thejaascommands (which is consistent with theMonitorrole). - Log off the remote console by entering the logout command.
9.5. Enable SSL/TLS on the LDAP Connection
Overview
10636. The directory server automatically generates a self-signed X.509 certificate which it uses to identify itself during the SSL/TLS handshake.
Procedure
- Obtain a copy of the server's self-signed certificate.
- Using a Web browser , navigate to the following URL:
https://localhost:10636
ImportantRemember to specify the scheme ashttps, not justhttp.The Web browser now signals an error, because the certificate it receives from the server is untrusted. In the case of Firefox, you will see the following error in the browser window:Figure 9.1. Obtaining the Certificate

- Click I Understand the Risks.
- Click Add Exception.The Add Security Exception dialog opens.
- In the Add Security Exception dialog, click .
- Click .The Certificate Viewer dialog opens.
- In the Certificate Viewer dialog, select the Details tab.
- Click .The Save Certificate To File dialog opens.
- In the Save Certificate To File dialog, use the drop-down list to set the Save as type to X.509 Certificate (DER).
- Save the certificate,
ApacheDS.der, to a convenient location on the filesystem.
- Convert the DER format certificate into a keystore.
- From a command prompt, change directory to the directory where you have stored the
ApacheDS.derfile. - Enter the following
keytoolcommand:keytool -import -file ApacheDS.der -alias server -keystore truststore.ks -storepass secret
- Copy the newly created keystore file,
truststore.ks, into the JBoss Fuseetc/directory. - Open the
ldap-module.xmlfile you created in Section 9.4, “Enable LDAP Authentication in the OSGi Container” in a text editor. - Edit the connection.url to use ldaps://localhost:10636.
- Add the highlighted lines in Example 9.3, “LDAP Configuration for Using SSL/TLS”.
Example 9.3. LDAP Configuration for Using SSL/TLS
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0" xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0"> <!-- Example configuration for using LDAP based authentication. This example uses an JAAS LoginModule from Karaf. It supports authentication of users and also supports retrieving user roles for authorization. Note, this config overwrite the default karaf domain that is defined inside some JAR file by using a rank > 99 attribute. --> <jaas:config name="karaf" rank="200"> <jaas:module className="org.apache.karaf.jaas.modules.ldap.LDAPLoginModule" flags="required"> initialContextFactory=com.sun.jndi.ldap.LdapCtxFactory connection.username=uid=admin,ou=system connection.password=secret connection.protocol= connection.url = ldaps://localhost:10636 user.base.dn = ou=users,ou=system user.filter = (uid=%u) user.search.subtree = true role.base.dn = ou=users,ou=system role.filter = (uid=%u) role.name.attribute = ou role.search.subtree = true authentication = simple ssl.protocol=TLSv1 ssl.truststore=truststore ssl.algorithm=PKIX </jaas:module> </jaas:config> <jaas:keystore name="truststore" path="file:///InstallDir/etc/truststore.ks" keystorePassword="secret" /> </blueprint> - Copy the
ldap-module.xmlfile into the Red Hat JBoss Fusedeploy/directory.The LDAP module is automatically activated. - Test the new LDAP realm by connecting to the running container using the JBoss Fuse
clientutility.- Open a new command prompt.
- Change to the JBoss Fuse install directory.
- Enter the following command to log on to the running container instance using the identity
jdoe:client -u jdoe -p secretYou should successfully log into the container's remote console becausejdoedoes have theadminrole.
Tightening up security
- Delete all entries from the Red Hat JBoss Fuse's
etc/users.propertiesfile.If theldap-module.xmlbundle fails to start up properly, JAAS authentication reverts to the built-in file-basedkarafrealm, which takes its user data from theusers.propertiesfile. - Disable the insecure LDAP endpoint on the Apache Directory Server.
- Create and deploy a properly signed X.509 certificate on the Apache Directory Server.
- Make sure that the LDAP server is configured to use the TLSv1 protocol (POODLE vulnerability). Do not enable the SSLv3 protocol. For more information, see Poodle vulnerability (CVE-2014-3566).
Apache Directory Server Reference
Appendix A. Managing Certificates
Abstract
A.1. What is an X.509 Certificate?
Role of certificates
Integrity of the public key
Digital signatures
Contents of an X.509 certificate
- A subject distinguished name (DN) that identifies the certificate owner.
- The public key associated with the subject.
- X.509 version information.
- A serial number that uniquely identifies the certificate.
- An issuer DN that identifies the CA that issued the certificate.
- The digital signature of the issuer.
- Information about the algorithm used to sign the certificate.
- Some optional X.509 v.3 extensions; for example, an extension exists that distinguishes between CA certificates and end-entity certificates.
Distinguished names
A.2. Certification Authorities
A.2.1. Introduction to Certificate Authorities
- commercial CAs are companies that sign certificates for many systems.
- private CAs are trusted nodes that you set up and use to sign certificates for your system only.
A.2.2. Commercial Certification Authorities
Signing certificates
Advantages of commercial CAs
Criteria for choosing a CA
- What are the certificate-signing policies of the commercial CAs?
- Are your applications designed to be available on an internal network only?
- What are the potential costs of setting up a private CA compared to the costs of subscribing to a commercial CA?
A.2.3. Private Certification Authorities
Choosing a CA software package
OpenSSL software package
Setting up a private CA using OpenSSL
Choosing a host for a private certification authority
Security precautions
- Do not connect the CA to a network.
- Restrict all access to the CA to a limited set of trusted users.
- Use an RF-shield to protect the CA from radio-frequency surveillance.
A.3. Certificate Chaining
Certificate chain
Figure A.1. A Certificate Chain of Depth 2

Self-signed certificate
Chain of trust
Certificates signed by multiple CAs
Figure A.2. A Certificate Chain of Depth 3

Trusted CAs
A.4. Special Requirements on HTTPS Certificates
Overview
HTTPS URL integrity check
Reference
How to specify the certificate identity
Using commonName
https://www.redhat.com/secure
C=IE,ST=Co. Dublin,L=Dublin,O=RedHat, OU=System,CN=www.redhat.com
www.redhat.com.
Using subjectAltName (multi-homed hosts)
subjectAltName certificate extension.
www.redhat.com www.jboss.org
subjectAltName that explicitly lists both of these DNS host names. If you generate your certificates using the openssl utility, edit the relevant line of your openssl.cnf configuration file to specify the value of the subjectAltName extension, as follows:
subjectAltName=DNS:www.redhat.com,DNS:www.jboss.org
subjectAltName (the subjectAltName takes precedence over the Common Name).
*, in host names. For example, you can define the subjectAltName as follows:
subjectAltName=DNS:*.jboss.org
., delimiter in front of the domain name). For example, if you specified *jboss.org, your certificate could be used on any domain that ends in the letters jboss.
A.5. Creating Your Own Certificates
Abstract
A.5.1. Install the OpenSSL Utilities
Installing OpenSSL on RHEL and Fedora platforms
yum install openssl
Source code distribution
A.5.2. Set Up a Private Certificate Authority
Overview
Steps to set up a private Certificate Authority
- Create the directory structure for the CA, as follows:
X509CA/demoCA X509CA/demoCA/private X509CA/demoCA/certs X509CA/demoCA/newcerts X509CA/demoCA/crl
- Using a text editor, create the file,
X509CA/openssl.cfg, and add the following contents to this file:Example A.1. OpenSSL Configuration
# # SSLeay example configuration file. # This is mostly being used for generation of certificate requests. # RANDFILE = ./.rnd #################################################################### [ req ] default_bits = 2048 default_keyfile = keySS.pem distinguished_name = req_distinguished_name encrypt_rsa_key = yes default_md = sha1 [ req_distinguished_name ] countryName = Country Name (2 letter code) organizationName = Organization Name (eg, company) commonName = Common Name (eg, YOUR name) #################################################################### [ ca ] default_ca = CA_default # The default ca section #################################################################### [ CA_default ] dir = ./demoCA # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. #unique_subject = no # Set to 'no' to allow creation of # several certificates with same subject. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/cacert.pem # The CA certificate serial = $dir/serial # The current serial number crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.pem# The private key RANDFILE = $dir/private/.rand # private random number file name_opt = ca_default # Subject Name options cert_opt = ca_default # Certificate field options default_days = 365 # how long to certify for default_crl_days = 30 # how long before next CRL default_md = md5 # which md to use. preserve = no # keep passed DN ordering policy = policy_anything [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optionalImportantThe precedingopenssl.cfgconfiguration file is provided as a demonstration only. In a production environment, this configuration file would need to be carefully elaborated by an engineer with a high level of security expertise, and actively maintained to protect against evolving security threats. - Initialize the
demoCA/serialfile, which must have the initial contents01(zero one). Enter the following command:echo 01 > demoCA/serial
- Initialize the
demoCA/index.txt, which must initially be completely empty. Enter the following command:touch demoCA/index.txt
- Create a new self-signed CA certificate and private key with the command:
openssl req -x509 -new -config openssl.cfg -days 365 -out demoCA/cacert.pem -keyout demoCA/private/cakey.pem
You are prompted for a pass phrase for the CA private key and details of the CA distinguished name as shown in Example A.2, “Creating a CA Certificate”.Example A.2. Creating a CA Certificate
Generating a 2048 bit RSA private key ...........................................................................+++ .................+++ writing new private key to 'demoCA/private/cakey.pem' Enter PEM pass phrase: Verifying - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) []:DE Organization Name (eg, company) []:Red Hat Common Name (eg, YOUR name) []:Scooby Doo
NoteThe security of the CA depends on the security of the private key file and the private key pass phrase used in this step.You must ensure that the file names and location of the CA certificate and private key,cacert.pemandcakey.pem, are the same as the values specified inopenssl.cfg.
A.5.3. Create a CA Trust Store File
Overview
Steps to create a CA trust store
- Assemble the collection of trusted CA certificates that you want to deploy.The trusted CA certificates can be obtained from public CAs or private CAs. The trusted CA certificates can be in any format that is compatible with the Java keystore utility; for example, PEM format. All you need are the certificates themselves—the private keys and passwords are not required.
- Add a CA certificate to the trust store using the keytool -import command.Enter the following command to add the CA certificate,
cacert.pem, in PEM format, to a JKS trust store.keytool -import -file cacert.pem -alias CAAlias -keystore truststore.ts -storepass StorePass
Wheretruststore.tsis a keystore file containing CA certificates. If this file does not already exist, the keytool command creates it. TheCAAliasis a convenient identifier for the imported CA certificate andStorePassis the password required to access the keystore file. - Repeat the previous step to add all of the CA certificates to the trust store.
A.5.4. Generate and Sign a New Certificate
Overview
Steps to generate and sign a new certificate
- Generate a certificate and private key pair using the keytool -genkeypair command, as follows:
keytool -genkeypair -keyalg RSA -dname "CN=Alice, OU=Engineering, O=Red Hat, ST=Dublin, C=IE" -validity 365 -alias alice -keypass KeyPass -keystore alice.ks -storepass StorePass
Because the specified keystore,alice.ks, did not exist prior to issuing the command implicitly creates a new keystore and sets its password toStorePass.The-dnameand-validityflags define the contents of the newly created X.509 certificate.NoteWhen specifying the certificate's Distinguished Name (through the-dnameparameter), you must be sure to observe any policy constraints specified in theopenssl.cfgfile. If those policy constraints are not heeded, you will not be able to sign the certificate using the CA (in the next steps).NoteIt is essential to generate the key pair with the-keyalg RSAoption (or a key algorithm of similar strength). The default key algorithm uses a combination of DSA encryption and SHA-1 signature. But the SHA-1 algorithm is no longer regarded as sufficiently secure and modern Web browsers will reject certificates signed using SHA-1. When you select the RSA key algorithm, thekeytoolutility uses an SHA-2 algorithm instead. - Create a certificate signing request using the keystore -certreq command.Create a new certificate signing request for the
alice.kscertificate and export it to thealice_csr.pemfile, as follows:keytool -certreq -alias alice -file alice_csr.pem -keypass KeyPass -keystore alice.ks -storepass StorePass
- Sign the CSR using the openssl ca command.Sign the CSR for the Alice certificate, using your private CA, as follows:
openssl ca -config openssl.cfg -days 365 -in alice_csr.pem -out alice_signed.pem
You will prompted to enter the CA private key pass phrase you used when creating the CA (in Step 5).For more details about the openssl ca command see http://www.openssl.org/docs/apps/ca.html#. - Convert the signed certificate to PEM only format using the openssl x509 command with the
-outformoption set toPEM. Enter the following command:openssl x509 -in alice_signed.pem -out alice_signed.pem -outform PEM
- Concatenate the CA certificate file and the converted, signed certificate file to form a certificate chain. For example, on Linux and UNIX platforms, you can concatenate the CA certificate file and the signed Alice certificate,
alice_signed.pem, as follows:cat demoCA/cacert.pem alice_signed.pem > alice.chain
- Import the new certificate's full certificate chain into the Java keystore using the keytool -import command. Enter the following command:
keytool -import -file alice.chain -keypass KeyPass -keystore alice.ks -storepass StorePass
Appendix B. ASN.1 and Distinguished Names
Abstract
B.1. ASN.1
Overview
BER
DER
References
B.2. Distinguished Names
Overview
- X.509 certificates—for example, one of the DNs in a certificate identifies the owner of the certificate (the security principal).
- LDAP—DNs are used to locate objects in an LDAP directory tree.
String representation of DN
DN string example
C=US,O=IONA Technologies,OU=Engineering,CN=A. N. Other
Structure of a DN string
OID
Attribute types
Table B.1. Commonly Used Attribute Types
| String Representation | X.500 Attribute Type | Size of Data | Equivalent OID |
|---|---|---|---|
|
C
|
countryName
|
2
|
2.5.4.6
|
|
O
|
organizationName
|
1...64
|
2.5.4.10
|
|
OU
|
organizationalUnitName
|
1...64
|
2.5.4.11
|
|
CN
|
commonName
|
1...64
|
2.5.4.3
|
| ST |
stateOrProvinceName
|
1...64
|
2.5.4.8
|
|
L
|
localityName
|
1...64
|
2.5.4.7
|
|
STREET
|
streetAddress
| ||
|
DC
|
domainComponent
| ||
|
UID
|
userid
|
AVA
<attr-type>=<attr-value>
CN=A. N. Other
2.5.4.3=A. N. Other
RDN
<attr-type>=<attr-value>[+<attr-type>=<attr-value> ...]
OU=Eng1+OU=Eng2+OU=Eng3
OU=Engineering
Index
A
- Abstract Syntax Notation One (see ASN.1)
- ASN.1, Contents of an X.509 certificate, ASN.1 and Distinguished Names
- attribute types, Attribute types
- AVA, AVA
- OID, OID
- RDN, RDN
- attribute value assertion (see AVA)
- AVA, AVA
B
- Basic Encoding Rules (see BER)
- BER, BER
C
- CA, Integrity of the public key
- choosing a host, Choosing a host for a private certification authority
- commercial CAs, Commercial Certification Authorities
- list of trusted, Trusted CAs
- multiple CAs, Certificates signed by multiple CAs
- private CAs, Private Certification Authorities
- security precautions, Security precautions
- certificates
- chaining, Certificate chain
- peer, Chain of trust
- public key, Contents of an X.509 certificate
- self-signed, Self-signed certificate
- signing, Integrity of the public key
- X.509, Role of certificates
- chaining of certificates, Certificate chain
D
- DER, DER
- Distinguished Encoding Rules (see DER)
- distinguished names
- definition, Overview
- DN
- definition, Overview
- string representation, String representation of DN
J
- JAAS
- configuration syntax, Configuring a JAAS realm
- converting to blueprint, Converting standard JAAS login properties to XML
- namespace, Namespace
- jaas:config, Configuring a JAAS realm
- jaas:module, Configuring a JAAS realm
- JMX SSL connection, enabling, Enabling Remote JMX SSL
M
- multiple CAs, Certificates signed by multiple CAs
O
- OpenSSL, OpenSSL software package
P
- peer certificate, Chain of trust
- public keys, Contents of an X.509 certificate
R
- RDN, RDN
- relative distinguished name (see RDN)
- root certificate directory, Trusted CAs
S
- self-signed certificate, Self-signed certificate
- signing certificates, Integrity of the public key
- SSLeay, OpenSSL software package
T
- trusted CAs, Trusted CAs
X
- X.500, ASN.1 and Distinguished Names
- X.509 certificate
- definition, Role of certificates
Legal Notice
Trademark Disclaimer
