Skip to content

Commit de231a2

Browse files
author
Sahil Takiar
committed
HADOOP-16346: Stabilize S3A OpenSSL support
1 parent d12ad9e commit de231a2

9 files changed

Lines changed: 102 additions & 24 deletions

File tree

hadoop-common-project/hadoop-common/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,11 @@
346346
<dependency>
347347
<groupId>org.wildfly.openssl</groupId>
348348
<artifactId>wildfly-openssl</artifactId>
349+
<scope>test</scope>
350+
</dependency>
351+
<dependency>
352+
<groupId>org.wildfly.openssl</groupId>
353+
<artifactId>wildfly-openssl-java</artifactId>
349354
<scope>provided</scope>
350355
</dependency>
351356
<dependency>

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/DelegatingSSLSocketFactory.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@
5858
* SSL with no modification to the list of enabled ciphers.</li>
5959
* </ul>
6060
* </p>
61+
*
62+
* In order to load OpenSSL, applications must ensure the wildfly-openssl
63+
* artifact is on the classpath. Currently, only ABFS and S3A provide
64+
* wildfly-openssl as a runtime dependency.
6165
*/
6266
public final class DelegatingSSLSocketFactory extends SSLSocketFactory {
6367

@@ -170,8 +174,14 @@ private void initializeSSLContext(SSLChannelMode preferredChannelMode)
170174
OpenSSLProvider.register();
171175
openSSLProviderRegistered = true;
172176
}
177+
java.util.logging.Logger logger = java.util.logging.Logger.getLogger(
178+
SSL.class.getName());
179+
logger.setLevel(Level.WARNING);
173180
ctx = SSLContext.getInstance("openssl.TLS");
174181
ctx.init(null, null, null);
182+
// Strong reference needs to be kept to logger until initialization of
183+
// SSLContext finished (see HADOOP-16174):
184+
logger.setLevel(Level.INFO);
175185
channelMode = SSLChannelMode.OpenSSL;
176186
break;
177187
case Default_JSSE:

hadoop-common-project/hadoop-common/src/main/resources/core-default.xml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,11 +1978,16 @@
19781978
<description>
19791979
If secure connections to S3 are enabled, configures the SSL
19801980
implementation used to encrypt connections to S3. Supported values are:
1981-
"default_jsse" and "default_jsse_with_gcm". "default_jsse" uses the Java
1982-
Secure Socket Extension package (JSSE). However, when running on Java 8,
1983-
the GCM cipher is removed from the list of enabled ciphers. This is due
1984-
to performance issues with GCM in Java 8. "default_jsse_with_gcm" uses
1985-
the JSSE with the default list of cipher suites.
1981+
"default_jsse", "default_jsse_with_gcm", "default", and "openssl".
1982+
"default_jsse" uses the Java Secure Socket Extension package (JSSE).
1983+
However, when running on Java 8, the GCM cipher is removed from the list
1984+
of enabled ciphers. This is due to performance issues with GCM in Java 8.
1985+
"default_jsse_with_gcm" uses the JSSE with the default list of cipher
1986+
suites. "default_jsse_with_gcm" is equivalent to the behavior prior to
1987+
this feature being introduced. "default" attempts to use OpenSSL rather
1988+
than the JSSE for SSL encryption, if OpenSSL libraries cannot be loaded,
1989+
it falls back to the "default_jsse" behavior. "openssl" attempts to use
1990+
OpenSSL as well, but fails if OpenSSL libraries cannot be loaded.
19861991
</description>
19871992
</property>
19881993

hadoop-project/pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@
184184
<jline.version>3.9.0</jline.version>
185185
<powermock.version>1.5.6</powermock.version>
186186
<solr.version>7.7.0</solr.version>
187+
<openssl-wildfly.version>1.0.7.Final</openssl-wildfly.version>
187188
</properties>
188189

189190
<dependencyManagement>
@@ -1358,7 +1359,12 @@
13581359
<dependency>
13591360
<groupId>org.wildfly.openssl</groupId>
13601361
<artifactId>wildfly-openssl</artifactId>
1361-
<version>1.0.7.Final</version>
1362+
<version>${openssl-wildfly.version}</version>
1363+
</dependency>
1364+
<dependency>
1365+
<groupId>org.wildfly.openssl</groupId>
1366+
<artifactId>wildfly-openssl-java</artifactId>
1367+
<version>${openssl-wildfly.version}</version>
13621368
</dependency>
13631369

13641370
<dependency>

