Skip to content

Conversation

@laminelam
Copy link
Contributor

@laminelam laminelam commented Oct 10, 2023

https://issues.apache.org/jira/browse/SOLR-17020

Description

Solr currently connects to Zookeeper and manages ACLs using a set of credentials (when using Digest scheme). These credentials are either passed via the command line (system properties) or fetched from an unencrypted file on every host in the cluster. Clearly, this approach lacks sufficient security.

The proposed change of this contribution intends to integrate AWS Secret Manager for credential storage, offering two primary advantages:
• Improved security measures.
• Streamlined operations by centralizing credential storage, eliminating the need to update multiple hosts/files whenever passwords are changed.

Solution

This is a new module to support storing Zookeeper credentials in an AWS Secret Manager.

Added a new implementation of ZkCredentialsInjector that pulls the creds from AWS SM.

Ref guide in progress...

Tests

Added test cases.
Integration tests also made in AWS environment.

Checklist

Please review the following and check all that apply:

  • I have reviewed the guidelines for How to Contribute and my code conforms to the standards described there to the best of my ability.
  • I have created a Jira issue and added the issue ID to my pull request title.
  • I have given Solr maintainers access to contribute to my PR branch. (optional but recommended)
  • I have developed this patch against the main branch.
  • I have run ./gradlew check.
  • I have added tests for my changes.
  • I have added documentation for the Reference Guide

@laminelam laminelam changed the title SOLR-15857: Add Secret Manager support for ZK ACL credentials SOLR-15857: Add AWS Secret Manager support for ZK ACL credentials Oct 10, 2023
sort modules in alphabetical order
ZK_CREDENTIALS_INJECTOR_CLASS_NAME_VM_PARAM_NAME,
AllAndReadonlyCredentialZkCredentialsInjector.class.getName());

SolrZkClient zkClient =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why so many ZK clients? Can't the one be used over and over for each create? At least most of the zk clients look to be the same. Also use try-with-resources to avoid the explicit need to close the zk clients

Copy link
Contributor Author

@laminelam laminelam Oct 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @risdenk
This is an existing (copied) code. For some reason (race condition?) you need to close and recreate ZKClient to make the nodes creation successful. You don't want to reuse it in the last block because you want to connect to ZK with 'OPEN_ACL_UNSAFE' ACLs.

Refactored the existing code and added new tests cases to void code duplication. Created a new setUpZKNodes method.

I think AbstractDigestZkACLAndCredentialsProvidersTestBase (which BTW is not abstract) needs more refactoring. Didn't want to make this PR bigger than it already is, but we should consider favoring composition over inheritance here.

@laminelam laminelam requested a review from risdenk October 19, 2023 19:29
Copy link
Contributor

@HoustonPutman HoustonPutman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I think there might be issues with the various cli tools, using the modules provided by SOLR_MODULES.

import software.amazon.awssdk.services.secretsmanager.model.SecretsManagerException;

public class AWSSecretManagerCredentialsInjector implements ZkCredentialsInjector {
public static final String SECRET_CREDENTIAL_PROVIDER_SECRET_NAME_VM_PARAM =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that these names make sense to me. They are not consistent with each other.

  • solr.zk.credentials.secret
  • solrZkCredentials
  • solr.zk.credentials.region

I think these work better.

Copy link
Contributor Author

@laminelam laminelam Nov 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, they are not consistent because they don't have the same functionality. Some are VM variable names (internal to Solr, so I followed the same naming convention of the existing creds/acl providers), one is an AWS variable value.
How about this new version?

