Enabling SSL
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 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:
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 openssl
command:
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:
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).
If you setup Solr as a service on Linux using the steps outlined in Taking Solr to Production, then make these changes in /var/solr/solr.in.sh instead.
|
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
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:
Run Single Node Solr using SSL
Start Solr using the command shown below; by default clients will not be required to authenticate:
*nix Command
bin/solr -p 8984
Windows Command
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.
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.
*nix Example
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"
Windows Example
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
ZooKeeper does not support encrypted communication with clients like Solr. There are several related JIRA tickets where SSL support is being planned/worked on: ZOOKEEPER-235; ZOOKEEPER-236; ZOOKEEPER-1000; and 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.
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:
If you have set up your ZooKeeper cluster to use a chroot for Solr, make sure you use the correct zkhost
string with zkcli
, e.g., -zkhost localhost:2181/solr
.
Run SolrCloud with SSL
If you have defined ZK_HOST in solr.in.sh /solr.in.cmd (see 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:
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.
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
:
Start the Second Solr Node
Finally, start the second Solr node on port 7574 - again, to skip hostname verification, add -Dsolr.ssl.checkPeerName=false
;
Example Client Actions
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
|
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:
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):
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:
{
"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:
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:
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:
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();