hadoop-tools/hadoop-aws/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,11 @@
430430
<artifactId>assertj-core</artifactId>
431431
<scope>test</scope>
432432
</dependency>
433+
<dependency>
434+
<groupId>org.wildfly.openssl</groupId>
435+
<artifactId>wildfly-openssl</artifactId>
436+
<scope>runtime</scope>
437+
</dependency>
433438
<dependency>
434439
<groupId>junit</groupId>
435440
<artifactId>junit</artifactId>

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/impl/NetworkBinding.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,6 @@ public static void bindSSLChannelMode(Configuration conf,
8080
throw new IllegalArgumentException(channelModeString +
8181
" is not a valid value for " + SSL_CHANNEL_MODE);
8282
}
83-
if (channelMode == DelegatingSSLSocketFactory.SSLChannelMode.OpenSSL ||
84-
channelMode == DelegatingSSLSocketFactory.SSLChannelMode.Default) {
85-
throw new UnsupportedOperationException("S3A does not support " +
86-
"setting " + SSL_CHANNEL_MODE + " " +
87-
DelegatingSSLSocketFactory.SSLChannelMode.OpenSSL + " or " +
88-
DelegatingSSLSocketFactory.SSLChannelMode.Default);
89-
}
9083

9184
// Look for AWS_SOCKET_FACTORY_CLASSNAME on the classpath and instantiate
9285
// an instance using the DelegatingSSLSocketFactory as the

hadoop-tools/hadoop-aws/src/site/markdown/tools/hadoop-aws/performance.md

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -535,10 +535,41 @@ GCM cipher is only disabled on Java 8. GCM performance has been improved
535535
in Java 9, so if `default_jsse` is specified and applications run on Java
536536
9, they should see no difference compared to running with the vanilla JSSE.
537537

