AWS Open Source Blog
TLS 1.0/1.1 changes in OpenJDK and Amazon Corretto
Starting on April 20, 2021, quarterly update releases of OpenJDK are disabling TLS1.0 and TLS1.1 availability by default in all versions of OpenJDK. Amazon Corretto will be keeping TLS1.0 and TLS1.1 available by default for a while longer. Feedback from customers and industry partners suggests that this deprecation has the potential to cause outages, so Amazon will be giving Corretto users a chance to audit their usage of TLS and take necessary measures before disabling these older protocols. This post describes the situation in more detail, explains how to re-enable older TLS versions on non-Corretto distributions if necessary, and provides ideas for auditing traffic.
What is the change in OpenJDK?
OpenJDK will be disabling TLS 1.0 and 1.1 availability by default in the security.properties
file. Java applications using TLS to communicate will need to use TLS 1.2 or above to establish a connection. The change will apply to at least OpenJDK 8u292 onward, OpenJDK 11.0.11 onward, and all versions of OpenJDK 16, following the JRE and JDK Crypto Roadmap published by Oracle.
Affected OpenJDK versions:
Version | Release number |
OpenJDK 8 | 8u292 and newer |
OpenJDK 11 | 11.0.11 and newer |
OpenJDK 16 and above | All versions |
Applications that update to a JDK with this change may see outages if they are currently using TLS 1.0/1.1, either to connect to endpoints that don’t support at least TLS 1.2 (client scenario) or serving traffic to clients that don’t support TLS 1.2 (server scenario). Affected apps can re-enable these versions of TLS because they aren’t being removed from the JDK. Only their availability by default is changing.
What is happening in AWS?
As explained by AWS VP/Distinguished Engineer Colm MacCárthaigh in his blog post Java, Scala, Kotlin and TLS1.0 / TLS1.1, at AWS “every service has long supported at least TLS1.2 and this change won’t impact communication to or from those services.” We believe that applications serving traffic to web browsers will also be covered because all popular browsers support TLS1.2 and are themselves working to deprecate TLS1.0 and TLS1.1. However, according to MacCárthaigh, this change has the potential to cause outages in “non-cloud networks like co-lo and on-premises datacenters, or on industrial and home networks, where it’s not uncommon to encounter legacy appliances and applications that haven’t been, or can’t be updated to support TLS1.2.”
We will be postponing this change in Corretto to give users time to audit their systems and decide whether they need to take action in their own installations. After researching the matter, we believe that the risk of outages is not negligible, and we are calling out the risk to our Corretto users to let them evaluate their situations and decide on next steps.
We suggest a couple of ways for auditing traffic below and we will continue to work on a better way that we will publish here soon.
Amazon Linux, AWS Lambda, and AWS CodeBuild will also continue to support TLS1.0 and TLS1.1 in OpenJDK.
What is Amazon’s position on TLS1.0 and TLS1.1?
We agree that TLS1.0 and TLS1.1 should continue to be removed from the ecosystem. As MacCárthaigh says, “TLS1.2 and TLS1.3 are unambiguously better than TLS1.0 and TLS1.1.”
The IETF (Internet Engineering Task Force) has released a draft document officially deprecating these versions, which is expected to publish during 2021. As mentioned previously, browsers are also working to deprecate them.
Allowing TLS1.0 and TLS1.1 connections to be established, however, doesn’t currently present a realistic security threat, so we believe this temporary measure to prioritize application stability is the right decision. MacCárthaigh’s post goes into detail about the security aspects of running TLS1.0 and 1.1.
These decisions are subject to change if and when new information comes to light.
How do I re-enable TLS1.0 and TLS1.1 in JDK distributions other than Corretto?
The good news is that re-enabling these versions is straightforward. First, locate your java.security
configuration file located in the jre/lib/security
folder for OpenJDK 8 or conf/security
for OpenJDK 11 and higher. If you are unfamiliar with this file, you can take a look at the current version in Corretto 11 on GitHub. From here are two options.
Option 1 (preferred): First, ensure the security.overridePropertiesFile
value in the java.security
file is set to true (this is usually the default value). Then, take the following steps:
- Create a file named
enableLegacyTLS.security
. - In that file, add an entry for
jdk.tls.disabledAlgorithms
with the same contents as thejdk.tls.disabledAlgorithms
property in thejava.security
file. - Remove TLSv1 and/or TLSv1.1 from the list on the
enableLegacyTLS.security
. (You can see this line in the Corretto GitHub). - Start your application with
-Djava.security.properties=path/to/enableLegacyTLS.security
.
Alternatively, you can edit this value in the java.security
file directly. Search for the property jdk.tls.disabledAlgorithms
. For OpenJDK 11, its contents will be similar to:
By removing the TLSv1.1 and/or TLSv1 entries (in bold above), you can re-establish those versions back to the list of usable versions within the JDK.
To make your Corretto configuration more restrictive, perform similar steps adding “TLSv1, TLSv1.1″ to the jdk.tls.disabledAlgorithms
property.
How do I audit my systems?
We can suggest two imperfect methods that will help get information on what applications are doing. They both impact system performance, so you may want to do them on a single server in your fleet to get an idea of percentages rather than count each connection.
Option 1: Using JDK SSL debug logging
The JDK has the ability to log detailed information about the TLS connection. This log will contain the exact version of TLS that is negotiated among all the data it generates. This method requires restarting your server and turning on logging by passing the following parameter to the Java command:
The log lines identifying the TLS version used look like the following.
If you are using OpenJDK/Corretto 11:
If you are using OpenJDK/Corretto 8:
If you capture this log to a file for a given period of time, you can get a summary using a command like the following (on Linux/Mac):
On Windows, you can use the following PowerShell command:
gc example.log | ?{$_ -like "*Negotiated Protocol*"} | %{$_.split(":")[4]} | sort | group | select Name, Count
Option 2 (on Linux): Using tcpdump
tcpdump
allows you to get information from an already running server, without needing to restart. The drawback is that it will put your NIC in a non-performant mode and won’t be able to distinguish which connections are from your JVM, so you may end up with incorrect data if other services are running on that machine.
We will capture all TLS handshakes and be able to count how many of those are TLS 1.0 and 1.1 using the following command:
Here is the breakdown of what that command is doing:
sudo tcpdump
: Privileged permissions are required for capturing traffic.-C 100
: Limit the file size to 100 MB; after that size is reached, rotate to a new file.-W 5
: Limit the number of rotated files to 5; after that, start overwriting old files. These two options will ensure no more than 500 MB are used.tcp[((tcp[12] & 0xf0) >> 2)] = 0x16
: Capture only packets for which the first byte after the TCP header is0x16
. This will ensure only TLS handshake packets are captured.tcp[((tcp[12] & 0xf0) >> 2) + 1] = 0x03
: Capture only packets for which the second byte after the TCP header is0x03
. This should be true for all TLS versions from 1.0 to 1.3.tcp[((tcp[12] & 0xf0) >> 2) + 5] = 0x02
: Capture only packets for which the sixth byte after the TCP header is0x02
. This ensures we only capture Server Hello messages.-w output.pcap
: Store the results inoutput.pcap
.
Once we have let this run from the desired time, we can stop tcpdump
with Ctrl + C
. We will then have several files named output.pcap
with a number at the end.
We can use tcpdump
again to check how many connections of each TLS type we have detected. The total number of TLS connections recorded in the file is available with:
To get the total number of TLS 1.0 connections recorded in the file:
To get the total number of TLS 1.1 connections recorded in the file:
The total number of TLS 1.2 and TLS 1.3 connections recorded in the file is available with: