WildFly 14 / JBoss EAP 7.2

For WildFly, deploy and install does not automatically configure the application server for you. Configure the application server according to instructions in the following sections.

For the oracle-specific parts in this guide we assume you have installed Oracle XE version 11g release 2 (can be downloaded from Oracle Database) on your machine and configured it to listen on port 1521

It is highly inadvisable to run your application using a root user due to risk of privilege escalation. Running your installation as root may lead root privileges being set on files which later WildFly is unable to read. It is instead recommended to run the installation with the same user as is running your application server.

Add Database Driver

For MariaDB and PostgreSQL, the database driver can be added by hot-deploying it into the deployment directory. This will be picked up by WildFly and deployed so we can create a DataSource straight away. You can use a generic name, without version number, in order to get a generic 'driver-name' for the data source command.

Example command for MariaDB:

$ cp mariadb-java-client-2.2.6.jar wildfly_home/standalone/deployments/mariadb-java-client.jar

Example command for PostgreSQL:

$ cp postgresql-42.2.5.jar wildfly_home/standalone/deployments/postgresql.jar

If you are using another type of database, copy the JDBC driver to the deployment directory and make note of the driver class and driver-name shown in the server log for later use when adding the DataSource. For example:

... INFO [org.jboss.as.connector.deployers.jdbc] (...) WFLYJCA0005: Deploying non-JDBC-compliant driver class org.postgresql.Driver (version 42.2.5)
... INFO [org.jboss.as.connector.deployers.jdbc] (...) WFLYJCA0018: Started Driver service with driver-name = postgresql-jdbc3.jar

Increase Allowed Memory Usage

By default, 1303MB of heap (RAM) is allowed to be used by the application server. This is sufficient for a small/normal installation. If you expect much traffic you can increase this memory limit by editing wildfly_home/bin/standalone.conf to increase this to a higher value, for example:

JAVA_OPTS="-Xms2048m -Xmx2048m -XX:MetaspaceSize=192M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true"

Add DataSource

To add a data source for EJBCA to use, start JBoss (with bin/standalone.sh) and run the commands in JBoss CLI according to the MariaDB, MySQL, Oracle XE, or PostgreSQL examples below.

Note that -driver-name is linked to the name of the jar file you copied in the step Add Database Driver above. The -jindi-name is linked to the database.properties value, and the default value is used in the following example.

MariaDB

For MariaDB, run the following:

> wildfly_home/bin/jboss-cli.sh -c
> data-source add --name=ejbcads --driver-name="mariadb-java-client.jar" --connection-url="jdbc:mysql://127.0.0.1:3306/ejbca" --jndi-name="java:/EjbcaDS" --use-ccm=true --driver-class="org.mariadb.jdbc.Driver" --user-name="ejbca" --password="ejbca" --validate-on-match=true --background-validation=false --prepared-statements-cache-size=50 --share-prepared-statements=true --min-pool-size=5 --max-pool-size=150 --pool-prefill=true --transaction-isolation=TRANSACTION_READ_COMMITTED --check-valid-connection-sql="select 1;"
> :reload

MySQL

For MySQL, run the following.

Note that MySQL imposes increased secure password creations and the following example uses --password="Ejbca-2020".

> data-source add --name=ejbcads --driver-name="com.mysql.jdbc.Driver" --connection-url="jdbc:mysql://127.0.0.1:3306/ejbca" --jndi-name="java:/EjbcaDS" --use-ccm=true --driver-class="com.mysql.jdbc.Driver" --user-name="ejbca" --password="Ejbca-2020" --validate-on-match=true --background-validation=false --prepared-statements-cache-size=50 --share-prepared-statements=true --min-pool-size=5 --max-pool-size=150 --pool-prefill=true --transaction-isolation=TRANSACTION_READ_COMMITTED --check-valid-connection-sql="select 1;"
> :reload

Oracle XE version 11g Release 2

For Oracle XE, run the following:

> wildfly_home/bin/jboss-cli.sh -c
> data-source add --name=ejbcads --driver-name="ojdbc8.jar" --connection-url="jdbc:oracle:thin:@127.0.0.1:1521:XE" --jndi-name="java:/EjbcaDS" --use-ccm=true --driver-class="oracle.jdbc.driver.OracleDriver" --user-name="ejbca" --password="ejbca" --validate-on-match=true --background-validation=false --prepared-statements-cache-size=50 --share-prepared-statements=true --min-pool-size=5 --max-pool-size=150 --pool-prefill=true --transaction-isolation=TRANSACTION_READ_COMMITTED --check-valid-connection-sql="select 1 from dual"
> :reload

PostgreSQL

For PostgreSQL, run the following:

> wildfly_home/bin/jboss-cli.sh -c
> data-source add --name=ejbcads --driver-name="org.postgresql.Driver" --connection-url="jdbc:postgresql://127.0.0.1/ejbca" --jndi-name="java:/EjbcaDS" --use-ccm=true --driver-name="postgresql.jar" --driver-class="org.postgresql.Driver" --user-name="ejbca_user" --password="foo123" --validate-on-match=true --background-validation=false --prepared-statements-cache-size=50 --share-prepared-statements=true --min-pool-size=5 --max-pool-size=150 --pool-prefill=true --transaction-isolation=TRANSACTION_READ_COMMITTED --check-valid-connection-sql="select 1;"
> :reload

If you are using another type of database, adapt the statement above with the correct driver-name, connection-url, driver-class and check-valid-connection-sql.

images/s/-98b7og/8401/7d0034e810b0e95b8c0694abfaf748cf5135c15a/_/images/icons/emoticons/warning.svg Wait for the reload to complete by checking the server log or the result of :read-attribute(name=server-state) before continuing.

Configure WildFly Remoting

EJBCA needs to use JBoss Remoting for the EJBCA CLI to work. Configure it to use a separate port 4447 and remove any other dependency on remoting except for what EJBCA needs.

/subsystem=remoting/http-connector=http-remoting-connector:write-attribute(name=connector-ref,value=remoting)
/socket-binding-group=standard-sockets/socket-binding=remoting:add(port=4447,interface=management)
/subsystem=undertow/server=default-server/http-listener=remoting:add(socket-binding=remoting,enable-http2=true)
/subsystem=infinispan/cache-container=ejb:remove()
/subsystem=infinispan/cache-container=server:remove()
/subsystem=infinispan/cache-container=web:remove()
/subsystem=ejb3/cache=distributable:remove()
/subsystem=ejb3/passivation-store=infinispan:remove()
:reload

images/s/-98b7og/8401/7d0034e810b0e95b8c0694abfaf748cf5135c15a/_/images/icons/emoticons/warning.svg Wait for the reload to complete by checking the server log or the result of :read-attribute(name=server-state) before continuing.

Configure Logging

Configure logging in JBoss to be able to dynamically change logging. For production systems, INFO log level is recommended:

/subsystem=logging/logger=org.ejbca:add(level=INFO)
/subsystem=logging/logger=org.cesecore:add(level=INFO)

To later enable DEBUG log level, if needed, use the following:

/subsystem=logging/logger=org.ejbca:write-attribute(name=level, value=DEBUG)
/subsystem=logging/logger=org.cesecore:write-attribute(name=level, value=DEBUG)

HTTP(S) Listener Configuration with 3-port Separation

The following covers HTTP(S) listener configuration with 3-port separation.

Remove Existing TLS and HTTP Configuration

Run the following commands in JBoss CLI to remove existing TLS and HTTP configuration (just to be safe):

$ wildfly_home/bin/jboss-cli.sh --connect
/subsystem=undertow/server=default-server/http-listener=default:remove()
/subsystem=undertow/server=default-server/https-listener=https:remove()
/socket-binding-group=standard-sockets/socket-binding=http:remove()
/socket-binding-group=standard-sockets/socket-binding=https:remove()
:reload

