You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by da...@apache.org on 2018/10/05 08:21:26 UTC

lucene-solr:jira/http2: SOLR-12837: Support SSL for http/2

Repository: lucene-solr
Updated Branches:
  refs/heads/jira/http2 f6f40462c -> 135de05d9


SOLR-12837: Support SSL for http/2


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/135de05d
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/135de05d
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/135de05d

Branch: refs/heads/jira/http2
Commit: 135de05d9d92c89a992a4acb0c6c3a929e1829d1
Parents: f6f4046
Author: Cao Manh Dat <da...@apache.org>
Authored: Fri Oct 5 15:21:13 2018 +0700
Committer: Cao Manh Dat <da...@apache.org>
Committed: Fri Oct 5 15:21:13 2018 +0700

----------------------------------------------------------------------
 lucene/ivy-versions.properties                  |  2 ++
 lucene/tools/junit4/solr-tests.policy           |  5 +++
 .../client/solrj/embedded/JettySolrRunner.java  | 35 ++++++++++++++++--
 solr/server/etc/conscrypt.xml                   | 11 ++++++
 solr/server/etc/jetty-https.xml                 | 26 +++++++++++++-
 solr/server/ivy.xml                             |  3 ++
 solr/server/modules/conscrypt.mod               |  9 +++++
 solr/server/modules/https.mod                   |  1 +
 solr/solrj/ivy.xml                              |  3 ++
 .../apache/solr/client/solrj/SolrClient.java    |  8 +++++
 .../solr/client/solrj/impl/Http2SolrClient.java | 37 +++++++-------------
 .../java/org/apache/solr/SolrTestCaseJ4.java    |  6 +++-
 12 files changed, 116 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/135de05d/lucene/ivy-versions.properties
----------------------------------------------------------------------
diff --git a/lucene/ivy-versions.properties b/lucene/ivy-versions.properties
index 868e908..8cce10f 100644
--- a/lucene/ivy-versions.properties
+++ b/lucene/ivy-versions.properties
@@ -240,6 +240,8 @@ org.codehaus.janino.version = 2.7.6
 /org.codehaus.woodstox/stax2-api = 3.1.4
 /org.codehaus.woodstox/woodstox-core-asl = 4.4.1
 
+/org.conscrypt/conscrypt-openjdk-uber = 1.3.0
+
 org.eclipse.jetty.version = 9.4.11.v20180605
 /org.eclipse.jetty.http2/http2-client = ${org.eclipse.jetty.version}
 /org.eclipse.jetty.http2/http2-common = ${org.eclipse.jetty.version}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/135de05d/lucene/tools/junit4/solr-tests.policy
