-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NIFI-12501 Encrypt MiNiFi bootstrap properties #8151
NIFI-12501 Encrypt MiNiFi bootstrap properties #8151
Conversation
5243f63
to
4b1ffa7
Compare
4b1ffa7
to
18421f1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for putting together this new feature @ferencerdei.
As much of the implementation is based on the existing NiFi approach, the code looks straightforward in general. However, there appear to be a few places where copying some of the NiFi approach brought over some elements that may not be needed. This is particularly true of the nifi-property-protection-factory
library, which has many transitive dependencies that do not apply to MiNiFi. That is one high-level item that should be addressed. I also noted a handful of other items to consider.
return bootstrapProperties.containsKey(MINIFI_BOOTSTRAP_SENSITIVE_KEY) && !StringUtils.isBlank(bootstrapProperties.getProperty(MINIFI_BOOTSTRAP_SENSITIVE_KEY)); | ||
} | ||
|
||
private Path createSensitiveKeyFile(File confDir) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for writing out the sensitive key value to a new file as opposed to having the new process read the key from the bootstrap configuration itself? Although NiFi bootstrap has done some similar things with other values, this is not an optimal approach as it makes additional copies on the file system. This is one example of an approach where some additional consideration is worthwhile to implement a better solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to keep to logic as consistent as possible with the NiFi, so we can easily switch when we change the bootstrap / application properties file structure to the same as in NiFi. But yea, It can be read from bootstrap directly (it could be even in NiFi.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the reply, given that this is a new implementation, although based on the existing one, this is a good opportunity to change the approach for MiNiFi itself.
if (isSensitiveKeyPresent(bootstrapProperties)) { | ||
Path sensitiveKeyFile = createSensitiveKeyFile(confDir); | ||
writeSensitiveKeyFile(bootstrapProperties, sensitiveKeyFile); | ||
sensitiveParameter = "-K " + sensitiveKeyFile.toFile().getAbsolutePath(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in writing the key, it seems like it one option would be to pass the path to the bootstrap configuration and having the called process read the file, instead of creating a new copy of the key in a new file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I'll apply that change
...ns/minifi-commons-utils/src/main/java/org/apache/nifi/minifi/commons/utils/PropertyUtil.java
Outdated
Show resolved
Hide resolved
...ns/minifi-commons-utils/src/main/java/org/apache/nifi/minifi/commons/utils/PropertyUtil.java
Outdated
Show resolved
Hide resolved
...minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-properties-loader/pom.xml
Outdated
Show resolved
Hide resolved
...-config/src/main/java/org/apache/nifi/minifi/toolkit/config/command/MiNiFiEncryptConfig.java
Outdated
Show resolved
Hide resolved
...-config/src/main/java/org/apache/nifi/minifi/toolkit/config/command/MiNiFiEncryptConfig.java
Show resolved
Hide resolved
18421f1
to
66f2596
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review, I've applied the suggested changes
return bootstrapProperties.containsKey(MINIFI_BOOTSTRAP_SENSITIVE_KEY) && !StringUtils.isBlank(bootstrapProperties.getProperty(MINIFI_BOOTSTRAP_SENSITIVE_KEY)); | ||
} | ||
|
||
private Path createSensitiveKeyFile(File confDir) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to keep to logic as consistent as possible with the NiFi, so we can easily switch when we change the bootstrap / application properties file structure to the same as in NiFi. But yea, It can be read from bootstrap directly (it could be even in NiFi.)
...minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-properties-loader/pom.xml
Outdated
Show resolved
Hide resolved
if (isSensitiveKeyPresent(bootstrapProperties)) { | ||
Path sensitiveKeyFile = createSensitiveKeyFile(confDir); | ||
writeSensitiveKeyFile(bootstrapProperties, sensitiveKeyFile); | ||
sensitiveParameter = "-K " + sensitiveKeyFile.toFile().getAbsolutePath(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I'll apply that change
...ns/minifi-commons-utils/src/main/java/org/apache/nifi/minifi/commons/utils/PropertyUtil.java
Outdated
Show resolved
Hide resolved
...-config/src/main/java/org/apache/nifi/minifi/toolkit/config/command/MiNiFiEncryptConfig.java
Outdated
Show resolved
Hide resolved
...work-bundle/minifi-framework/minifi-runtime/src/main/java/org/apache/nifi/minifi/MiNiFi.java
Outdated
Show resolved
Hide resolved
...roperties-loader/src/main/java/org/apache/nifi/minifi/properties/MiNiFiPropertiesLoader.java
Outdated
Show resolved
Hide resolved
...ies-loader/src/main/java/org/apache/nifi/minifi/properties/ProtectedBootstrapProperties.java
Outdated
Show resolved
Hide resolved
...erties-loader/src/main/java/org/apache/nifi/minifi/properties/ProtectedMiNiFiProperties.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for putting together this change. It helps MiNiFi to become more secure by protecting the sensitive properties. I have no issues with the approach, only left some cosmetics related comment.
@@ -41,4 +50,22 @@ public String getProperty(String key) { | |||
.orElseGet(() -> super.getProperty(key)); | |||
} | |||
|
|||
@Override | |||
public String getProperty(String key, String defaultValue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With introducing this method the previous one could be refactored to
@Override
public String getProperty(String key) {
return getProperty(key, null);
}
} | ||
|
||
public static ProtectedBootstrapProperties loadProtectedProperties(File file) { | ||
if (file == null || !file.exists() || !file.canRead()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code is duplicated, and present in the same form in MinifiPropertiesLoader class.
I suggest to create an interface and extract the common code to there.
if (existingValue != null) { | ||
if (existingValue.toString().equals(value.toString())) { | ||
redundantKeys.add(key.toString()); | ||
return existingValue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's just a copy paste code, but this return is unnecessary. Practically we always return with value.
.stream() | ||
.filter(entry -> ((String) entry.getKey()).startsWith(JAVA_ARG_KEY_PREFIX)) | ||
.map(entry -> (String) entry.getValue()) | ||
.filter(entry -> entry.startsWith(JAVA_ARG_KEY_PREFIX)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lamdba variable should now be called key instead of entry
testProperties.put(PULL_HTTP_BASE_KEY + ".override.core", "true"); | ||
testProperties.put(FileChangeIngestor.POLLING_PERIOD_INTERVAL_KEY, FileChangeIngestor.DEFAULT_POLLING_PERIOD_INTERVAL); | ||
testProperties.put(MiNiFiProperties.NIFI_MINIFI_FLOW_CONFIG.getKey(), MiNiFiProperties.NIFI_MINIFI_FLOW_CONFIG.getDefaultValue()); | ||
when(testProperties.getProperty(FileChangeIngestor.CONFIG_FILE_PATH_KEY)).thenReturn(TEST_CONFIG_PATH); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice refactor
if (shutdownProperty != null) { | ||
properties.setProperty(GRACEFUL_SHUTDOWN_PROP, shutdownProperty); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could eliminate the if with Optional.ofNullable(shutdownProperty).orElse(DEFAULT_GRACEFUL_SHUTDOWN_VALUE)
@@ -142,10 +144,7 @@ public void testError() { | |||
// Exception testing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's not your code, but please remove the comment, as it does not hold any additional or valuable information
@@ -63,7 +63,7 @@ public enum MiNiFiProperties { | |||
NIFI_MINIFI_SECURITY_SSL_PROTOCOL("nifi.minifi.security.ssl.protocol", null, false, false, VALID), | |||
NIFI_MINIFI_FLOW_USE_PARENT_SSL("nifi.minifi.flow.use.parent.ssl", null, false, true, VALID), | |||
NIFI_MINIFI_SENSITIVE_PROPS_KEY("nifi.minifi.sensitive.props.key", null, true, false, VALID), | |||
NIFI_MINIFI_SENSITIVE_PROPS_ALGORITHM("nifi.minifi.sensitive.props.algorithm", null, true, false, VALID), | |||
NIFI_MINIFI_SENSITIVE_PROPS_ALGORITHM("nifi.minifi.sensitive.props.algorithm", null, false, false, VALID), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch!
@@ -60,6 +61,87 @@ After downloading the binary and extracting it, to run the MiNiFi Toolkit Conver | |||
## Note | |||
It's not guaranteed in all circumstances that the migration will result in a correct flow. For example if a processor's configuration has changed between version, the conversion tool won't be aware of this, and will use the deprecated property names. You will need to fix such issues manually. | |||
|
|||
# <a id="encrypt-sensitive-properties-in-bootstrapconf" href="#encrypt-sensitive-properties-in-bootstrapconf">Encrypting Sensitive Properties in bootstrap.conf</a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the detailed docs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ferencerdei Just a note that this appears close to completion, but there are a couple conflicts at the moment that require rebasing.
…nifi_bootstrap_conf_properties # Conflicts: # minifi/minifi-assembly/README.md # minifi/minifi-bootstrap/src/test/java/org/apache/nifi/minifi/bootstrap/configuration/ingestors/PullHttpChangeIngestorCommonTest.java # minifi/minifi-bootstrap/src/test/java/org/apache/nifi/minifi/bootstrap/configuration/ingestors/PullHttpChangeIngestorSSLTest.java # minifi/minifi-bootstrap/src/test/java/org/apache/nifi/minifi/bootstrap/configuration/ingestors/PullHttpChangeIngestorTest.java # minifi/minifi-c2/minifi-c2-assembly/README.md
Thanks for the review comments, I resolved the requested changes and conflicts as well. |
Thanks for the updates. Looked good to me. Merged. |
Summary
NIFI-12501
This change makes it possible to encrypt bootstrap.conf file. The properties used in bootstrap classes and the MiNiFi framework will handle these (separate bootstrap/minifi property loaders are defined).
Added an encrypt config functionality to the MiNiFi toolkit that generates a random encryption key and encrypts sensitive values in the defined bootstrap.conf.
Tracking
Please complete the following tracking steps prior to pull request creation.
Issue Tracking
Pull Request Tracking
NIFI-00000
NIFI-00000
Pull Request Formatting
main
branchVerification
Please indicate the verification steps performed prior to pull request creation.
Build
mvn clean install -P contrib-check
Licensing
LICENSE
andNOTICE
filesDocumentation