Configuring the NIO HTTPS Interface of Redwood Platform
The NIO connector is built-in and uses the JSSE framework for encryption. Ensure you install the Unlimited strength Java Cryptography Extension (JCE). It is important to keep your Java Virtual Machine up-to-date, with the Unlimited strength Java Cryptography Extension (JCE). See Test Java Cryptographic Extension for a simple script to test if the JCE is installed.
Cipher Suites
Supported Mozilla Firefox and Google Chrome, and Edge versions, and the Redwood Server system tools ( jtool
) support the following cipher suites:
TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
And the following are inherently insecure and should not be used, hence the!
which disallows them (to use this list with the APR connector, ensure it is a colon (:
) separated list):
!aNULL,!eNULL,!EXPORT,!DES,!RC4,!3DES,!MD5,!PSK
Redwood recommends you use these cipher suites (the list above and the exclusions) in your configuration. These cipher suites have been chosen after careful research, however, Redwood cannot guarantee that these cipher-suites are 100% secure.
If a client needs to connect to your central Redwood Server and does not support these strong ciphers, you add a second connector, specifically for your client. You configure your firewall to restrict connections to this connector to your client. The port number should be smaller than the main connector, for licensing reasons.
Keystore
The keystore is used by the JSSE as a repository for certificates; this is used by the NIO connector. When you create a keystore, you will be asked for a password, please keep the password safe and ensure that, at the end of the keystore creation, you specify the same password again. The only information you must provide is the What is your first and last name, which should be set to the FQDN of the host where Redwood Platform runs. Users can see the remainder of the information you provide; Redwood recommends to fill in all fields with legitimate values.
The keystore password will be required to generate a Certificate Signing Request and must be entered in the Redwood Platform server.xml
file.
The following error will be displayed when you do not provide the valid password:
keytool error: java.io.IOException: Keystore was tampered with, or password was incorrect
Process Flow
- Perform one of the following:
- Use a certificate signed by a trusted CA.
- Create a local keystore.
- Create a Certificate Signing Request (CSR).
- Request your purchased certificate.
- Import the certificate.
- Create a keystore with a self-signed certificate.
- Configure Redwood Platform for Encryption.
- Update the
ContextURL
registry entry.
Prerequisites
- Installed and configured Java Development Kit (JDK), which should ideally be the latest version shipped by the platform vendor (it must be supported).
Procedure
In the following procedures the UNIX path ( $JAVA_HOME/bin/keytool
) is used for the keytool executable, on Windows you would typically specify the full path or "%JAVA_HOME%"\bin\keytool.exe
instead.
Create a Local Keystore with a Self-Signed Certificate
- Run the below command.
- Fill in a password.
- Answer all questions, note that What is your first and last name should be set to the FQDN of your Redwood Platform instance. Type
yes
at the end to confirm the details. - Fill in the same password, both must match. This password will later have to be entered in the Redwood Platform
server.xml
file along with the location of the keystore.
$JAVA_HOME/bin/keytool -genkey -keyalg RSA -alias <alias> -keystore <keystore> -storepass <password> -validity 360 -keysize 2048
<alias>
- an alias for your key, not used by Redwood Platform.<keystore>
- path to the keystore, ensure that this file is protected (only readable by the user that runs Redwood Platform), you specify this path in thekeystoreFile
attribute of yourconnector
.<password>
- password for your keystore, you specify this password in thekeystorePass
attribute of yourconnector
.
Create a Certificate Signing Request for your CA and Import the Certificate
- Run the following command:
${JAVA_HOME}/bin/keytool -genkey -alias <alias> -keyalg RSA -keystore <keystore>
. - Fill in a password.
- Answer all questions, note that What is your first and last name should be set to the FQDN of your Redwood Platform instance. Type
yes
at the end to confirm the details. - Fill in the same password, both must match. This password will later have to be entered in the Redwood Platform
server.xml
file along with the location of the keystore. - Run the following command:
${JAVA_HOME}/bin/keytool -certreq -keyalg RSA -alias <alias> -file <csr_file> -keystore <keystore>
. - Fill in the password you specified when you created the keystore.
- Send the csr file to your CA.
- Import the signed certificate with the command:
${JAVA_HOME}/bin/keytool -import -trustcacerts -alias <alias> -file <cert_file> -keystore <keystore>
.
<alias>
- an alias for your key, not used by Redwood Platform, however, in each of the above commands, the same alias must be used..<keystore>
- path to the keystore, ensure that this file is protected (only readable by the user that runs Redwood Platform), you specify this path in thekeystoreFile
attribute of yourconnector
.<password>
- password for your keystore, you specify this password in thekeystorePass
attribute of yourconnector
.
Configure Redwood Platform for Encryption
- Add the section below to
<install_dir>/j2ee/cluster/server<n>/conf/server.xml
: - Start Redwood Platform and test to see if you can log in, you might need to add a security exception if you created a self-signed certificate.
- If you can log in successfully, it is time to add the
redirectPort
to the HTTP connector, see below:
Secure connector to add to server.xml
, note that <port>
, <keystore>
, and <keystore_password>
need to be adapted.
<!-- Define a SSL HTTP/1.1 Connector on port <port> -->
<Connector port="<port>" protocol="org.apache.coyote.http11.Http11NioProtocol"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="<keystore>" keystorePass="<keystore_password>" clientAuth="false"
sslProtocol="TLSv1.3"
useServerCipherSuitesOrder="true"
ciphers="TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"
URIEncoding="UTF-8" compression="2048"
compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css" maxThreads="150"
connectionTimeout="20000" keepAliveTimeout="90000"/>
Insert the redirectPort
only after you have tested the secure connector, change the below:
<Connector port="<port>" allowTrace="false" protocol="org.apache.coyote.http11.Http11Protocol"
URIEncoding="UTF-8" compression="2048"
compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css" maxThreads="150"
connectionTimeout="20000" keepAliveTimeout="90000"/>
Ensure it looks like the following, <port>
needs to be replaced with the port of your secure connector above (besides, on production systems, you remove the allowTrace
):
<Connector port="<port>" protocol="org.apache.coyote.http11.Http11Protocol"
URIEncoding="UTF-8" compression="2048" redirectPort="<secure_port>"
compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css" maxThreads="150"
connectionTimeout="20000" keepAliveTimeout="90000"/>
You can use the following command to to test the connection, the protocol and cipher used:
openssl s_client -connect <server>:<port>
Adapt web.xml
A new security constraint and a number of filters need to be added to the end of web.xml
; after the following block:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
The lines to add to the files are between <!-- Start of change -->
and <!-- End of change -->
:
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- Start of change -->
<security-constraint>
<web-resource-collection>
<web-resource-name>twx-portal</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<filter>
<filter-name>httpHeaderSecurity</filter-name>
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>hstsEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>hstsMaxAgeSeconds</param-name>
<param-value>31536000</param-value>
</init-param>
<init-param>
<param-name>hstsIncludeSubDomains</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>antiClickJackingOption</param-name>
<param-value>SAMEORIGIN</param-value>
</init-param>
</filter>
<!--The mapping for the HTTP header security Filter-->
<filter-mapping>
<filter-name>httpHeaderSecurity</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<!-- End of change -->
</web-app>
Update the ContextURL registry entry
- Navigate to Configuration > Registry.
- Expand configuration, locate ContextURL.
- Specify the FQDN, a name that all clients will be able to access, ensure the port is correct and not blocked by any firewall. For example:
https://pr1.example.com:53000/redwood
. - Restart Redwood Platform.
Issue the following command to restart
UNIX
<install_dir>/j2ee/cluster/server<n>/bin/start.sh
Windows
<install_dir>\j2ee\cluster\server<n>\bin\start.cmd
Example
In the following example you create a self-signed certificate and configure Redwood Platform to use it.
Create a self-signed certificate:
> %JAVA_HOME%\bin\keytool -genkey -keyalg RSA -alias "Redwood Server" -keystore c:\Users\example\keystore -storepass changeit -validity 360 -keysize 2048
> ATTRIB -S -H c:\Users\example\keystore
Configure Redwood Platform
The following connector was added to /opt/redwood/j2ee/cluster/server1/conf/server.xml
<!-- Define a SSL HTTP/1.1 Connector on port 443 -->
<Connector port="443" scheme="https" secure="true" SSLEnabled="true"
protocol="org.apache.coyote.http11.Http11NioProtocol"
keystoreFile="c:\Users\example\keystore" keystorePass="changeit" clientAuth="false"
sslProtocol="TLSv1.3"
useServerCipherSuitesOrder="true"
ciphers="TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"
URIEncoding="UTF-8" compression="2048"
compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css" maxThreads="150"
connectionTimeout="20000" keepAliveTimeout="90000"/>
Restart Redwood Platform and test if you can log in with https://<hostname>:443/redwood
, if the test is successful, edit the following:
<Connector port="10180" allowTrace="false" protocol="org.apache.coyote.http11.Http11Protocol"
URIEncoding="UTF-8" compression="2048"
compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css" maxThreads="150"
connectionTimeout="20000" keepAliveTimeout="90000"/>
This is how it looks now with the redirectPort
:
<Connector port="10180" protocol="org.apache.coyote.http11.Http11Protocol"
URIEncoding="UTF-8" compression="2048" redirectPort="443"
compressableMimeType="text/html,text/xml,text/plain,text/javascript,text/css" maxThreads="150"
connectionTimeout="20000" keepAliveTimeout="90000"/>
The following connector was added to /opt/redwood/j2ee/cluster/server1/conf/web.xml
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- Start of change -->
<security-constraint>
<web-resource-collection>
<web-resource-name>twx-portal</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
<filter>
<filter-name>httpHeaderSecurity</filter-name>
<filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
<async-supported>true</async-supported>
<init-param>
<param-name>hstsEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>hstsMaxAgeSeconds</param-name>
<param-value>31536000</param-value>
</init-param>
<init-param>
<param-name>hstsIncludeSubDomains</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>antiClickJackingOption</param-name>
<param-value>SAMEORIGIN</param-value>
</init-param>
</filter>
<!--The mapping for the HTTP header security Filter-->
<filter-mapping>
<filter-name>httpHeaderSecurity</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<!-- End of change -->
</web-app>
Protecting Cookies
You add the secure flag to cookies by adding or amending the <cookie-config>
in j2ee/cluster/server1/conf/web.xml
:
Locate the <session-config>
in web.xml
:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
The add or amend the <cookie-config>
tag as follows:
<session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<secure>true</secure>
</cookie-config>
</session-config>
See Also
- HTTP/HTTPS Connector Configuration
- SSL/TLS Configuration HOW-TO
- Configuring the HTTP or HTTPS Interface of Redwood Platform
onsiteTopic