----------------------------------------------------------------------
diff --git a/lucene/tools/junit4/solr-tests.policy b/lucene/tools/junit4/solr-tests.policy
index 1c46a78..1b810b0 100644
--- a/lucene/tools/junit4/solr-tests.policy
+++ b/lucene/tools/junit4/solr-tests.policy
@@ -76,6 +76,11 @@ grant {
   // SSL related properties for Solr tests
   permission java.security.SecurityPermission "getProperty.ssl.*";
   permission javax.net.ssl.SSLPermission "setDefaultSSLContext";
+  permission java.security.SecurityPermission "insertProvider.*";
+  permission java.security.SecurityPermission "putProviderProperty.*";
+  permission java.security.SecurityPermission "getProviderProperty.*";
+  permission java.security.SecurityPermission "getProperty.conscrypt.*";
+  permission java.security.SecurityPermission "putProperty.conscrypt.*";
 
   // SASL/Kerberos related properties for Solr tests
   permission javax.security.auth.PrivateCredentialPermission "javax.security.auth.kerberos.KerberosTicket * \"*\"", "read";

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/135de05d/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java b/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
index 0bc5f18..39340a9 100644
--- a/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
+++ b/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
@@ -30,6 +30,7 @@ import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.security.Security;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.LinkedList;
@@ -41,11 +42,16 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.impl.HttpSolrClient;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.servlet.SolrDispatchFilter;
+import org.conscrypt.OpenSSLProvider;
+import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
+import org.eclipse.jetty.http2.HTTP2Cipher;
 import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
+import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
 import org.eclipse.jetty.server.Connector;
 import org.eclipse.jetty.server.HttpConfiguration;
 import org.eclipse.jetty.server.HttpConnectionFactory;
@@ -236,8 +242,31 @@ public class JettySolrRunner {
       if (sslcontext != null) {
         configuration.setSecureScheme("https");
         configuration.addCustomizer(new SecureRequestCustomizer());
-        connector = new ServerConnector(server, new SslConnectionFactory(sslcontext, "http/1.1"),
-            new HttpConnectionFactory(configuration));
+        HttpConnectionFactory http1ConnectionFactory = new HttpConnectionFactory(configuration);
+
+        if (config.onlyHttp1) {
+          connector = new ServerConnector(server, new SslConnectionFactory(sslcontext,
+              http1ConnectionFactory.getProtocol()),
+              http1ConnectionFactory);
+        } else {
+          sslcontext.setProvider("Conscrypt");
+          sslcontext.setCipherComparator(HTTP2Cipher.COMPARATOR);
+
+          connector = new ServerConnector(server);
+          SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(sslcontext, "alpn");
+          connector.addConnectionFactory(sslConnectionFactory);
+          connector.setDefaultProtocol(sslConnectionFactory.getProtocol());
+
+          HTTP2ServerConnectionFactory http2ConnectionFactory = new HTTP2ServerConnectionFactory(configuration);
+
+          ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory(
+              http2ConnectionFactory.getProtocol(),
+              http1ConnectionFactory.getProtocol());
+          alpn.setDefaultProtocol(http1ConnectionFactory.getProtocol());
+          connector.addConnectionFactory(alpn);
+          connector.addConnectionFactory(http1ConnectionFactory);
+          connector.addConnectionFactory(http2ConnectionFactory);
+        }
       } else {
         if (config.onlyHttp1) {
           connector = new ServerConnector(server, new HttpConnectionFactory(configuration));
@@ -505,7 +534,7 @@ public class JettySolrRunner {
         throw new IllegalStateException("Jetty Connector is not open: " + 
                                         c.getLocalPort());
       }
-      protocol = c.getDefaultProtocol().startsWith("SSL")  ? "https" : "http";
+      protocol = c.getDefaultProtocol().equalsIgnoreCase("ssl")  ? "https" : "http";
       return new URL(protocol, c.getHost(), c.getLocalPort(), config.context);
 
     } catch (MalformedURLException e) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/135de05d/solr/server/etc/conscrypt.xml
----------------------------------------------------------------------
diff --git a/solr/server/etc/conscrypt.xml b/solr/server/etc/conscrypt.xml
new file mode 100644
index 0000000..591d426
--- /dev/null
+++ b/solr/server/etc/conscrypt.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
+<Configure id="Conscrypt" class="org.conscrypt.OpenSSLProvider">
+  <Call class="java.security.Security" name="insertProviderAt">
+    <Arg><Ref refid="Conscrypt"/></Arg>
+    <Arg type="Integer">1</Arg>
+  </Call>
+  <Ref refid="sslContextFactory">
+    <Set name="Provider"><Property name="solr.jetty.ssl.provider" default="Conscrypt"></Property></Set>
+  </Ref>
+</Configure>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/135de05d/solr/server/etc/jetty-https.xml
----------------------------------------------------------------------
diff --git a/solr/server/etc/jetty-https.xml b/solr/server/etc/jetty-https.xml
index 32685ff..41c3f19 100644
--- a/solr/server/etc/jetty-https.xml
+++ b/solr/server/etc/jetty-https.xml
@@ -8,6 +8,13 @@
 <!-- ============================================================= -->
 <Configure id="Server" class="org.eclipse.jetty.server.Server">
 
+  <Ref refid="sslContextFactory">
+    <Set name="CipherComparator">
+      <Get class="org.eclipse.jetty.http2.HTTP2Cipher" name="COMPARATOR"/>
+    </Set>
+    <Set name="useCipherSuitesOrder">true</Set>    
+  </Ref>
+
   <!-- =========================================================== -->
   <!-- Add a HTTPS Connector.                                      -->
   <!-- Configure an o.e.j.server.ServerConnector with connection   -->
@@ -29,11 +36,27 @@
           <Array type="org.eclipse.jetty.server.ConnectionFactory">
             <Item>
               <New class="org.eclipse.jetty.server.SslConnectionFactory">
-                <Arg name="next">http/1.1</Arg>
+                <Arg name="next">alpn</Arg>
                 <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
               </New>
             </Item>
             <Item>
+              <New id="alpn" class="org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory">                
+                <Arg name="protocols">
+                  <Array type="java.lang.String">
+                    <Item>h2</Item>
+                    <Item>http/1.1</Item>
+                  </Array>
+                </Arg>
+                <Set name="defaultProtocol">http/1.1</Set>  
+              </New>
+            </Item>
+            <Item>
+              <New class="org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory">
+                <Arg name="config"><Ref refid="sslHttpConfig"/></Arg>
+              </New>
+            </Item>
+            <Item>
               <New class="org.eclipse.jetty.server.HttpConnectionFactory">
                 <Arg name="config"><Ref refid="sslHttpConfig"/></Arg>
               </New>
@@ -49,4 +72,5 @@
       </New>
     </Arg>
   </Call>
+
 </Configure>

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/135de05d/solr/server/ivy.xml
----------------------------------------------------------------------
diff --git a/solr/server/ivy.xml b/solr/server/ivy.xml
index cc13a0b..a1d191c 100644
--- a/solr/server/ivy.xml
+++ b/solr/server/ivy.xml
@@ -56,10 +56,13 @@
     <dependency org="org.eclipse.jetty" name="jetty-util" rev="${/org.eclipse.jetty/jetty-util}" conf="jetty"/>
     <dependency org="org.eclipse.jetty" name="jetty-webapp" rev="${/org.eclipse.jetty/jetty-webapp}" conf="jetty"/>
     <dependency org="org.eclipse.jetty" name="jetty-xml" rev="${/org.eclipse.jetty/jetty-xml}" conf="jetty"/>
+    <dependency org="org.eclipse.jetty" name="jetty-alpn-conscrypt-server" rev="${/org.eclipse.jetty/jetty-xml}" conf="jetty"/>
+    <dependency org="org.eclipse.jetty" name="jetty-alpn-server" rev="${/org.eclipse.jetty/jetty-xml}" conf="jetty"/>
 
     <dependency org="org.eclipse.jetty.http2" name="http2-server" rev="${/org.eclipse.jetty.http2/http2-server}" conf="jetty"/>
     <dependency org="org.eclipse.jetty.http2" name="http2-common" rev="${/org.eclipse.jetty.http2/http2-common}" conf="jetty"/>
     <dependency org="org.eclipse.jetty.http2" name="http2-hpack" rev="${/org.eclipse.jetty.http2/http2-hpack}" conf="jetty"/>
+    <dependency org="org.conscrypt" name="conscrypt-openjdk-uber" rev="${/org.conscrypt/conscrypt-openjdk-uber}" conf="jetty"/>
 
     <dependency org="javax.servlet" name="javax.servlet-api" rev="${/javax.servlet/javax.servlet-api}" conf="jetty"/>
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/135de05d/solr/server/modules/conscrypt.mod
----------------------------------------------------------------------
diff --git a/solr/server/modules/conscrypt.mod b/solr/server/modules/conscrypt.mod
new file mode 100644
index 0000000..638e3d6
--- /dev/null
+++ b/solr/server/modules/conscrypt.mod
@@ -0,0 +1,9 @@
+#
+# Jetty HTTPS Connector
+#
+
+[depend]
+ssl
+
+[xml]
+etc/conscrypt.xml
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/135de05d/solr/server/modules/https.mod
----------------------------------------------------------------------
diff --git a/solr/server/modules/https.mod b/solr/server/modules/https.mod
index 8affbcf..18e024f 100644
--- a/solr/server/modules/https.mod
+++ b/solr/server/modules/https.mod
@@ -4,6 +4,7 @@
 
 [depend]
 ssl
+conscrypt
 
 [xml]
 etc/jetty-https.xml
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/135de05d/solr/solrj/ivy.xml
----------------------------------------------------------------------
diff --git a/solr/solrj/ivy.xml b/solr/solrj/ivy.xml
index fa5277f..671815b 100644
--- a/solr/solrj/ivy.xml
+++ b/solr/solrj/ivy.xml
@@ -49,6 +49,9 @@
     <dependency org="org.eclipse.jetty" name="jetty-util" rev="${/org.eclipse.jetty/jetty-util}" conf="compile"/>
     <dependency org="org.eclipse.jetty" name="jetty-http" rev="${/org.eclipse.jetty/jetty-http}" conf="compile"/>
     <dependency org="org.eclipse.jetty" name="jetty-io" rev="${/org.eclipse.jetty/jetty-io}" conf="compile"/>
+    <dependency org="org.eclipse.jetty" name="jetty-alpn-conscrypt-client" rev="${/org.eclipse.jetty/jetty-io}" conf="compile"/>
+    <dependency org="org.eclipse.jetty" name="jetty-alpn-client" rev="${/org.eclipse.jetty/jetty-io}" conf="compile"/>
+    <dependency org="org.conscrypt" name="conscrypt-openjdk-uber" rev="${/org.conscrypt/conscrypt-openjdk-uber}" conf="compile"/>
 
     <dependency org="org.apache.logging.log4j" name="log4j-slf4j-impl" rev="${/org.apache.logging.log4j/log4j-slf4j-impl}" conf="test"/>
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/135de05d/solr/solrj/src/java/org/apache/solr/client/solrj/SolrClient.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/SolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/SolrClient.java
index 4b555e1..0bee577 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/SolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/SolrClient.java
@@ -33,10 +33,12 @@ import org.apache.solr.common.params.CommonParams;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.NamedList;
+import org.conscrypt.OpenSSLProvider;
 
 import java.io.Closeable;
 import java.io.IOException;
 import java.io.Serializable;
+import java.security.Security;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -51,6 +53,12 @@ import java.util.List;
 public abstract class SolrClient implements Serializable, Closeable {
 
   private static final long serialVersionUID = 1L;
+  static {
+    // Set Conscrypt as default OpenSSLProvider for all clients
+    if (Security.getProvider("Conscrypt") == null) {
+      Security.insertProviderAt(new OpenSSLProvider(), 1);
+    }
+  }
 
   private DocumentObjectBinder binder;
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/135de05d/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java
index 23805bb..405a7b8 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java
@@ -163,25 +163,25 @@ public class Http2SolrClient extends SolrClient {
     QueuedThreadPool httpClientExecutor = new QueuedThreadPool(100, 4);
     httpClientExecutor.setDaemon(true);
 
+    SslContextFactory sslContextFactory;
+    if (builder.sslConfig == null) {
+      sslContextFactory = getDefaultSslContextFactory();
+    } else {
+      sslContextFactory = builder.sslConfig.createContextFactory();
+    }
+
     HttpClientTransport transport;
-    if (useHttp1(builder)) {
-      LOG.info("Create Http2SolrClient with HTTP/1.1 transport");
+    if (builder.useHttp1_1) {
+      LOG.debug("Create Http2SolrClient with HTTP/1.1 transport");
       transport = new HttpClientTransportOverHTTP(2);
-
-      SslContextFactory sslContextFactory;
-      if (builder.sslConfig == null) {
-        sslContextFactory = getDefaultSslContextFactory();
-      } else {
-        sslContextFactory = builder.sslConfig.createContextFactory();
-      }
       httpClient = new HttpClient(transport, sslContextFactory);
     } else {
-      LOG.info("Create Http2SolrClient with HTTP/2 transport");
-      //TODO adding https support for HTTP2 when use JDK 9
+      LOG.debug("Create Http2SolrClient with HTTP/2 transport");
       HTTP2Client http2client = new HTTP2Client();
       transport = new HttpClientTransportOverHTTP2(http2client);
-      httpClient = new HttpClient(transport, null);
+      httpClient = new HttpClient(transport, sslContextFactory);
     }
+
     httpClient.setExecutor(httpClientExecutor);
     httpClient.setStrictEventOrdering(false);
     httpClient.setConnectBlocking(true);
@@ -195,19 +195,6 @@ public class Http2SolrClient extends SolrClient {
     return httpClient;
   }
 
-  private boolean useHttp1(Builder builder) {
-    if (serverBaseUrl != null && serverBaseUrl.startsWith("https"))
-      return true;
-
-    if (builder.useHttp1_1 || builder.sslConfig != null)
-      return true;
-
-    if (System.getProperty("javax.net.ssl.trustStore") != null)
-      return true;
-
-    return false;
-  }
-
   public void close() {
     // we wait for async requests, so far devs don't want to give sugar for this
     asyncTracker.waitForComplete();

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/135de05d/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
index 71daf96..9a6bb27 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
@@ -42,6 +42,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.security.SecureRandom;
+import java.security.Security;
 import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -137,6 +138,7 @@ import org.apache.solr.util.StartupLoggingUtils;
 import org.apache.solr.util.TestHarness;
 import org.apache.solr.util.TestInjection;
 import org.apache.zookeeper.KeeperException;
+import org.conscrypt.OpenSSLProvider;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -282,7 +284,9 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
     startTrackingSearchers();
     ignoreException("ignore_exception");
     newRandomConfig();
-    
+
+    Security.insertProviderAt(new OpenSSLProvider(), 1);
+
     sslConfig = buildSSLConfig();
     // based on randomized SSL config, set SchemaRegistryProvider appropriately
     HttpClientUtil.setSchemaRegistryProvider(sslConfig.buildClientSchemaRegistryProvider());