images/s/-98b7og/8401/7d0034e810b0e95b8c0694abfaf748cf5135c15a/_/images/icons/emoticons/warning.svg Wait for the reload to complete by checking the server log or the result of :read-attribute(name=server-state) before continuing.

Add New Interfaces and Sockets

To add new interfaces and sockets, use the following:

/interface=http:add(inet-address="0.0.0.0")
/interface=httpspub:add(inet-address="0.0.0.0")
/interface=httpspriv:add(inet-address="0.0.0.0")
/socket-binding-group=standard-sockets/socket-binding=http:add(port="8080",interface="http")
/socket-binding-group=standard-sockets/socket-binding=httpspub:add(port="8442",interface="httpspub")
/socket-binding-group=standard-sockets/socket-binding=httpspriv:add(port="8443",interface="httpspriv")

Configure TLS

Configure TLS according to the following instructions.

Make sure the passwords in this section are correct, in order for the commands not to fail. In production the passwords should be changed to "real" passwords.

Update the keystore-password for keystore.jks to match httpsserver.password and the keystore-password for truststore.jks to match java.truststore in web.properties:

/subsystem=elytron/key-store=httpsKS:add(path="keystore/keystore.jks",relative-to=jboss.server.config.dir,credential-reference={clear-text="serverpwd"},type=JKS)
/subsystem=elytron/key-store=httpsTS:add(path="keystore/truststore.jks",relative-to=jboss.server.config.dir,credential-reference={clear-text="changeit"},type=JKS)
/subsystem=elytron/key-manager=httpsKM:add(key-store=httpsKS,algorithm="SunX509",credential-reference={clear-text="serverpwd"})
/subsystem=elytron/trust-manager=httpsTM:add(key-store=httpsTS)
/subsystem=elytron/server-ssl-context=httpspub:add(key-manager=httpsKM,protocols=["TLSv1.2"])
/subsystem=elytron/server-ssl-context=httpspriv:add(key-manager=httpsKM,protocols=["TLSv1.2"],trust-manager=httpsTM,need-client-auth=true,authentication-optional=false,want-client-auth=true)

Optionally, the "httpspriv" context can be configured with optional client certificate authentication using "need-client-auth=false,authentication-optional=true" instead.

Add HTTP(S) Listeners

To add HTTP(S) listeners:

/subsystem=undertow/server=default-server/http-listener=http:add(socket-binding="http", redirect-socket="httpspriv")
/subsystem=undertow/server=default-server/https-listener=httpspub:add(socket-binding="httpspub", ssl-context="httpspub", max-parameters=2048)
/subsystem=undertow/server=default-server/https-listener=httpspriv:add(socket-binding="httpspriv", ssl-context="httpspriv", max-parameters=2048)
:reload

images/s/-98b7og/8401/7d0034e810b0e95b8c0694abfaf748cf5135c15a/_/images/icons/emoticons/warning.svg Wait for the reload to complete by checking the server log or the result of :read-attribute(name=server-state) before continuing.

HTTP Protocol Behavior Configuration

The following shows an example HTTP Protocol Behavior Configuration.

/system-property=org.apache.catalina.connector.URI_ENCODING:add(value="UTF-8")
/system-property=org.apache.catalina.connector.USE_BODY_ENCODING_FOR_QUERY_STRING:add(value=true)
/system-property=org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH:add(value=true)
/system-property=org.apache.tomcat.util.http.Parameters.MAX_COUNT:add(value=2048)
/system-property=org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH:add(value=true)
/subsystem=webservices:write-attribute(name=wsdl-host, value=jbossws.undefined.host)
/subsystem=webservices:write-attribute(name=modify-wsdl-address, value=true)
:reload

If you are using OCSP GET requests, setting URI encoding and allowing encoding for Query and backslash above are needed.

This will also ensure that the address in the EJBCA WS WSDL will match the hostname and port that the client used to access the server.

images/s/-98b7og/8401/7d0034e810b0e95b8c0694abfaf748cf5135c15a/_/images/icons/emoticons/warning.svg Wait for the reload to complete by checking the server log or the result of :read-attribute(name=server-state) before continuing.

Remove RESTEasy-Crypto

The application server can sometimes load its own version of Bouncy Castle, resulting in incompatibility and/or conflict issues.

A typical error occurring as a consequence of the wrong Bouncy Castle being loaded in EJBCA is:

ClassCastException setting BagAttributes, can not set friendly name: : java.lang.ClassCastException: org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject cannot be cast to org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier

To avoid issues and prevent Wildfly/JBoss from loading the Bouncy Castle library included in the RESTEasy-Crypto module rather than the library included in EJBCA, run the following:

$ cd /opt/wildfly
$ sed -i 's|.*org.jboss.resteasy.resteasy-crypto.*||' modules/system/layers/base/org/jboss/as/jaxrs/main/module.xml
$ rm -rf modules/system/layers/base/org/jboss/resteasy/resteasy-crypto

The following displays an example error log message in case of a conflict:

ERROR [StartupSingletonBean] BouncyCastle is not loaded by an EJBCA classloader, version conflict is likely:
org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject: #012org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject(4690542e).
ClassLoader=ModuleClassLoader for Module "org.bouncycastle" from local module loader @3fb6a447
(finder: local module finder @79b4d0f (roots: /opt/jboss/modules,/opt/jboss/modules/system/layers/base))#012++++CodeSource:
([jar:file:/opt/jboss/modules/system/layers/base/org/bouncycastle/main/bcprov-jdk15on-1.60.jar!/] [#012[#012 Version: V3#012 Subject:
CN=Legion of the Bouncy Castle Inc., OU=Java Software Code Signing, O=Sun Microsystems Inc#012 Signature Algorithm:
SHA1withDSA, OID = 1.2.840.10040.4.3#012#012 Key: Sun DSA Public Key#012 Parameters:DSA#012#011p:
fd7f5381 1d751229 52df4a9c 2eece4e7 f611b752 3cef4400 c31e3f80 b6512669#012 455d4022 51fb593d
8d58fabf c5f5ba30 f6cb9b55 6cd7813b 801d346f f26660b7#012

Optional Configuration

The following sections cover optional configurations.

Remove Welcome Content

/subsystem=undertow/server=default-server/host=default-host/location="\/":remove()
/subsystem=undertow/configuration=handler/file=welcome-content:remove()
:reload

images/s/-98b7og/8401/7d0034e810b0e95b8c0694abfaf748cf5135c15a/_/images/icons/emoticons/warning.svg Wait for the reload to complete by checking the server log or the result of :read-attribute(name=server-state) before continuing.

Redirect to Application for Unknown URLs

Known URLs starts with /ejbca/, /crls, /certificates or /.well-known/ (EST) for EJBCA according to the following example:

/subsystem=undertow/configuration=filter/rewrite=redirect-to-app:add(redirect=true,target="/ejbca/")
/subsystem=undertow/server=default-server/host=default-host/filter-ref=redirect-to-app:add(predicate="method(GET) and not path-prefix('/ejbca/','/crls','/certificates','/.well-known/') and not equals({%{LOCAL_PORT}, 4447})")
:reload

images/s/-98b7og/8401/7d0034e810b0e95b8c0694abfaf748cf5135c15a/_/images/icons/emoticons/warning.svg Wait for the reload to complete by checking the server log or the result of :read-attribute(name=server-state) before continuing.

URL Rewriting for the CRL Servlet

Since EJBCA 7.2, the ability to customize the URL for the CRL store servlet has been removed. For more information, see ECA-7059 and the EJBCA 7.2 Upgrade Notes.

However, you can download CRLs on a different URL by adding a rewrite rule in Undertow. As an example, to allow a client to download CRLs from the URL /ejbca/crls/ instead of /ejbca/publicweb/crls/, add the following configuration:

/subsystem=undertow/configuration=filter/rewrite=crl-rewrite:add(target="/ejbca/publicweb/crls/$${1}")
/subsystem=undertow/server=default-server/host=default-host/filter-ref=crl-rewrite:add(predicate="method(GET) and regex('/crls/(.*)')")
:reload

images/s/-98b7og/8401/7d0034e810b0e95b8c0694abfaf748cf5135c15a/_/images/icons/emoticons/warning.svg Wait for the reload to complete by checking the server log or the result of :read-attribute(name=server-state) before continuing.

Remove the ExampleDS DataSource

To optionally remove the ExampleDS DataSource:

/subsystem=ee/service=default-bindings:remove()
data-source remove --name=ExampleDS
:reload

images/s/-98b7og/8401/7d0034e810b0e95b8c0694abfaf748cf5135c15a/_/images/icons/emoticons/warning.svg Wait for the reload to complete by checking the server log or the result of :read-attribute(name=server-state) before continuing.

Remove Unneeded Subsystems and Extensions

To optionally remove the unneeded subsystems and extensions:

/subsystem=jdr:remove()
/subsystem=sar:remove()
/subsystem=jmx:remove()
/subsystem=pojo:remove()
/subsystem=ee-security:remove()
/subsystem=microprofile-config-smallrye:remove()
/subsystem=microprofile-health-smallrye:remove()
/subsystem=microprofile-opentracing-smallrye:remove()
/extension=org.jboss.as.jdr:remove()
/extension=org.jboss.as.jmx:remove()
/extension=org.jboss.as.sar:remove()
/extension=org.jboss.as.pojo:remove()
/extension=org.wildfly.extension.ee-security:remove()
/extension=org.wildfly.extension.microprofile.config-smallrye:remove()
/extension=org.wildfly.extension.microprofile.health-smallrye:remove()
/extension=org.wildfly.extension.microprofile.opentracing-smallrye:remove()
:reload

images/s/-98b7og/8401/7d0034e810b0e95b8c0694abfaf748cf5135c15a/_/images/icons/emoticons/warning.svg Wait for the reload to complete by checking the server log or the result of :read-attribute(name=server-state) before continuing.

Enable AJP Connector

Enabling the AJP connector is only needed if you run an Apache front-end in front of WildFly:

/subsystem=undertow/server=default-server/ajp-listener=ajp-listener:add(socket-binding=ajp, scheme=https, enabled=true)

Add Support for PKCS#11 (HSMs)

WildFly by default isolates away most sun classes. EJBCA configures JBoss/WildFly to expose these classes (sun/security/pkcs11/wrapper), as of EJBCA 6.6.3, by using a jboss-deployment-structure.xml. This makes configuration in modules/system/layers/base/sun/jdk/main/module.xml not needed.

Add Support for Sending Email

To add support for sending email (smtp), configure EjbcaMail with:

/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=ejbca-mail-smtp:add(port="993", host="my.mail.server")
/subsystem=mail/mail-session="java:/EjbcaMail":add(jndi-name=java:/EjbcaMail, from=noreply@mymail)
/subsystem=mail/mail-session="java:/EjbcaMail"/server=smtp:add(outbound-socket-binding-ref=ejbca-mail-smtp, tls=true, username=smtpuser, password=smtppassword)
:reload

Only Hot Deploy at Startup

Historically application servers are really bad at cleaning up memory from previous deployments and hot (re-)deploy is discouraged in production. To avoid manual deployment with the management interface, we can specify that the deployment directory should be scanned once at application server startup by setting the scan-interval to 0.

/subsystem=deployment-scanner/scanner=default:write-attribute(name=scan-interval,value=0)

Disable Management Web Console

If you only plan on using the JBoss CLI anyway there is little reason to keep this around.

/core-service=management/management-interface=http-interface:write-attribute(name=console-enabled,value=false)
:reload

Next Step: Deploying EJBCA

For instructions on how to build and deploy EJBCA, see Deploying EJBCA.