SSLv2Hello with WildFly
It is now possible to use SSLv2Hello
with WildFly. This blog post will give an
introduction to this new feature, but it will assume previous knowledge on how to
configure SSL in Elytron. For more information on how to configure SSL,
refer to the elytron documentation.
An Overview of SSLv2Hello
Older JDK versions use SSLv2Hello
during the initial handshake message
where the SSL version that will be used for the rest of the handshake is negotiated.
The use of this protocol is discouraged. As a result, newer JDK versions disable this protocol by default for clients, but do provide the ability to re-enable it if needed.
By adding SSLv2Hello
as a supported protocol in WildFly, we are ensuring older
clients are still able to communicate to servers guaranteeing parity with legacy security.
Enabling SSLv2Hello on the Server Side
SSLv2Hello
can be enabled by configuring it in the protocols
attribute in the
SSL context definition in the Elytron subsystem. Let’s take a look at an example configuring
one way SSL using SSLv2Hello
in the server and client. The example application is available
here.
Back Up Your Standalone Server Configuration
Prior to starting, back up your standalone server configuration by making a copy of
your WILDFLY_HOME/standalone/configuration/standalone.xml
file. You will need it in the end
to restore your server’s configuration.
Pre-requisite Server Configuration
As a first step, we’re going to enable one-way SSL for applications deployed to WildFly
using the security enable-ssl-http-server
CLI command.
First, make sure you have an instance of your WildFly server running. Then, run the following commands:
WILDFLY_HOME/bin/jboss-cli.sh --connect
Then run the security enable-ssl-http-server
command as follows:
security enable-ssl-http-server --interactive
Please provide required pieces of information to enable SSL:
Certificate info:
Key-store file name (default default-server.keystore): server.keystore
Password (blank generated): secret
What is your first and last name? [Unknown]: localhost
What is the name of your organizational unit? [Unknown]: wildfly
What is the name of your organization? [Unknown]: jboss
What is the name of your City or Locality? [Unknown]: Raleigh
What is the name of your State or Province? [Unknown]: North Carolina
What is the two-letter country code for this unit? [Unknown]: US
Is CN=localhost, OU=jboss, O=wildfly, L=Raleigh, ST=North Carolina, C=US correct y/n [y]?y
Validity (in days, blank default): 365
Alias (blank generated): localhost
Enable SSL Mutual Authentication y/n (blank n):n
SSL options:
key store file: server.keystore
distinguished name: CN=localhost, OU=wildfly, O=jboss, L=Raleigh, ST=North Caro
lina, C=US
password: secret
validity: 365
alias: localhost
Server keystore file server.keystore, certificate file server.pem and server.csr file will be generated in server configuration directory.
Do you confirm y/n :y
Server reloaded.
SSL enabled for default-server
ssl-context is ssl-context-aaad4a67-14f1-4869-a01c-9fc56c3ff884
key-manager is key-manager-aaad4a67-14f1-4869-a01c-9fc56c3ff884
key-store is key-store-aaad4a67-14f1-4869-a01c-9fc56c3ff884
Make sure you enter your desired "hostname" for the first and last name field, otherwise you might
run into issues while permanently accepting this certificate
as an exception to some browsers. Chrome does not currently exhibit this behaviour.
|
As we can see from the output, the above command automatically generated a self-signed
certificate, added it to a newly created keystore and added a new ssl-context
resource,
ssl-context-aaad4a67-14f1-4869-a01c-9fc56c3ff884
to the Elytron subsystem in order to enable
one-way SSL for applications deployed to WildFly.
Test the Server SSL Configuration
To test the connection to the SSL port of your server instance, open a browser and navigate to https://localhost:8443/.
You get the privacy error because the server certificate is self-signed. If you need to use a fully signed certificate, you must get a PEM file from the Certificate Authority and then import the PEM into the keystore. |
Configuring SSLv2Hello in the Server
At this point in time, your server has not yet been configured to accept SSLv2Hello
messages. Since, we used the security enable-ssl-http-server
CLI command, this configures our SSL context
to accept TLSv1.2
only. To enable SSLv2Hello
, we need to update our ssl-context
configuration in the
Elytron subsystem to modify the attribute protocols
to include SSLv2Hello
as follows:
/subsystem=elytron/server-ssl-context=ssl-context-aaad4a67-14f1-4869-a01c-9fc56c3ff884:write-attribute(name=protocols,value=[TLSv1,SSLv2Hello])
reload
When configuring any SSL context to enable SSLv2Hello (client or server), you always
need to specify an additional SSL/TLS protocol. SSLv2Hello cannot be specified by itself,
as it is a pseudo protocol which is only used to negotiate another SSL/TLS version to be used
throughout the rest of the communication.
|
A Note On Enabling SSLv2Hello In Newer JDK Versions
Newer JDK versions have disabled TLSv1. Since we need the TLSv1 protocol to make use of SSLv2Hello, we will walk you through how to re-enable it on the server side.
-
Access the following file:
WILDFLY_HOME/bin/standalone.conf
. -
Look for the following line
# JAVA_OPTS="$JAVA_OPTS -Djava.security.properties==/path/to/custom/java.security"
-
Make sure to uncomment it and edit the path to the file
enabled_tlsv1.properties
in this example application. Additionally, make sure you use one=
as opposed to two. That way you will not completely override thejava.security
file.
Note, you might have to reload your server for these changes to take effect.
Configure the Client’s Trust Store
Export the server’s certificate to a file by navigating to WILDFLY_HOME/standalone/configuration
and
running the following command:
keytool -export -alias localhost -keystore server.keystore -file myCert.cer -storepass secret
Import the certificate into the client’s trust store. Note the following command will create a trust store if it does not exist at the location specified.
keytool -import -file myCert.cer -alias localhost -keystore client.keystore -storepass secret
You should see the following output next:
Owner: CN=localhost, OU=wildfly, O=jboss, L=Raleigh, ST=North Carolina, C=US
Issuer: CN=localhost, OU=wildfly, O=jboss, L=Raleigh, ST=North Carolina, C=US
Serial number: 7af5ad9991816bbc
Valid from: Wed Nov 04 16:15:09 EST 2020 until: Thu Nov 04 16:15:09 EDT 2021
Certificate fingerprints:
SHA1: 24:6E:96:9A:8B:D2:FF:2B:7B:58:87:84:03:F3:ED:C6:56:8B:96:5B
SHA256: 27:51:F6:7A:F8:51:7D:6E:CB:DA:4A:9A:75:E5:9A:AD:06:88:1B:AE:40:73:7D:D8:E4:4F:22:CA:8E:03:94:37
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: FF BA 34 E8 94 94 BE EB 25 B5 C5 4E B3 B2 A4 34 ..4.....%..N...4
0010: 97 EE A2 24 ...$
]
]
Trust this certificate? [no]: y
Certificate was added to keystore
You have now created the client’s trustore and imported the server’s certificate.
Configure a Client that sends SSLv2Hello messages
The example application presents a simple client Client.java
which checks the connection
to the server is successful. To ensure the client uses SSLv2Hello
in its initial
handshake, we have provided a common configuration framework in
wildfly-config.xml
.
Review this file to see how SSLv2Hello
is enabled in the client SSL context along with
TLSv1
.
As a final step in configuring the client, update the path to the client’s trust store to
/PATH/TO/client.keystore
.
Build and Deploy the Application
Ensure you have a running instance of your server. Then, navigate to the root directory of the example application and run the following commands:
cd server
mvn clean package wildfly:deploy
This deploys the server-sslv2hello.war
to the running instance of the server.
You should see a message in the server log indicating that the archive deployed successfully.
Verifying the Client Sends SSLv2Hello Messages
In the following section, we will be inspecting the SSL debug logs to ensure the Client Hello messages
make use of SSLv2Hello
. You will need to enable SSL debug logs in your client and server using
the javax.net.debug
system property as follows:
-
To run your client with SSL debug logs:
mvn clean install -Dtest=Client -Djavax.net.debug=ssl,handshake
-
To run your server with SSL debug logs:
WILDFLY_HOME/bin/standalone.sh -Djavax.net.debug=ssl,handshake
Verifying SSLv2Hello Messages Succeed When SSLv2Hello is Configured on the Server
Run your client.
In your client SSL logs, you should see a ClientHello
message similar to the following:
"ClientHello": {
"client version" : "TLSv1",
"random" : "28 D9 B0 EB 0E A1 5B 07 B6 0D 21 B1 87 F8 42 14 EE 11 6A 11 8B B6 19 7D 2B CF DB B5 B1 A1 43 01",
"session id" : "",
"cipher suites" : "[TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA(0xC00A), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(0xC014), TLS_RSA_WITH_AES_256_CBC_SHA(0x0035), TLS_DHE_RSA_WITH_AES_256_CBC_SHA(0x0039), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA(0xC009), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA(0xC013), TLS_RSA_WITH_AES_128_CBC_SHA(0x002F), TLS_DHE_RSA_WITH_AES_128_CBC_SHA(0x0033)]",
"compression methods" : "00",
"extensions" : [
"status_request (5)": {
"certificate status type": ocsp
"OCSP status request": {
"responder_id": <empty>
"request extensions": {
<empty>
}
}
},
"supported_groups (10)": {
"versions": [secp256r1, secp384r1, secp521r1, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192]
},
"ec_point_formats (11)": {
"formats": [uncompressed]
},
"status_request_v2 (17)": {
"cert status request": {
"certificate status type": ocsp_multi
"OCSP status request": {
"responder_id": <empty>
"request extensions": {
<empty>
}
}
}
},
"extended_master_secret (23)": {
<empty>
},
"supported_versions (43)": {
"versions": [TLSv1, SSLv2Hello]
},
"renegotiation_info (65,281)": {
"renegotiated connection": [<no renegotiated connection>]
}
]
}
Notice how TLSv1
and SSLv2Hello
are specified under supported_versions
. This triggers
an SSLv2Hello ClientHello
. Your tests should succeed, and you should be able to see the
negotiated protocol is TLSv1
in both your client and server logs.
Verifying SSLv2Hello messages fail when SSLv2Hello is not configured on the server
You can modify your server-ssl-context
resource again to only accept TLSv1
as follows:
/subsystem=elytron/server-ssl-context=ssl-context-aaad4a67-14f1-4869-a01c-9fc56c3ff884:write-attribute(name=protocols,value=[TLSv1])
Now, run your client.
You should be able to see a similar ClientHello
as the one in the section above, but you should also see a
handshake_failure
in the log.
Upon reviewing your server log, it should provide more details as to what causes the failure. You should see a message similar to the following:
ERROR [stderr] (default I/O-2) javax.net.ssl|ERROR|01 14|default I/O-2|2020-11-05
14:29:27.677 EST|TransportContext.java:318|Fatal (HANDSHAKE_FAILURE): SSLv2Hello is not enabled (
14:29:27,678 ERROR [stderr] (default I/O-2) "throwable" : {
14:29:27,678 ERROR [stderr] (default I/O-2) javax.net.ssl.SSLHandshakeException: SSLv2Hello is not enabled
Now, you have verified that enabling SSLv2Hello
on the client side triggers an SSLv2Hello
message,
which if not supported by the server, causes a handshake exception.
Undeploy the Application
When you are finished testing the application, follow these steps to undeploy the archive:
-
Make sure you start the WildFly server.
-
Open a terminal and navigate to the root directory of this example.
-
Type the following commands to undeploy the archive:
cd server mvn wildfly:undeploy