diff --git a/CHANGES.md b/CHANGES.md index 74217cccaf0d..18b7ed989fb6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -65,6 +65,9 @@ * RunInference Wrapper with Sklearn Model Handler support added in Go SDK ([#24497](https://github.com/apache/beam/issues/23382)). * X feature added (Java/Python) ([#X](https://github.com/apache/beam/issues/X)). +* Adding override of allowed TLS algorithms (Java), now maintaining the disabled/legacy algorithms + present in 2.43.0 (up to 1.8.0_342, 11.0.16, 17.0.2 for respective Java versions). This is accompanied + by an explicit re-enabling of TLSv1 and TLSv1.1 for Java 8 and Java 11. ## Breaking Changes @@ -81,6 +84,7 @@ ## Bugfixes * Avoids Cassandra syntax error when user-defined query has no where clause in it (Java) ([#24829](https://github.com/apache/beam/issues/24829)). +* Fixed JDBC connection failures (Java) during handshake due to deprecated TLSv1(.1) protocol for the JDK. ([#24623](https://github.com/apache/beam/issues/24623)) ## Known Issues diff --git a/sdks/java/container/common.gradle b/sdks/java/container/common.gradle index 265d14fbe9c7..4886cd271d6c 100644 --- a/sdks/java/container/common.gradle +++ b/sdks/java/container/common.gradle @@ -80,8 +80,10 @@ task copyGolangLicenses(type: Copy) { task copyJdkOptions(type: Copy) { if (imageJavaVersion == "17" || imageJavaVersion == "11") { from "option-jamm.json" - into "build/target/options" } + from "java${imageJavaVersion}-security.properties" + from "option-java${imageJavaVersion}-security.json" + into "build/target/options" } task skipPullLicenses(type: Exec) { @@ -129,4 +131,4 @@ dockerPrepare.dependsOn copySdkHarnessLauncher dockerPrepare.dependsOn copyDockerfileDependencies dockerPrepare.dependsOn ":sdks:java:container:downloadCloudProfilerAgent" dockerPrepare.dependsOn copyJdkOptions -dockerPrepare.dependsOn validateJavaHome \ No newline at end of file +dockerPrepare.dependsOn validateJavaHome diff --git a/sdks/java/container/java11/java11-security.properties b/sdks/java/container/java11/java11-security.properties new file mode 100644 index 000000000000..caf64592c400 --- /dev/null +++ b/sdks/java/container/java11/java11-security.properties @@ -0,0 +1,47 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Java 11 java.security properties file override for JVM +# base properties derived from: +# openjdk version "11.0.16" 2022-07-19 +# OpenJDK Runtime Environment 18.9 (build 11.0.16+8) +# OpenJDK 64-Bit Server VM 18.9 (build 11.0.16+8, mixed mode, sharing) + +# Java has now disabled TLSv1 and TLSv1.1. We specifically put it in the +# legacy algorithms list to allow it to be used if something better is not +# available (e.g. TLSv1.2). This will prevent breakages for existing users +# (for example JDBC with MySQL). See +# https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8202343 +# for additional details. +jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, \ + DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \ + include jdk.disabled.namedCurves + +jdk.tls.legacyAlgorithms= \ + K_NULL, C_NULL, M_NULL, \ + DH_anon, ECDH_anon, \ + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC, TLSv1, TLSv1.1 + +# /dev/random blocks in virtualized environments due to lack of +# good entropy sources, which makes SecureRandom use impractical. +# In particular, that affects the performance of HTTPS that relies +# on SecureRandom. +# +# Due to that, /dev/urandom is used as the default. +# +# See http://www.2uo.de/myths-about-urandom/ for some background +# on security of /dev/urandom on Linux. +securerandom.source=file:/dev/./urandom \ No newline at end of file diff --git a/sdks/java/container/java11/option-java11-security.json b/sdks/java/container/java11/option-java11-security.json new file mode 100644 index 000000000000..a8ad9672a3fc --- /dev/null +++ b/sdks/java/container/java11/option-java11-security.json @@ -0,0 +1,9 @@ +{ + "name": "java-security", + "enabled": true, + "options": { + "properties": { + "java.security.properties": "/opt/apache/beam/options/java11-security.properties" + } + } +} diff --git a/sdks/java/container/java17/java17-security.properties b/sdks/java/container/java17/java17-security.properties new file mode 100644 index 000000000000..ec2a5c039cb9 --- /dev/null +++ b/sdks/java/container/java17/java17-security.properties @@ -0,0 +1,47 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Java 17 java.security properties file override for JVM +# base properties derived from: +# openjdk version "17.0.2" 2022-01-18 +# OpenJDK Runtime Environment (build 17.0.2+8-86) +# OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing) + +# Java has now disabled TLSv1 and TLSv1.1. We specifically put it in the +# legacy algorithms list to allow it to be used if something better is not +# available (e.g. TLSv1.2). This will prevent breakages for existing users +# (for example JDBC with MySQL). See +# https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8202343 +# for additional details. +jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, \ + DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL + +# The raw value from 17.0.2 for legacyAlgorithms is +# NULL, anon, RC4, DES, 3DES_EDE_CBC +# Because these values are in disabledAlgorithms, it is erroneous to include +# them in legacy (they are disabled in Java 8 and Java 11 as well). Here we +# only include TLSv1 and TLSv1.1 which were removed from disabledAlgorithms +jdk.tls.legacyAlgorithms=TLSv1, TLSv1.1 + +# /dev/random blocks in virtualized environments due to lack of +# good entropy sources, which makes SecureRandom use impractical. +# In particular, that affects the performance of HTTPS that relies +# on SecureRandom. +# +# Due to that, /dev/urandom is used as the default. +# +# See http://www.2uo.de/myths-about-urandom/ for some background +# on security of /dev/urandom on Linux. +securerandom.source=file:/dev/./urandom \ No newline at end of file diff --git a/sdks/java/container/java17/option-java17-security.json b/sdks/java/container/java17/option-java17-security.json new file mode 100644 index 000000000000..979d4be90d1e --- /dev/null +++ b/sdks/java/container/java17/option-java17-security.json @@ -0,0 +1,9 @@ +{ + "name": "java-security", + "enabled": true, + "options": { + "properties": { + "java.security.properties": "/opt/apache/beam/options/java17-security.properties" + } + } +} diff --git a/sdks/java/container/java8/java8-security.properties b/sdks/java/container/java8/java8-security.properties new file mode 100644 index 000000000000..f637d3ef7567 --- /dev/null +++ b/sdks/java/container/java8/java8-security.properties @@ -0,0 +1,47 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Java 8 java.security properties file override for JVM +# base properties derived from: +# openjdk version "1.8.0_342" +# OpenJDK Runtime Environment (build 1.8.0_342-b07) +# OpenJDK 64-Bit Server VM (build 25.342-b07, mixed mode) + +# Java has now disabled TLSv1 and TLSv1.1. We specifically put it in the +# legacy algorithms list to allow it to be used if something better is not +# available (e.g. TLSv1.2). This will prevent breakages for existing users +# (for example JDBC with MySQL). See +# https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8202343 +# for additional details. +jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, \ + DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \ + include jdk.disabled.namedCurves + +jdk.tls.legacyAlgorithms= \ + K_NULL, C_NULL, M_NULL, \ + DH_anon, ECDH_anon, \ + RC4_128, RC4_40, DES_CBC, DES40_CBC, \ + 3DES_EDE_CBC, TLSv1, TLSv1.1 + +# /dev/random blocks in virtualized environments due to lack of +# good entropy sources, which makes SecureRandom use impractical. +# In particular, that affects the performance of HTTPS that relies +# on SecureRandom. +# +# Due to that, /dev/urandom is used as the default. +# +# See http://www.2uo.de/myths-about-urandom/ for some background +# on security of /dev/urandom on Linux. +securerandom.source=file:/dev/./urandom \ No newline at end of file diff --git a/sdks/java/container/java8/option-java8-security.json b/sdks/java/container/java8/option-java8-security.json new file mode 100644 index 000000000000..47f2938bf7cd --- /dev/null +++ b/sdks/java/container/java8/option-java8-security.json @@ -0,0 +1,9 @@ +{ + "name": "java-security", + "enabled": true, + "options": { + "properties": { + "java.security.properties": "/opt/apache/beam/options/java8-security.properties" + } + } +} diff --git a/sdks/java/core/src/test/java/org/apache/beam/sdk/SdkHarnessEnvironmentTest.java b/sdks/java/core/src/test/java/org/apache/beam/sdk/SdkHarnessEnvironmentTest.java index dd2d469fd4be..2c61e8a62041 100644 --- a/sdks/java/core/src/test/java/org/apache/beam/sdk/SdkHarnessEnvironmentTest.java +++ b/sdks/java/core/src/test/java/org/apache/beam/sdk/SdkHarnessEnvironmentTest.java @@ -19,7 +19,12 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.hasItemInArray; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertNotNull; +import java.security.Security; +import javax.net.ssl.SSLContext; import org.apache.beam.sdk.coders.StringUtf8Coder; import org.apache.beam.sdk.testing.PAssert; import org.apache.beam.sdk.testing.TestPipeline; @@ -66,4 +71,43 @@ public void testJammAgentAvailable() throws Exception { PAssert.that(output).containsInAnyOrder("measured"); p.run().waitUntilFinish(); } + + /** {@link DoFn} used to validate that TLS was enabled as part of java security properties. */ + private static class TLSDoFn extends DoFn { + @ProcessElement + public void processElement(ProcessContext c) throws Exception { + String[] disabledAlgorithms = + Security.getProperty("jdk.tls.disabledAlgorithms").trim().split("\\s*,\\s*"); + String[] legacyAlgorithms = + Security.getProperty("jdk.tls.legacyAlgorithms").trim().split("\\s*,\\s*"); + assertThat(disabledAlgorithms, not(hasItemInArray("TLSv1"))); + assertThat(disabledAlgorithms, not(hasItemInArray("TLSv1.1"))); + assertThat(legacyAlgorithms, hasItemInArray("TLSv1")); + assertThat(legacyAlgorithms, hasItemInArray("TLSv1.1")); + + // getDefaultSSLParameters() shows all protocols that JSSE implements that are allowed. + // getSupportedSSLParameters() shows all protocols that JSSE implements including those that + // are disabled. + SSLContext context = SSLContext.getInstance("TLS"); + context.init(null, null, null); + assertNotNull(context); + String[] defaultProtocols = context.getDefaultSSLParameters().getProtocols(); + assertThat(defaultProtocols, hasItemInArray("TLSv1")); + assertThat(defaultProtocols, hasItemInArray("TLSv1.1")); + + c.output("TLSv1-TLSv1.1 enabled"); + } + } + + @Test + @Category({ValidatesRunner.class, UsesSdkHarnessEnvironment.class}) + public void testTlsAvailable() throws Exception { + PCollection input = p.apply(Create.of("TLS").withCoder(StringUtf8Coder.of())); + + PCollection output = input.apply(ParDo.of(new TLSDoFn())); + + PAssert.that(output).containsInAnyOrder("TLSv1-TLSv1.1 enabled"); + + p.run().waitUntilFinish(); + } }