538-
Other options for `fs.s3a.ssl.channel.mode` include `default_jsse_with_gcm`.
539-
This option includes GCM in the list of cipher suites on Java 8, so it is
540-
equivalent to running with the vanilla JSSE. The naming convention is setup
541-
in order to preserve backwards compatibility with HADOOP-15669.
538+
`fs.s3a.ssl.channel.mode` can be set to `default_jsse_with_gcm`. This option
539+
includes GCM in the list of cipher suites on Java 8, so it is equivalent to
540+
running with the vanilla JSSE.
541+
542+
### OpenSSL Acceleration
543+
544+
**Experimental Feature**
545+
546+
As of HADOOP-16050 and HADOOP-16346, `fs.s3a.ssl.channel.mode` can be set to
547+
either `default` or `openssl` to enable native OpenSSL acceleration of HTTPS
548+
requests. OpenSSL implements the SSL and TLS protocols using native code. For
549+
users reading a large amount of data over HTTPS, OpenSSL can provide a
550+
significant performance benefit over the JSSE.
551+
552+
S3A uses the
553+
[WildFly OpenSSL](https://github.com/wildfly-security/wildfly-openssl) library
554+
to bind OpenSSL to the Java JSSE APIs. This library allows S3A to
555+
transparently read data using OpenSSL. The wildfly-openssl library is a
556+
runtime dependency of S3A and contains native libraries for binding the Java
557+
JSSE to OpenSSL.
558+
559+
WildFly OpenSSL must load OpenSSL itself. This can be done using the system
560+
property `org.wildfly.openssl.path`. For example,
561+
`HADOOP_OPTS="-Dorg.wildfly.openssl.path=<path to OpenSSL libraries>
562+
${HADOOP_OPTS}"`. See WildFly OpenSSL documentation for more details.
563+
564+
When `fs.s3a.ssl.channel.mode` is set to `default`, S3A will attempt to load
565+
the OpenSSL libraries using the WildFly library. If it is unsuccessful, it
566+
will fall back to the `default_jsse` behavior.
567+
568+
When `fs.s3a.ssl.channel.mode` is set to `openssl`, S3A will attempt to load
569+
the OpenSSL libraries using WildFly. If it is unsuccessful, it will throw an
570+
exception and S3A initialization will fail.
571+
572+
### `fs.s3a.ssl.channel.mode` Configuration
542573

543574
`fs.s3a.ssl.channel.mode` can be configured as follows:
544575

@@ -549,11 +580,16 @@ in order to preserve backwards compatibility with HADOOP-15669.
549580
<description>
550581
If secure connections to S3 are enabled, configures the SSL
551582
implementation used to encrypt connections to S3. Supported values are:
552-
"default_jsse" and "default_jsse_with_gcm". "default_jsse" uses the Java
553-
Secure Socket Extension package (JSSE). However, when running on Java 8,
554-
the GCM cipher is removed from the list of enabled ciphers. This is due
555-
to performance issues with GCM in Java 8. "default_jsse_with_gcm" uses
556-
the JSSE with the default list of cipher suites.
583+
"default_jsse", "default_jsse_with_gcm", "default", and "openssl".
584+
"default_jsse" uses the Java Secure Socket Extension package (JSSE).
585+
However, when running on Java 8, the GCM cipher is removed from the list
586+
of enabled ciphers. This is due to performance issues with GCM in Java 8.
587+
"default_jsse_with_gcm" uses the JSSE with the default list of cipher
588+
suites. "default_jsse_with_gcm" is equivalent to the behavior prior to
589+
this feature being introduced. "default" attempts to use OpenSSL rather
590+
than the JSSE for SSL encryption, if OpenSSL libraries cannot be loaded,
591+
it falls back to the "default_jsse" behavior. "openssl" attempts to use
592+
OpenSSL as well, but fails if OpenSSL libraries cannot be loaded.
557593
</description>
558594
</property>
559595
```
@@ -564,6 +600,11 @@ Supported values for `fs.s3a.ssl.channel.mode`:
564600
|-------------------------------|-------------|
565601
| default_jsse | Uses Java JSSE without GCM on Java 8 |
566602
| default_jsse_with_gcm | Uses Java JSSE |
603+
| default | Uses OpenSSL, falls back to default_jsse if OpenSSL cannot be loaded |
604+
| openssl | Uses OpenSSL, fails if OpenSSL cannot be loaded |
605+
606+
The naming convention is setup in order to preserve backwards compatibility
607+
with HADOOP-15669.
567608

568609
Other options may be added to `fs.s3a.ssl.channel.mode` in the future as
569610
further SSL optimizations are made.

hadoop-tools/hadoop-aws/src/test/java/org/apache/hadoop/fs/contract/s3a/ITestS3AContractSeek.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Arrays;
2525
import java.util.Collection;
2626

27+
import org.junit.Before;
2728
import org.junit.Test;
2829
import org.junit.runner.RunWith;
2930
import org.junit.runners.Parameterized;
@@ -41,6 +42,7 @@
4142
import org.apache.hadoop.fs.s3a.S3AInputPolicy;
4243
import org.apache.hadoop.fs.s3a.S3ATestUtils;
4344
import org.apache.hadoop.security.ssl.DelegatingSSLSocketFactory;
45+
import org.apache.hadoop.util.NativeCodeLoader;
4446

4547
import static com.google.common.base.Preconditions.checkNotNull;
4648
import static org.apache.hadoop.fs.s3a.Constants.INPUT_FADVISE;
@@ -55,6 +57,9 @@
5557
SSLChannelMode.Default_JSSE;
5658
import static org.apache.hadoop.security.ssl.DelegatingSSLSocketFactory.
5759
SSLChannelMode.Default_JSSE_with_GCM;
60+
import static org.apache.hadoop.security.ssl.DelegatingSSLSocketFactory.
61+
SSLChannelMode.OpenSSL;
62+
import static org.junit.Assume.assumeTrue;
5863

5964

6065
/**
@@ -84,7 +89,7 @@ public class ITestS3AContractSeek extends AbstractContractSeekTest {
8489
public static Collection<Object[]> params() {
8590
return Arrays.asList(new Object[][]{
8691
{INPUT_FADV_SEQUENTIAL, Default_JSSE},
87-
{INPUT_FADV_RANDOM, Default_JSSE_with_GCM},
92+
{INPUT_FADV_RANDOM, OpenSSL},
8893
{INPUT_FADV_NORMAL, Default_JSSE_with_GCM},
8994
});
9095
}
@@ -200,6 +205,14 @@ public S3AFileSystem getFileSystem() {
200205
return (S3AFileSystem) super.getFileSystem();
201206
}
202207

208+
@Before
209+
public void validateSSLChannelMode() {
210+
if (this.sslChannelMode == OpenSSL) {
211+
assumeTrue(NativeCodeLoader.isNativeCodeLoaded() &&
212+
NativeCodeLoader.buildSupportsOpenssl());
213+
}
214+
}
215+
203216
@Test
204217
public void testReadPolicyInFS() throws Throwable {
205218
describe("Verify the read policy is being consistently set");

hadoop-tools/hadoop-azure/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@
194194
<dependency>
195195
<groupId>org.wildfly.openssl</groupId>
196196
<artifactId>wildfly-openssl</artifactId>
197-
<scope>compile</scope>
197+
<scope>runtime</scope>
198198
</dependency>
199199

200200
<!--com.fasterxml.jackson is used by WASB, not ABFS-->

0 commit comments

Comments
 (0)