| = Enabling SSL |
| // 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. |
| |
| Solr can encrypt communications to and from clients, and between nodes in SolrCloud mode, with SSL. |
| |
| This section describes enabling SSL using a self-signed certificate. |
| |
| For background on SSL certificates and keys, see http://www.tldp.org/HOWTO/SSL-Certificates-HOWTO/. |
| |
| == Basic SSL Setup |
| |
| === Generate a Self-Signed Certificate and a Key |
| |
| To generate a self-signed certificate and a single key that will be used to authenticate both the server and the client, we'll use the JDK https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html[`keytool`] command and create a separate keystore. This keystore will also be used as a truststore below. It's possible to use the keystore that comes with the JDK for these purposes, and to use a separate truststore, but those options aren't covered here. |
| |
| Run the commands below in the `server/etc/` directory in the binary Solr distribution. It's assumed that you have the JDK `keytool` utility on your `PATH`, and that `openssl` is also on your `PATH`. See https://www.openssl.org/related/binaries.html for OpenSSL binaries for Windows and Solaris. |
| |
| The `-ext SAN=...` `keytool` option allows you to specify all the DNS names and/or IP addresses that will be allowed during hostname verification (but see below for how to skip hostname verification between Solr nodes so that you don't have to specify all hosts here). |
| |
| In addition to `localhost` and `127.0.0.1`, this example includes a LAN IP address `192.168.1.3` for the machine the Solr nodes will be running on: |
| |
| [source,bash] |
| ---- |
| keytool -genkeypair -alias solr-ssl -keyalg RSA -keysize 2048 -keypass secret -storepass secret -validity 9999 -keystore solr-ssl.keystore.p12 -storetype PKCS12 -ext SAN=DNS:localhost,IP:192.168.1.3,IP:127.0.0.1 -dname "CN=localhost, OU=Organizational Unit, O=Organization, L=Location, ST=State, C=Country" |
| ---- |
| |
| The above command will create a keystore file named `solr-ssl.keystore.p12` in the current directory. |
| |
| === Convert the Certificate and Key to PEM Format for Use with curl |
| |
| Convert the PKCS12 format keystore, including both the certificate and the key, into PEM format using the http://www.openssl.org[`openssl`] command: |
| |
| [source,bash] |
| ---- |
| openssl pkcs12 -in solr-ssl.keystore.p12 -out solr-ssl.pem |
| ---- |
| |
| If you want to use curl on OS X Yosemite (10.10), you'll need to create a certificate-only version of the PEM format, as follows: |
| |
| [source,bash] |
| ---- |
| openssl pkcs12 -nokeys -in solr-ssl.keystore.p12 -out solr-ssl.cacert.pem |
| ---- |
| |
| === Set Common SSL-Related System Properties |
| |
| The Solr Control Script is already setup to pass SSL-related Java system properties to the JVM. To activate the SSL settings, uncomment and update the set of properties beginning with SOLR_SSL_* in `bin/solr.in.sh`. (or `bin\solr.in.cmd` on Windows). |
| |
| NOTE: If you setup Solr as a service on Linux using the steps outlined in <<taking-solr-to-production.adoc#taking-solr-to-production,Taking Solr to Production>>, then make these changes in `/var/solr/solr.in.sh` instead. |
| |
| .bin/solr.in.sh example SOLR_SSL_* configuration |
| [source,bash] |
| ---- |
| # Enables HTTPS. It is implicitly 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=etc/solr-ssl.keystore.p12 |
| SOLR_SSL_KEY_STORE_PASSWORD=secret |
| SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.p12 |
| SOLR_SSL_TRUST_STORE_PASSWORD=secret |
| # Require clients to authenticate |
| SOLR_SSL_NEED_CLIENT_AUTH=false |
| # Enable clients to authenticate (but not require) |
| SOLR_SSL_WANT_CLIENT_AUTH=false |
| # SSL Certificates contain host/ip "peer name" information that is validated by default. Setting |
| # this to false can be useful to disable these checks when re-using a certificate on many hosts |
| SOLR_SSL_CHECK_PEER_NAME=true |
| ---- |
| |
| When you start Solr, the `bin/solr` script includes the settings in `bin/solr.in.sh` and will pass these SSL-related system properties to the JVM. |
| |
| .Client Authentication Settings |
| WARNING: Enable either SOLR_SSL_NEED_CLIENT_AUTH or SOLR_SSL_WANT_CLIENT_AUTH but not both at the same time. They are mutually exclusive and Jetty will select one of them which may not be what you expect. SOLR_SSL_CLIENT_HOSTNAME_VERIFICATION should be set to false if you want to disable hostname verification. |
| |
| Similarly, when you start Solr on Windows, the `bin\solr.cmd` script includes the settings in `bin\solr.in.cmd` - uncomment and update the set of properties beginning with `SOLR_SSL_*` to pass these SSL-related system properties to the JVM: |
| |
| .bin\solr.in.cmd example SOLR_SSL_* configuration |
| [source,text] |
| ---- |
| REM Enables HTTPS. It is implicitly true if you set SOLR_SSL_KEY_STORE. Use this config |
| REM to enable https module with custom jetty configuration. |
| 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 |
| set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.p12 |
| set SOLR_SSL_KEY_STORE_PASSWORD=secret |
| set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.p12 |
| set SOLR_SSL_TRUST_STORE_PASSWORD=secret |
| REM Require clients to authenticate |
| set SOLR_SSL_NEED_CLIENT_AUTH=false |
| REM Enable clients to authenticate (but not require) |
| set SOLR_SSL_WANT_CLIENT_AUTH=false |
| REM SSL Certificates contain host/ip "peer name" information that is validated by default. Setting |
| REM this to false can be useful to disable these checks when re-using a certificate on many hosts |
| set SOLR_SSL_CHECK_PEER_NAME=true |
| ---- |
| |
| === Run Single Node Solr using SSL |
| |
| Start Solr using the command shown below; by default clients will not be required to authenticate: |
| |
| [.dynamic-tabs] |
| -- |
| [example.tab-pane#single-unix] |
| ==== |
| [.tab-label]**nix Command* |
| [source,bash] |
| ---- |
| bin/solr -p 8984 |
| ---- |
| ==== |
| |
| [example.tab-pane#single-windows] |
| ==== |
| [.tab-label]*Windows Command* |
| [source,text] |
| ---- |
| bin\solr.cmd -p 8984 |
| ---- |
| ==== |
| -- |
| |
| == Password Distribution via Hadoop Credential Store |
| |
| Solr supports reading keystore and truststore passwords from Hadoop credential store. This approach can be beneficial |
| if password rotation and distribution is already handled by credential stores. |
| |
| Hadoop credential store can be used with Solr using the following two steps. |
| |
| === Provide a Hadoop Credential Store |
| Create a Hadoop credstore file and define the entries below with the actual keystore passwords. |
| |
| [source,text] |
| ---- |
| solr.jetty.keystore.password |
| solr.jetty.truststore.password |
| javax.net.ssl.keyStorePassword |
| javax.net.ssl.trustStorePassword |
| ---- |
| |
| Note that if the `javax.net.ssl.\*` configurations are not set, they will fallback to the corresponding `solr.jetty.*` configurations. |
| |
| === Configure Solr to use Hadoop Credential Store |
| |
| Solr requires three parameters to be configured in order to use the credential store file for keystore passwords. |
| |
| `solr.ssl.credential.provider.chain`:: |
| The credential provider chain. This should be set to `hadoop`. |
| |
| `SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH`:: |
| The path to the credential store file. |
| |
| `HADOOP_CREDSTORE_PASSWORD`:: |
| The password to the credential store. |
| |
| [.dynamic-tabs] |
| -- |
| [example.tab-pane#credstore-unix] |
| ==== |
| [.tab-label]**nix Example* |
| [source,text] |
| ---- |
| SOLR_OPTS=" -Dsolr.ssl.credential.provider.chain=hadoop" |
| SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH=localjceks://file/home/solr/hadoop-credential-provider.jceks |
| HADOOP_CREDSTORE_PASSWORD="credStorePass123" |
| ---- |
| ==== |
| |
| [example.tab-pane#credstore-windows] |
| ===== |
| [.tab-label]*Windows Example* |
| [source,text] |
| ---- |
| set SOLR_OPTS=" -Dsolr.ssl.credential.provider.chain=hadoop" |
| set SOLR_HADOOP_CREDENTIAL_PROVIDER_PATH=localjceks://file/home/solr/hadoop-credential-provider.jceks |
| set HADOOP_CREDSTORE_PASSWORD="credStorePass123" |
| ---- |
| ===== |
| -- |
| |
| |
| == SSL with SolrCloud |
| |
| This section describes how to run a two-node SolrCloud cluster with no initial collections and a single-node external ZooKeeper. The commands below assume you have already created the keystore described above. |
| |
| === Configure ZooKeeper |
| |
| NOTE: ZooKeeper does not support encrypted communication with clients like Solr. There are several related JIRA tickets where SSL support is being planned/worked on: https://issues.apache.org/jira/browse/ZOOKEEPER-235[ZOOKEEPER-235]; https://issues.apache.org/jira/browse/ZOOKEEPER-236[ZOOKEEPER-236]; https://issues.apache.org/jira/browse/ZOOKEEPER-1000[ZOOKEEPER-1000]; and https://issues.apache.org/jira/browse/ZOOKEEPER-2120[ZOOKEEPER-2120]. |
| |
| Before you start any SolrCloud nodes, you must configure your Solr cluster properties in ZooKeeper, so that Solr nodes know to communicate via SSL. |
| |
| This section assumes you have created and started a single-node external ZooKeeper on port 2181 on localhost - see <<setting-up-an-external-zookeeper-ensemble.adoc#setting-up-an-external-zookeeper-ensemble,Setting Up an External ZooKeeper Ensemble>>. |
| |
| The `urlScheme` cluster-wide property needs to be set to `https` before any Solr node starts up. The example below uses the `zkcli` tool that comes with the binary Solr distribution to do this: |
| |
| .*nix command |
| [source,bash] |
| ---- |
| server/scripts/cloud-scripts/zkcli.sh -zkhost localhost:2181 -cmd clusterprop -name urlScheme -val https |
| ---- |
| |
| .Windows command |
| [source,text] |
| ---- |
| server\scripts\cloud-scripts\zkcli.bat -zkhost localhost:2181 -cmd clusterprop -name urlScheme -val https |
| ---- |
| |
| If you have set up your ZooKeeper cluster to use a <<taking-solr-to-production.adoc#zookeeper-chroot,chroot for Solr>>, make sure you use the correct `zkhost` string with `zkcli`, e.g., `-zkhost localhost:2181/solr`. |
| |
| === Run SolrCloud with SSL |
| |
| NOTE: If you have defined `ZK_HOST` in `solr.in.sh`/`solr.in.cmd` (see <<setting-up-an-external-zookeeper-ensemble#updating-solr-include-files,instructions>>) you can omit `-z <zk host string>` from all of the `bin/solr`/`bin\solr.cmd` commands below. |
| |
| ==== Create Solr Home Directories for Two Nodes |
| |
| Create two copies of the `server/solr/` directory which will serve as the Solr home directories for each of your two SolrCloud nodes: |
| |
| .*nix commands |
| [source,bash] |
| ---- |
| mkdir cloud |
| cp -r server/solr cloud/node1 |
| cp -r server/solr cloud/node2 |
| ---- |
| |
| .Windows commands |
| [source,text] |
| ---- |
| mkdir cloud |
| xcopy /E server\solr cloud\node1\ |
| xcopy /E server\solr cloud\node2\ |
| ---- |
| |
| ==== Start the First Solr Node |
| |
| Next, start the first Solr node on port 8984. Be sure to stop the standalone server first if you started it when working through the previous section on this page. |
| |
| .*nix command |
| [source,bash] |
| ---- |
| bin/solr -cloud -s cloud/node1 -z localhost:2181 -p 8984 |
| ---- |
| |
| .Windows command |
| [source,text] |
| ---- |
| bin\solr.cmd -cloud -s cloud\node1 -z localhost:2181 -p 8984 |
| ---- |
| |
| Notice the use of the `-s` option to set the location of the Solr home directory for node1. |
| |
| If you created your SSL key without all DNS names/IP addresses on which Solr nodes will run, you can tell Solr to skip hostname verification for inter-Solr-node communications by setting the `solr.ssl.checkPeerName` system property to `false`: |
| |
| .*nix command |
| [source,bash] |
| ---- |
| bin/solr -cloud -s cloud/node1 -z localhost:2181 -p 8984 -Dsolr.ssl.checkPeerName=false |
| ---- |
| |
| .Windows command |
| [source,text] |
| ---- |
| bin\solr.cmd -cloud -s cloud\node1 -z localhost:2181 -p 8984 -Dsolr.ssl.checkPeerName=false |
| ---- |
| |
| ==== Start the Second Solr Node |
| |
| Finally, start the second Solr node on port 7574 - again, to skip hostname verification, add `-Dsolr.ssl.checkPeerName=false`; |
| |
| .*nix command |
| [source,text] |
| ---- |
| bin/solr -cloud -s cloud/node2 -z localhost:2181 -p 7574 |
| ---- |
| |
| .Windows command |
| [source,text] |
| ---- |
| bin\solr.cmd -cloud -s cloud\node2 -z localhost:2181 -p 7574 |
| ---- |
| |
| == Example Client Actions |
| |
| [IMPORTANT] |
| ==== |
| curl on OS X Mavericks (10.9) has degraded SSL support. For more information and workarounds to allow one-way SSL, see http://curl.haxx.se/mail/archive-2013-10/0036.html. curl on OS X Yosemite (10.10) is improved - 2-way SSL is possible - see http://curl.haxx.se/mail/archive-2014-10/0053.html. |
| |
| The curl commands in the following sections will not work with the system `curl` on OS X Yosemite (10.10). Instead, the certificate supplied with the `-E` parameter must be in PKCS12 format, and the file supplied with the `--cacert` parameter must contain only the CA certificate, and no key (see <<Convert the Certificate and Key to PEM Format for Use with curl,above>> for instructions on creating this file): |
| |
| [source,bash] |
| curl -E solr-ssl.keystore.p12:secret --cacert solr-ssl.cacert.pem ... |
| |
| ==== |
| |
| NOTE: If your operating system does not include curl, you can download binaries here: http://curl.haxx.se/download.html |
| |
| === Create a SolrCloud Collection using bin/solr |
| |
| Create a 2-shard, replicationFactor=1 collection named mycollection using the `_default` configset: |
| |
| .*nix command |
| [source,bash] |
| ---- |
| bin/solr create -c mycollection -shards 2 |
| ---- |
| |
| .Windows command |
| [source,text] |
| ---- |
| bin\solr.cmd create -c mycollection -shards 2 |
| ---- |
| |
| The `create` action will pass the `SOLR_SSL_*` properties set in your include file to the SolrJ code used to create the collection. |
| |
| === Retrieve SolrCloud Cluster Status using curl |
| |
| To get the resulting cluster status (again, if you have not enabled client authentication, remove the `-E solr-ssl.pem:secret` option): |
| |
| [source,bash] |
| ---- |
| curl -E solr-ssl.pem:secret --cacert solr-ssl.pem "https://localhost:8984/solr/admin/collections?action=CLUSTERSTATUS&indent=on" |
| ---- |
| |
| You should get a response that looks like this: |
| |
| [source,json] |
| ---- |
| { |
| "responseHeader":{ |
| "status":0, |
| "QTime":2041}, |
| "cluster":{ |
| "collections":{ |
| "mycollection":{ |
| "shards":{ |
| "shard1":{ |
| "range":"80000000-ffffffff", |
| "state":"active", |
| "replicas":{"core_node1":{ |
| "state":"active", |
| "base_url":"https://127.0.0.1:8984/solr", |
| "core":"mycollection_shard1_replica1", |
| "node_name":"127.0.0.1:8984_solr", |
| "leader":"true"}}}, |
| "shard2":{ |
| "range":"0-7fffffff", |
| "state":"active", |
| "replicas":{"core_node2":{ |
| "state":"active", |
| "base_url":"https://127.0.0.1:7574/solr", |
| "core":"mycollection_shard2_replica1", |
| "node_name":"127.0.0.1:7574_solr", |
| "leader":"true"}}}}, |
| "maxShardsPerNode":"1", |
| "router":{"name":"compositeId"}, |
| "replicationFactor":"1"}}, |
| "properties":{"urlScheme":"https"}}} |
| ---- |
| |
| === Index Documents using post.jar |
| |
| Use `post.jar` to index some example documents to the SolrCloud collection created above: |
| |
| [source,bash] |
| ---- |
| cd example/exampledocs |
| |
| java -Djavax.net.ssl.keyStorePassword=secret -Djavax.net.ssl.keyStore=../../server/etc/solr-ssl.keystore.p12 -Djavax.net.ssl.trustStore=../../server/etc/solr-ssl.keystore.p12 -Djavax.net.ssl.trustStorePassword=secret -Durl=https://localhost:8984/solr/mycollection/update -jar post.jar *.xml |
| ---- |
| |
| === Query Using curl |
| |
| Use curl to query the SolrCloud collection created above, from a directory containing the PEM formatted certificate and key created above (e.g., `example/etc/`) - if you have not enabled client authentication (system property `-Djetty.ssl.clientAuth=true)`, then you can remove the `-E solr-ssl.pem:secret` option: |
| |
| [source,bash] |
| ---- |
| curl -E solr-ssl.pem:secret --cacert solr-ssl.pem "https://localhost:8984/solr/mycollection/select?q=*:*" |
| ---- |
| |
| === Index a Document using CloudSolrClient |
| |
| From a java client using SolrJ, index a document. In the code below, the `javax.net.ssl.*` system properties are set programmatically, but you could instead specify them on the java command line, as in the `post.jar` example above: |
| |
| [source,java] |
| ---- |
| System.setProperty("javax.net.ssl.keyStore", "/path/to/solr-ssl.keystore.p12"); |
| System.setProperty("javax.net.ssl.keyStorePassword", "secret"); |
| System.setProperty("javax.net.ssl.trustStore", "/path/to/solr-ssl.keystore.p12"); |
| System.setProperty("javax.net.ssl.trustStorePassword", "secret"); |
| String zkHost = "127.0.0.1:2181"; |
| CloudSolrClient client = new CloudSolrClient.Builder().withZkHost(zkHost).build(); |
| client.setDefaultCollection("mycollection"); |
| SolrInputDocument doc = new SolrInputDocument(); |
| doc.addField("id", "1234"); |
| doc.addField("name", "A lovely summer holiday"); |
| client.add(doc); |
| client.commit(); |
| ---- |