You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ma...@apache.org on 2017/05/16 17:41:32 UTC

lucene-solr:branch_6x: SOLR-10307: Allow Passing SSL passwords through environment variables.

Repository: lucene-solr
Updated Branches:
  refs/heads/branch_6x 02490e309 -> 3ac88d657


SOLR-10307: Allow Passing SSL passwords through environment variables.


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

Branch: refs/heads/branch_6x
Commit: 3ac88d65768fa5d3780caa12bcba8c83fef623ac
Parents: 02490e3
Author: Mark Miller <ma...@apache.org>
Authored: Tue May 16 13:59:29 2017 -0300
Committer: Mark Miller <ma...@apache.org>
Committed: Tue May 16 14:19:58 2017 -0300

----------------------------------------------------------------------
 solr/CHANGES.txt                                |   5 +
 solr/bin/solr                                   |  34 ++----
 solr/bin/solr.cmd                               |  34 ++----
 solr/bin/solr.in.cmd                            |   3 +
 solr/bin/solr.in.sh                             |   3 +
 .../apache/solr/servlet/SolrDispatchFilter.java |   2 +
 .../src/java/org/apache/solr/util/SolrCLI.java  |   7 ++
 .../util/configuration/SSLConfigurations.java   |  78 ++++++++++++
 .../configuration/SSLConfigurationsFactory.java |  49 ++++++++
 .../solr/util/configuration/package-info.java   |  23 ++++
 .../configuration/SSLConfigurationsTest.java    | 121 +++++++++++++++++++
 solr/server/etc/jetty-ssl.xml                   |   4 +-
 12 files changed, 318 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3ac88d65/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 918e927..65d9ce8 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -32,6 +32,11 @@ Jetty 9.3.14.v20161028
 Detailed Change List
 ----------------------
 
+New Features
+----------------------
+
+* SOLR-10307: Allow Passing SSL passwords through environment variables. (Mano Kovacs via Mark Miller)
+
 Other Changes
 ----------------------
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3ac88d65/solr/bin/solr
----------------------------------------------------------------------
diff --git a/solr/bin/solr b/solr/bin/solr
index 61c161e..ad3df46 100755
--- a/solr/bin/solr
+++ b/solr/bin/solr
@@ -163,13 +163,20 @@ fi
 SOLR_URL_SCHEME=http
 SOLR_JETTY_CONFIG=()
 SOLR_SSL_OPTS=""
-if [ -n "$SOLR_SSL_KEY_STORE" ]; then
+if [ -z "$SOLR_SSL_ENABLED" ]; then
+  if [ -n "$SOLR_SSL_KEY_STORE" ]; then
+    SOLR_SSL_ENABLED="true" # implicitly from earlier behaviour
+  else
+    SOLR_SSL_ENABLED="false"
+  fi
+fi
+if [ "$SOLR_SSL_ENABLED" == "true" ]; then
   SOLR_JETTY_CONFIG+=("--module=https")
   SOLR_URL_SCHEME=https
-  SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore=$SOLR_SSL_KEY_STORE"
-  if [ -n "$SOLR_SSL_KEY_STORE_PASSWORD" ]; then
-    SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore.password=$SOLR_SSL_KEY_STORE_PASSWORD"
+  if [ -n "$SOLR_SSL_KEY_STORE" ]; then
+    SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore=$SOLR_SSL_KEY_STORE"
   fi
+
   if [ -n "$SOLR_SSL_KEY_STORE_TYPE" ]; then
     SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore.type=$SOLR_SSL_KEY_STORE_TYPE"
   fi
@@ -177,9 +184,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
   if [ -n "$SOLR_SSL_TRUST_STORE" ]; then
     SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore=$SOLR_SSL_TRUST_STORE"
   fi
-  if [ -n "$SOLR_SSL_TRUST_STORE_PASSWORD" ]; then
-    SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore.password=$SOLR_SSL_TRUST_STORE_PASSWORD"
-  fi
   if [ -n "$SOLR_SSL_TRUST_STORE_TYPE" ]; then
     SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore.type=$SOLR_SSL_TRUST_STORE_TYPE"
   fi
@@ -194,9 +198,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
   if [ -n "$SOLR_SSL_CLIENT_KEY_STORE" ]; then
     SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStore=$SOLR_SSL_CLIENT_KEY_STORE"
 
-    if [ -n "$SOLR_SSL_CLIENT_KEY_STORE_PASSWORD" ]; then
-      SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStorePassword=$SOLR_SSL_CLIENT_KEY_STORE_PASSWORD"
-    fi
     if [ -n "$SOLR_SSL_CLIENT_KEY_STORE_TYPE" ]; then
       SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStoreType=$SOLR_SSL_CLIENT_KEY_STORE_TYPE"
     fi
@@ -204,9 +205,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
     if [ -n "$SOLR_SSL_KEY_STORE" ]; then
       SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStore=$SOLR_SSL_KEY_STORE"
     fi
-    if [ -n "$SOLR_SSL_KEY_STORE_PASSWORD" ]; then
-      SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStorePassword=$SOLR_SSL_KEY_STORE_PASSWORD"
-    fi
     if [ -n "$SOLR_SSL_KEY_STORE_TYPE" ]; then
       SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStoreType=$SOLR_SSL_KEYSTORE_TYPE"
     fi
@@ -215,10 +213,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
   if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE" ]; then
     SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStore=$SOLR_SSL_CLIENT_TRUST_STORE"
 
-    if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD" ]; then
-      SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStorePassword=$SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD"
-    fi
-
     if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE_TYPE" ]; then
       SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStoreType=$SOLR_SSL_CLIENT_TRUST_STORE_TYPE"
     fi
@@ -227,10 +221,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then
       SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStore=$SOLR_SSL_TRUST_STORE"
     fi
 
-    if [ -n "$SOLR_SSL_TRUST_STORE_PASSWORD" ]; then
-      SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStorePassword=$SOLR_SSL_TRUST_STORE_PASSWORD"
-    fi
-
     if [ -n "$SOLR_SSL_TRUST_STORE_TYPE" ]; then
       SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStoreType=$SOLR_SSL_TRUST_STORE_TYPE"
     fi
@@ -1832,7 +1822,7 @@ function launch_solr() {
 
 
   # If SSL-related system props are set, add them to SOLR_OPTS
-  if [ -n "$SOLR_SSL_OPTS" ]; then
+  if [ "$SOLR_SSL_ENABLED" ]; then
     # If using SSL and solr.jetty.https.port not set explicitly, use the jetty.port
     SSL_PORT_PROP="-Dsolr.jetty.https.port=$SOLR_PORT"
     SOLR_OPTS+=($SOLR_SSL_OPTS "$SSL_PORT_PROP")

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3ac88d65/solr/bin/solr.cmd
----------------------------------------------------------------------
diff --git a/solr/bin/solr.cmd b/solr/bin/solr.cmd
index 727350b..9bb88f0 100644
--- a/solr/bin/solr.cmd
+++ b/solr/bin/solr.cmd
@@ -42,13 +42,21 @@ REM Select HTTP OR HTTPS related configurations
 set SOLR_URL_SCHEME=http
 set "SOLR_JETTY_CONFIG=--module=http"
 set "SOLR_SSL_OPTS= "
-IF DEFINED SOLR_SSL_KEY_STORE (
+
+IF NOT DEFINED SOLR_SSL_ENABLED (
+  IF DEFINED SOLR_SSL_KEY_STORE (
+    set "SOLR_SSL_ENABLED=true"
+  ) ELSE (
+    set "SOLR_SSL_ENABLED=false"
+  )
+)
+IF "%SOLR_SSL_ENABLED%"=="true" (
   set "SOLR_JETTY_CONFIG=--module=https"
   set SOLR_URL_SCHEME=https
-  set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore=%SOLR_SSL_KEY_STORE%"
-  IF DEFINED SOLR_SSL_KEY_STORE_PASSWORD (
-    set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore.password=%SOLR_SSL_KEY_STORE_PASSWORD%"
+  IF DEFINED SOLR_SSL_KEY_STORE (
+    set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore=%SOLR_SSL_KEY_STORE%"
   )
+
   IF DEFINED SOLR_SSL_KEY_STORE_TYPE (
     set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore.type=%SOLR_SSL_KEY_STORE_TYPE%"
   )
@@ -56,9 +64,6 @@ IF DEFINED SOLR_SSL_KEY_STORE (
   IF DEFINED SOLR_SSL_TRUST_STORE (
     set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore=%SOLR_SSL_TRUST_STORE%"
   )
-  IF DEFINED SOLR_SSL_TRUST_STORE_PASSWORD (
-    set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore.password=%SOLR_SSL_TRUST_STORE_PASSWORD%"
-  )
   IF DEFINED SOLR_SSL_TRUST_STORE_TYPE (
     set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore.type=%SOLR_SSL_TRUST_STORE_TYPE%"
   )
@@ -73,9 +78,6 @@ IF DEFINED SOLR_SSL_KEY_STORE (
   IF DEFINED SOLR_SSL_CLIENT_KEY_STORE (
     set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStore=%SOLR_SSL_CLIENT_KEY_STORE%"
 
-    IF DEFINED SOLR_SSL_CLIENT_KEY_STORE_PASSWORD (
-      set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStorePassword=%SOLR_SSL_CLIENT_KEY_STORE_PASSWORD%"
-    )
     IF DEFINED SOLR_SSL_CLIENT_KEY_STORE_TYPE (
       set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStoreType=%SOLR_SSL_CLIENT_KEY_STORE_TYPE%"
     )
@@ -83,9 +85,6 @@ IF DEFINED SOLR_SSL_KEY_STORE (
     IF DEFINED SOLR_SSL_KEY_STORE (
       set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStore=%SOLR_SSL_KEY_STORE%"
     )
-    IF DEFINED SOLR_SSL_KEY_STORE_PASSWORD (
-      set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStorePassword=%SOLR_SSL_KEY_STORE_PASSWORD%"
-    )
     IF DEFINED SOLR_SSL_KEY_STORE_TYPE (
       set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStoreType=%SOLR_SSL_KEY_STORE_TYPE%"
     )
@@ -94,10 +93,6 @@ IF DEFINED SOLR_SSL_KEY_STORE (
   IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE (
     set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStore=%SOLR_SSL_CLIENT_TRUST_STORE%"
 
-    IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD (
-      set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStorePassword=%SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD%"
-    )
-
     IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE_TYPE (
       set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStoreType=%SOLR_SSL_CLIENT_TRUST_STORE_TYPE%"
     )
@@ -105,9 +100,6 @@ IF DEFINED SOLR_SSL_KEY_STORE (
     IF DEFINED SOLR_SSL_TRUST_STORE (
      set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStore=%SOLR_SSL_TRUST_STORE%"
     )
-    IF DEFINED SOLR_SSL_TRUST_STORE_PASSWORD (
-     set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStorePassword=%SOLR_SSL_TRUST_STORE_PASSWORD%"
-    )
     IF DEFINED SOLR_SSL_TRUST_STORE_TYPE (
      set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStoreType=%SOLR_SSL_TRUST_STORE_TYPE%"
     )
@@ -1135,7 +1127,7 @@ IF NOT "%REMOTE_JMX_OPTS%"=="" set "START_OPTS=%START_OPTS% %REMOTE_JMX_OPTS%"
 IF NOT "%SOLR_ADDL_ARGS%"=="" set "START_OPTS=%START_OPTS% %SOLR_ADDL_ARGS%"
 IF NOT "%SOLR_HOST_ARG%"=="" set "START_OPTS=%START_OPTS% %SOLR_HOST_ARG%"
 IF NOT "%SOLR_OPTS%"=="" set "START_OPTS=%START_OPTS% %SOLR_OPTS%"
-IF NOT "%SOLR_SSL_OPTS%"=="" (
+IF "%SOLR_SSL_ENABLED%"=="true" (
   set "SSL_PORT_PROP=-Dsolr.jetty.https.port=%SOLR_PORT%"
   set "START_OPTS=%START_OPTS% %SOLR_SSL_OPTS% !SSL_PORT_PROP!"
 )

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3ac88d65/solr/bin/solr.in.cmd
----------------------------------------------------------------------
diff --git a/solr/bin/solr.in.cmd b/solr/bin/solr.in.cmd
index 59dee18..4b56dd5 100644
--- a/solr/bin/solr.in.cmd
+++ b/solr/bin/solr.in.cmd
@@ -87,6 +87,9 @@ REM set SOLR_JETTY_HOST=0.0.0.0
 REM Sets the port Solr binds to, default is 8983
 REM set SOLR_PORT=8983
 
+REM Enables HTTPS. It is implictly true if you set SOLR_SSL_KEY_STORE. Use this config
+REM to enable https module with custom jetty configuration.
+REM set SOLR_SSL_ENABLED=true
 REM Uncomment to set SSL-related system properties
 REM Be sure to update the paths to the correct keystore for your environment
 REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3ac88d65/solr/bin/solr.in.sh
----------------------------------------------------------------------
diff --git a/solr/bin/solr.in.sh b/solr/bin/solr.in.sh
index 620cf3f..f5d57e3 100644
--- a/solr/bin/solr.in.sh
+++ b/solr/bin/solr.in.sh
@@ -106,6 +106,9 @@
 # Sets the port Solr binds to, default is 8983
 #SOLR_PORT=8983
 
+# Enables HTTPS. It is implictly true if you set SOLR_SSL_KEY_STORE. Use this config
+# to enable https module with custom jetty configuration.
+#SOLR_SSL_ENABLED=true
 # Uncomment to set SSL-related system properties
 # Be sure to update the paths to the correct keystore for your environment
 #SOLR_SSL_KEY_STORE=/home/shalin/work/oss/shalin-lusolr/solr/server/etc/solr-ssl.keystore.jks

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3ac88d65/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
index 5950c2e..12e5c7d 100644
--- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
+++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
@@ -71,6 +71,7 @@ import org.apache.solr.request.SolrRequestInfo;
 import org.apache.solr.security.AuthenticationPlugin;
 import org.apache.solr.security.PKIAuthenticationPlugin;
 import org.apache.solr.util.SolrFileCleaningTracker;
+import org.apache.solr.util.configuration.SSLConfigurationsFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -137,6 +138,7 @@ public class SolrDispatchFilter extends BaseSolrFilter {
   @Override
   public void init(FilterConfig config) throws ServletException
   {
+    SSLConfigurationsFactory.current().init();
     log.trace("SolrDispatchFilter.init(): {}", this.getClass().getClassLoader());
     CoreContainer coresInit = null;
     try{

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3ac88d65/solr/core/src/java/org/apache/solr/util/SolrCLI.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/SolrCLI.java b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
index aa7c8b5..5742a6b 100644
--- a/solr/core/src/java/org/apache/solr/util/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
@@ -60,6 +60,8 @@ import java.util.stream.Stream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
+import javax.net.ssl.SSLPeerUnverifiedException;
+
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.GnuParser;
 import org.apache.commons.cli.HelpFormatter;
@@ -113,6 +115,7 @@ import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.ContentStreamBase;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.security.Sha256AuthenticationProvider;
+import org.apache.solr.util.configuration.SSLConfigurationsFactory;
 import org.noggit.CharArr;
 import org.noggit.JSONParser;
 import org.noggit.JSONWriter;
@@ -252,6 +255,8 @@ public class SolrCLI {
       exit(0);
     }
 
+    SSLConfigurationsFactory.current().init();
+
     Tool tool = findTool(args);
     CommandLine cli = parseCmdLine(args, tool.getOptions());
     System.exit(tool.runTool(cli));
@@ -867,6 +872,8 @@ public class SolrCLI {
       while (System.nanoTime() < timeout) {
         try {
           return getStatus(solrUrl);
+        } catch (SSLPeerUnverifiedException exc) {
+            throw exc;
         } catch (Exception exc) {
           if (exceptionIsAuthRelated(exc)) {
             throw exc;

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3ac88d65/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java
new file mode 100644
index 0000000..bfa5186
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+package org.apache.solr.util.configuration;
+
+import java.lang.invoke.MethodHandles;
+import java.util.Map;
+
+import org.apache.solr.common.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Dedicated object to handle Solr configurations
+ */
+public class SSLConfigurations {
+  private final Map<String, String> envVars;
+
+  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+  public static class SysProps {
+    public static final String SSL_KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword";
+    public static final String SSL_TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword";
+  }
+
+  public static class EnvVars {
+    public static final String SOLR_SSL_CLIENT_KEY_STORE_PASSWORD = "SOLR_SSL_CLIENT_KEY_STORE_PASSWORD";
+    public static final String SOLR_SSL_KEY_STORE_PASSWORD = "SOLR_SSL_KEY_STORE_PASSWORD";
+    public static final String SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD = "SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD";
+    public static final String SOLR_SSL_TRUST_STORE_PASSWORD = "SOLR_SSL_TRUST_STORE_PASSWORD";
+  }
+
+  /**
+   * @param envVars Map of environment variables to use
+   */
+  public SSLConfigurations(Map<String, String> envVars) {
+    this.envVars = envVars;
+  }
+
+  /** Initiates javax.net.ssl.* system properties from the proper sources. */
+  public void init() {
+
+    String clientKeystorePassword = envVars.get(EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD);
+    String keystorePassword = envVars.get(EnvVars.SOLR_SSL_KEY_STORE_PASSWORD);
+
+    String clientTruststorePassword = envVars.get(EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD);
+    String truststorePassword = envVars.get(EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD);
+
+    if (isEmpty(System.getProperty(SysProps.SSL_KEY_STORE_PASSWORD))
+        && !(isEmpty(clientKeystorePassword) && isEmpty(keystorePassword))) {
+      log.debug("Setting {} based on env var", SysProps.SSL_KEY_STORE_PASSWORD);
+      System.setProperty(SysProps.SSL_KEY_STORE_PASSWORD, clientKeystorePassword != null ? clientKeystorePassword : keystorePassword);
+    }
+    if (isEmpty(System.getProperty(SysProps.SSL_TRUST_STORE_PASSWORD))
+        && !(isEmpty(clientTruststorePassword) && isEmpty(truststorePassword))) {
+      log.debug("Setting {} based on env var", SysProps.SSL_TRUST_STORE_PASSWORD);
+      System.setProperty(SysProps.SSL_TRUST_STORE_PASSWORD, clientTruststorePassword != null ? clientTruststorePassword : truststorePassword);
+    }
+  }
+
+  private boolean isEmpty(String str) {
+    return StringUtils.isEmpty(str);
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3ac88d65/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java
new file mode 100644
index 0000000..1da7c01
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+package org.apache.solr.util.configuration;
+
+import com.google.common.annotations.VisibleForTesting;
+
+public class SSLConfigurationsFactory {
+  static private SSLConfigurations currentConfigurations;
+
+  /**
+   * Creates if necessary and returns singleton object of Configurations. Can be used for
+   * static accessor of application-wide instance.
+   * @return Configurations object
+   */
+  static public SSLConfigurations current() {
+    if (currentConfigurations == null) {
+      synchronized (SSLConfigurationsFactory.class) {
+        if (currentConfigurations == null) {
+          currentConfigurations = getInstance();
+        }
+      }
+    }
+    return currentConfigurations;
+  }
+
+  private static SSLConfigurations getInstance() {
+    return new SSLConfigurations(System.getenv());
+  }
+
+  @VisibleForTesting
+  static public synchronized void setCurrent(SSLConfigurations configurations) {
+    currentConfigurations = configurations;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3ac88d65/solr/core/src/java/org/apache/solr/util/configuration/package-info.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/util/configuration/package-info.java b/solr/core/src/java/org/apache/solr/util/configuration/package-info.java
new file mode 100644
index 0000000..68b7db3
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/util/configuration/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+ 
+/** 
+ * Common Util APIs related to Solr configuration.
+ */
+package org.apache.solr.util.configuration;
+
+

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3ac88d65/solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java b/solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java
new file mode 100644
index 0000000..a1d4696
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+
+package org.apache.solr.util.configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.lucene.util.TestRuleRestoreSystemProperties;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public class SSLConfigurationsTest {
+  private Map<String, String> envs;
+  private SSLConfigurations sut;
+
+  public static final String SAMPLE_PW1 = "pw123";
+  public static final String SAMPLE_PW2 = "pw456";
+  public static final String SAMPLE_PW3 = "pw789";
+  public static final String KEY_STORE_PASSWORD = SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD;
+  public static final String TRUST_STORE_PASSWORD = SSLConfigurations.SysProps.SSL_TRUST_STORE_PASSWORD;
+
+  @Rule
+  public TestRule syspropRestore = new TestRuleRestoreSystemProperties(
+      SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD,
+      SSLConfigurations.SysProps.SSL_TRUST_STORE_PASSWORD
+  );
+
+  @Before
+  public void setUp() {
+    envs = new HashMap<>();
+  }
+
+  private SSLConfigurations createSut() {
+    sut = new SSLConfigurations(envs);
+    return sut;
+  }
+
+  @Test
+  public void testSslConfigKeystorePwFromKeystoreEnvVar() {
+    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1);
+    createSut().init();
+    assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW1));
+  }
+
+  @Test
+  public void testSslConfigKeystorePwFromClientKeystoreEnvVar() {
+    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
+    createSut().init();
+    assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW2));
+  }
+
+  @Test
+  public void testSslConfigKeystorePwFromBothEnvVars() {
+    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1);
+    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
+    createSut().init();
+    assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW2));
+  }
+
+  @Test
+  public void testSslConfigKeystorePwNotOverwrittenIfExists() {
+    System.setProperty(KEY_STORE_PASSWORD, SAMPLE_PW3);
+    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1);
+    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2);
+    createSut().init();
+    assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW3)); // unchanged
+  }
+
+
+  @Test
+  public void testSslConfigTruststorePwFromKeystoreEnvVar() {
+    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1);
+    createSut().init();
+    assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW1));
+  }
+
+  @Test
+  public void testSslConfigTruststorePwFromClientKeystoreEnvVar() {
+    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
+    createSut().init();
+    assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW2));
+  }
+
+  @Test
+  public void testSslConfigTruststorePwFromBothEnvVars() {
+    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1);
+    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
+    createSut().init();
+    assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW2));
+  }
+
+  @Test
+  public void testSslConfigTruststorePwNotOverwrittenIfExists() {
+    System.setProperty(TRUST_STORE_PASSWORD, SAMPLE_PW3);
+    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1);
+    envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2);
+    createSut().init();
+    assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW3)); // unchanged
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3ac88d65/solr/server/etc/jetty-ssl.xml
----------------------------------------------------------------------
diff --git a/solr/server/etc/jetty-ssl.xml b/solr/server/etc/jetty-ssl.xml
index 4d85de6..741ac48 100644
--- a/solr/server/etc/jetty-ssl.xml
+++ b/solr/server/etc/jetty-ssl.xml
@@ -8,9 +8,9 @@
 <!-- ============================================================= -->
 <Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
   <Set name="KeyStorePath"><Property name="solr.jetty.keystore" default="./etc/solr-ssl.keystore.jks"/></Set>
-  <Set name="KeyStorePassword"><Property name="solr.jetty.keystore.password" default="secret"/></Set>
+  <Set name="KeyStorePassword"><Env name="SOLR_SSL_KEY_STORE_PASSWORD" default="secret"/></Set>
   <Set name="TrustStorePath"><Property name="solr.jetty.truststore" default="./etc/solr-ssl.keystore.jks"/></Set>
-  <Set name="TrustStorePassword"><Property name="solr.jetty.truststore.password" default="secret"/></Set>
+  <Set name="TrustStorePassword"><Env name="SOLR_SSL_TRUST_STORE_PASSWORD" default="secret"/></Set>
   <Set name="NeedClientAuth"><Property name="solr.jetty.ssl.needClientAuth" default="false"/></Set>
   <Set name="WantClientAuth"><Property name="solr.jetty.ssl.wantClientAuth" default="false"/></Set>
   <Set name="KeyStoreType"><Property name="solr.jetty.keystore.type" default="JKS"/></Set>