 public static final String AWS_SM_CREDENTIALS_SECRET_NAME_VM_PARAM = "zkAWSSecretCredentialsSecretName";
private static final String AWS_SM_CREDENTIALS_REGION_VM_PARAM = "zkAWSSecretCredentialsRegion";
private static final String AWS_SM_CREDENTIALS_SECRET_NAME_DEFAULT = "/solr/zk/credentials/dev/secret";

Followed AWS SM recommended naming convention.

Edit: slashes in variable names can cause problems. I am going with this syntax instead: solr.zk.credentials.dev.secret for secret name


PATH=$JAVA_HOME/bin:$PATH $JVM $SOLR_ZK_CREDS_AND_ACLS $ZKCLI_JVM_FLAGS -Dlog4j.configurationFile=$log4j_config -Dsolr.home=$solr_home \
-classpath "$sdir/../../solr-webapp/webapp/WEB-INF/lib/*:$sdir/../../lib/ext/*:$sdir/../../lib/*" org.apache.solr.cloud.ZkCLI ${1+"$@"}
-Dsolr.install.dir=$SOLR_DIR -Dsolr.modules=$SOLR_MODULES -classpath "$sdir/../../solr-webapp/webapp/WEB-INF/lib/*:$sdir/../../lib/ext/*:$sdir/../../lib/*" org.apache.solr.cloud.ZkCLI ${1+"$@"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SOLR_MODULES might not be provided, so probably want to use "${SOLR_MODULES:-}"

Also $SOLR_DIR needs to be in quotes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The operator has to set SOLR_MODULES in zkcli.*
In the same way we expect it in solr.in.* to enable different modules.
We'll add the missing quotes.


solr_home="$sdir/../../solr"

# Get solr dir with fullpath
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the Solr Modules auto-added with the bin/solr <tool> command?

Also are you sure that ZKCLI.java and SolrCLI.java use the solr.modules option? I thought that was enabled through the solr.xml, which those tools wouldn't know about.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am curious to find out the answer!

Copy link
Contributor Author

@laminelam laminelam Nov 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @HoustonPutman for looking at this

Little background: We discussed this last year if you remember as part of a bigger PR.

The issue we faced at that time was that SolrJ doesn't "see" the libraries part of the other modules as Solr default class loader does't load classes from different modules. We decided at that time to split the contrib into small ones to make that possible.

One of those contribs (that answers your question) is this one. It enables passing a custom class loader to SolrZKClient.

To answer your question:

  • It's not possible to rely on solr.xml for the reason explained here.
  • ZKCli and SolrCli don't use solr.modules directly but via NodeConfig. NodeConfig reads solr.modules passed through SOLR_MODULES in zkcli.* or solr.in.*

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Houston,

I have added solr modules to solr and solr.cmd.

PS: There is another way to load the modules without touching solr and solr.cmd but this requires changing a lot of "tool" classes where SolrZkClient instantiation is duplicated (the code is duplicated 12 times in 8 diff classes). I think we should extract the code instantiating the SolrZkClient to a separate class as well as considering merging ZK related tool classes.
@HoustonPutman
@epugh

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would LOVE to see that refactoring on SolrZkClient.. I've been looking more at that code base, and I think there is a LOT of opportunity for clean up. We have a LOT of tickets that are around reducing what is in solr and solr.cmd in favour of Java code, so this is a bit of a step in the wrong direction!

Copy link
Contributor Author

@laminelam laminelam Mar 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @epugh
I have a new PR where I separated code instantiating SolrZkClient and CloudSolrClient in ZK related SolrCli tool classes.
The PR adds also a SolrClassLoader to CloudHttp2SolrClient Builder which allows to load solr modules libs without relying on solr and solr.cmd scripts.
As soon as it's approved internally will push it upstream for your review.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exciting!

Add double quotes
Copy link
Contributor

@HoustonPutman HoustonPutman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ZkCli is getting replaced by SolrCLI, so SolrCLI needs support too

Comment on lines 38 to 42
public static final String AWS_SM_CREDENTIALS_SECRET_NAME_VM_PARAM =
"zkAWSSecretCredentialsSecretName";
private static final String AWS_SM_CREDENTIALS_REGION_VM_PARAM = "zkAWSSecretCredentialsRegion";
private static final String AWS_SM_CREDENTIALS_SECRET_NAME_DEFAULT =
"solr.zk.credentials.dev.secret";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • zkAWSSecretCredentialsSecretName -> zkCredentialsAWSSecretName
  • zkAWSSecretCredentialsRegion -> zkCredentialsAWSRegion
  • solr.zk.credentials.dev.secret -> solr.zk.credentials.secret


PATH=$JAVA_HOME/bin:$PATH $JVM $SOLR_ZK_CREDS_AND_ACLS $ZKCLI_JVM_FLAGS -Dlog4j.configurationFile=$log4j_config -Dsolr.home=$solr_home \
-classpath "$sdir/../../solr-webapp/webapp/WEB-INF/lib/*:$sdir/../../lib/ext/*:$sdir/../../lib/*" org.apache.solr.cloud.ZkCLI ${1+"$@"}
-Dsolr.install.dir="$SOLR_DIR" -Dsolr.modules="$SOLR_MODULES" -classpath "$sdir/../../solr-webapp/webapp/WEB-INF/lib/*:$sdir/../../lib/ext/*:$sdir/../../lib/*" org.apache.solr.cloud.ZkCLI ${1+"$@"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"$SOLR_MODULES" -> "${SOLR_MODULES:-}"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @HoustonPutman ,
I have added the changes.
As soon as you're about to approve the PR will update the ref. guide.

@github-actions
Copy link

This PR had no visible activity in the past 60 days, labeling it as stale. Any new activity will remove the stale label. To attract more reviewers, please tag someone or notify the dev@solr.apache.org mailing list. Thank you for your contribution!

@github-actions github-actions bot added the stale PR not updated in 60 days label Feb 28, 2024
Copy link
Contributor

@epugh epugh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you've added the additional support to both the zkcli and the solr scripts, which is great. There is another PR, #2298 that I hope to merge in the next few days which establishes parity between solr zk subommands and what zkcli, and I hope to remove zkcli from the main branch. If that happened, would it make sense/help you to have this support be ONLY available for the solr zk commands?

```


- Pass the secret name and region trough `solr.in.sh:`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"through"?


solr_home="$sdir/../../solr"

# Get solr dir with fullpath
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would LOVE to see that refactoring on SolrZkClient.. I've been looking more at that code base, and I think there is a LOT of opportunity for clean up. We have a LOT of tickets that are around reducing what is in solr and solr.cmd in favour of Java code, so this is a bit of a step in the wrong direction!

@janhoy
Copy link
Contributor

janhoy commented Apr 3, 2024

Are we sure this fits as a Solr module? Since this is client-side solrj code, it could be in e.g. solrj-aws-secret instead?

@laminelam
Copy link
Contributor Author

laminelam commented Apr 4, 2024

Are we sure this fits as a Solr module? Since this is client-side solrj code, it could be in e.g. solrj-aws-secret instead?

Actually, this is a server side code.
When Solr starts, it reads ZK creds from a local (clear) text file and uses them to connect to ZK.
With this feature, Solr would get the ZK creds from an AWS Secret Manager, and then proceed to connect to ZK.

Now, from SolrJ side we have 3 options:

  • Use the existing mechanism. Get the ZK creds and set them in System Props using the standard way.
  • The client can connect to AWS SM to get the creds before passing them to System Props.
  • This module can be used to connect directly to AWS SM and inject the creds into SolrJ. Though, the libs have to
    be added to class path.
    System.setProperty("zkACLProvider", "org.apache.solr.common.cloud.DigestZkACLProvider");
    System.setProperty("zkCredentialsProvider", "org.apache.solr.common.cloud.DigestZkCredentialsProvider");
    System.setProperty("zkCredentialsInjector", "org.apache.solr.secret.zk.AWSSecretManagerCredentialsInjector");
    System.setProperty("zkCredentialsAWSSecretName", "myZkSecret");
    System.setProperty("zkCredentialsAWSRegion", "us-east-1");

    CloudSolrClient client = new CloudHttp2SolrClient.Builder(zkHosts)...

Somewhere down the line SolrZkClient will instantiate an AWSSecretManagerCredentialsInjector.

@github-actions
Copy link

github-actions bot commented Jun 6, 2024

This PR had no visible activity in the past 60 days, labeling it as stale. Any new activity will remove the stale label. To attract more reviewers, please tag someone or notify the dev@solr.apache.org mailing list. Thank you for your contribution!

@github-actions github-actions bot added the stale PR not updated in 60 days label Jun 6, 2024
@epugh
Copy link
Contributor

epugh commented Sep 4, 2024

I don't know that it changes anything, but at this point the zkcli.bat and zkcli.sh are no longer part of solr! Does that help at all? Also, it sounds like we had a refactoring that you were hoping to push up, did that ever make it fruition?

@github-actions github-actions bot removed the stale PR not updated in 60 days label Sep 6, 2024
@github-actions
Copy link

github-actions bot commented Nov 6, 2024

This PR has had no activity for 60 days and is now labeled as stale. Any new activity will remove the stale label. To attract more reviewers, please tag people who might be familiar with the code area and/or notify the dev@solr.apache.org mailing list. To exempt this PR from being marked as stale, make it a draft PR or add the label "exempt-stale". If left unattended, this PR will be closed after another 60 days of inactivity. Thank you for your contribution!

@github-actions github-actions bot added the stale PR not updated in 60 days label Nov 6, 2024
@github-actions
Copy link

github-actions bot commented Jan 5, 2025

This PR is now closed due to 60 days of inactivity after being marked as stale. Re-opening this PR is still possible, in which case it will be marked as active again.

@github-actions github-actions bot added the closed-stale Closed after being stale for 60 days label Jan 5, 2025
@github-actions github-actions bot closed this Jan 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cat:cloud closed-stale Closed after being stale for 60 days dependencies Dependency upgrades scripts stale PR not updated in 60 days start-scripts test-framework tests tool:build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants