HADOOP-15169. "hadoop.ssl.enabled.protocols" should be considered in httpserver2. Contributed by Brahma Reddy Battula, Wei-Chiu Chuang.
Reviewed-by: Xiaoyu Yao <xyao@apache.org> Co-authored-By: Brahma Reddy Battula <brahma@apache.org>
This commit is contained in:
parent
85af77c757
commit
c39e9fc9a3
|
@ -538,11 +538,45 @@ public final class HttpServer2 implements FilterContainer {
|
||||||
LOG.info("Excluded Cipher List:" + excludeCiphers);
|
LOG.info("Excluded Cipher List:" + excludeCiphers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setEnabledProtocols(sslContextFactory);
|
||||||
conn.addFirstConnectionFactory(new SslConnectionFactory(sslContextFactory,
|
conn.addFirstConnectionFactory(new SslConnectionFactory(sslContextFactory,
|
||||||
HttpVersion.HTTP_1_1.asString()));
|
HttpVersion.HTTP_1_1.asString()));
|
||||||
|
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setEnabledProtocols(SslContextFactory sslContextFactory) {
|
||||||
|
String enabledProtocols = conf.get(SSLFactory.SSL_ENABLED_PROTOCOLS_KEY,
|
||||||
|
SSLFactory.SSL_ENABLED_PROTOCOLS_DEFAULT);
|
||||||
|
if (!enabledProtocols.equals(SSLFactory.SSL_ENABLED_PROTOCOLS_DEFAULT)) {
|
||||||
|
// Jetty 9.2.4.v20141103 and above excludes certain protocols by
|
||||||
|
// default. Remove the user enabled protocols from the exclude list,
|
||||||
|
// and add them into the include list.
|
||||||
|
String[] jettyExcludedProtocols =
|
||||||
|
sslContextFactory.getExcludeProtocols();
|
||||||
|
String[] enabledProtocolsArray =
|
||||||
|
StringUtils.getTrimmedStrings(enabledProtocols);
|
||||||
|
List<String> enabledProtocolsList =
|
||||||
|
Arrays.asList(enabledProtocolsArray);
|
||||||
|
|
||||||
|
List<String> resetExcludedProtocols = new ArrayList<>();
|
||||||
|
for (String jettyExcludedProtocol: jettyExcludedProtocols) {
|
||||||
|
if (!enabledProtocolsList.contains(jettyExcludedProtocol)) {
|
||||||
|
resetExcludedProtocols.add(jettyExcludedProtocol);
|
||||||
|
} else {
|
||||||
|
LOG.debug("Removed {} from exclude protocol list",
|
||||||
|
jettyExcludedProtocol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sslContextFactory.setExcludeProtocols(
|
||||||
|
resetExcludedProtocols.toArray(new String[0]));
|
||||||
|
LOG.info("Reset exclude protocol list: {}", resetExcludedProtocols);
|
||||||
|
|
||||||
|
sslContextFactory.setIncludeProtocols(enabledProtocolsArray);
|
||||||
|
LOG.info("Enabled protocols: {}", enabledProtocols);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpServer2(final Builder b) throws IOException {
|
private HttpServer2(final Builder b) throws IOException {
|
||||||
|
|
|
@ -98,6 +98,8 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest {
|
||||||
+ "TLS_DHE_RSA_WITH_AES_128_CBC_SHA,\t\n "
|
+ "TLS_DHE_RSA_WITH_AES_128_CBC_SHA,\t\n "
|
||||||
+ "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
|
+ "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
|
||||||
|
|
||||||
|
private static final String INCLUDED_PROTOCOLS = "SSLv2Hello,TLSv1.1";
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setup() throws Exception {
|
public static void setup() throws Exception {
|
||||||
turnOnSSLDebugLogging();
|
turnOnSSLDebugLogging();
|
||||||
|
@ -128,6 +130,8 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest {
|
||||||
|
|
||||||
private static void setupServer(Configuration conf, Configuration sslConf)
|
private static void setupServer(Configuration conf, Configuration sslConf)
|
||||||
throws IOException, URISyntaxException {
|
throws IOException, URISyntaxException {
|
||||||
|
conf.set(SSLFactory.SSL_ENABLED_PROTOCOLS_KEY, INCLUDED_PROTOCOLS);
|
||||||
|
sslConf.set(SSLFactory.SSL_ENABLED_PROTOCOLS_KEY, INCLUDED_PROTOCOLS);
|
||||||
server = new HttpServer2.Builder().setName("test")
|
server = new HttpServer2.Builder().setName("test")
|
||||||
.addEndpoint(new URI("https://localhost")).setConf(conf)
|
.addEndpoint(new URI("https://localhost")).setConf(conf)
|
||||||
.keyPassword(
|
.keyPassword(
|
||||||
|
@ -214,6 +218,22 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest {
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HttpsURLConnection
|
||||||
|
getConnectionWithPreferredProtocolSSLSocketFactory(URL url,
|
||||||
|
String protocols) throws IOException, GeneralSecurityException {
|
||||||
|
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
|
||||||
|
SSLSocketFactory sslSocketFactory = clientSslFactory
|
||||||
|
.createSSLSocketFactory();
|
||||||
|
LOG.info("Creating " +
|
||||||
|
PreferredProtocolSSLSocketFactory.class.getCanonicalName() +
|
||||||
|
" with protocols: " + protocols);
|
||||||
|
PreferredProtocolSSLSocketFactory cipherSSLSocketFactory
|
||||||
|
= new PreferredProtocolSSLSocketFactory(sslSocketFactory,
|
||||||
|
StringUtils.getTrimmedStrings(protocols));
|
||||||
|
conn.setSSLSocketFactory(cipherSSLSocketFactory);
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEcho() throws Exception {
|
public void testEcho() throws Exception {
|
||||||
assertEquals("a:b\nc:d\n",
|
assertEquals("a:b\nc:d\n",
|
||||||
|
@ -269,6 +289,18 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIncludedProtocols() throws Exception {
|
||||||
|
URL url = new URL(baseUrl, SERVLET_PATH_ECHO + "?a=b&c=d");
|
||||||
|
HttpsURLConnection conn =
|
||||||
|
getConnectionWithPreferredProtocolSSLSocketFactory(url,
|
||||||
|
INCLUDED_PROTOCOLS);
|
||||||
|
assertFalse("included protocol list is empty",
|
||||||
|
INCLUDED_PROTOCOLS.isEmpty());
|
||||||
|
|
||||||
|
readFromConnection(conn);
|
||||||
|
}
|
||||||
|
|
||||||
/** Test that verified that additionally included cipher
|
/** Test that verified that additionally included cipher
|
||||||
* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is only available cipher for working
|
* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA is only available cipher for working
|
||||||
* TLS connection from client to server disabled for all other common ciphers.
|
* TLS connection from client to server disabled for all other common ciphers.
|
||||||
|
@ -370,4 +402,78 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class PreferredProtocolSSLSocketFactory extends SSLSocketFactory {
|
||||||
|
private final SSLSocketFactory delegateSocketFactory;
|
||||||
|
private final String[] enabledProtocols;
|
||||||
|
|
||||||
|
PreferredProtocolSSLSocketFactory(SSLSocketFactory sslSocketFactory,
|
||||||
|
String[] enabledProtocols) {
|
||||||
|
delegateSocketFactory = sslSocketFactory;
|
||||||
|
if (null != enabledProtocols && enabledProtocols.length > 0) {
|
||||||
|
this.enabledProtocols = enabledProtocols;
|
||||||
|
} else {
|
||||||
|
this.enabledProtocols = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getDefaultCipherSuites() {
|
||||||
|
return delegateSocketFactory.getDefaultCipherSuites();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getSupportedCipherSuites() {
|
||||||
|
return delegateSocketFactory.getSupportedCipherSuites();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(Socket socket, String string, int i, boolean bln)
|
||||||
|
throws IOException {
|
||||||
|
SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket(
|
||||||
|
socket, string, i, bln);
|
||||||
|
setEnabledProtocols(sslSocket);
|
||||||
|
return sslSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(String string, int i) throws IOException {
|
||||||
|
SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket(
|
||||||
|
string, i);
|
||||||
|
setEnabledProtocols(sslSocket);
|
||||||
|
return sslSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(String string, int i, InetAddress ia, int i1)
|
||||||
|
throws IOException {
|
||||||
|
SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket(
|
||||||
|
string, i, ia, i1);
|
||||||
|
setEnabledProtocols(sslSocket);
|
||||||
|
return sslSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(InetAddress ia, int i) throws IOException {
|
||||||
|
SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket(ia,
|
||||||
|
i);
|
||||||
|
setEnabledProtocols(sslSocket);
|
||||||
|
return sslSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1)
|
||||||
|
throws IOException {
|
||||||
|
SSLSocket sslSocket = (SSLSocket) delegateSocketFactory.createSocket(ia,
|
||||||
|
i, ia1, i1);
|
||||||
|
setEnabledProtocols(sslSocket);
|
||||||
|
return sslSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setEnabledProtocols(SSLSocket sslSocket) {
|
||||||
|
if (null != enabledProtocols) {
|
||||||
|
sslSocket.setEnabledProtocols(enabledProtocols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue