jfrazee commented on a change in pull request #4753:
URL: https://github.com/apache/nifi/pull/4753#discussion_r560378813



##########
File path: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/state/server/ZooKeeperStateServer.java
##########
@@ -198,6 +219,104 @@ public static ZooKeeperStateServer create(final 
NiFiProperties properties) throw
             zkProperties.load(bis);
         }
 
-        return new ZooKeeperStateServer(zkProperties);
+        return new ZooKeeperStateServer(reconcileProperties(properties, 
zkProperties));
+    }
+
+    /**
+     * Reconcile properties between the nifi.properties and 
zookeeper.properties (zoo.cfg) files. Most of the ZooKeeper server properties 
are derived from
+     * the zookeeper.properties file, while the TLS key/truststore properties 
are taken from nifi.properties.
+     * @param niFiProperties NiFiProperties file containing ZooKeeper client 
and TLS configuration
+     * @param zkProperties The zookeeper.properties file containing Zookeeper 
server configuration
+     * @return A reconciled QuorumPeerConfig which will include TLS properties 
set if they are available.
+     * @throws IOException If configuration files fail to parse.
+     * @throws ConfigException If secure configuration is not as expected. 
Check administration documentation.
+     */
+    private static QuorumPeerConfig reconcileProperties(NiFiProperties 
niFiProperties, Properties zkProperties) throws IOException, ConfigException {
+        QuorumPeerConfig peerConfig = new QuorumPeerConfig();
+        peerConfig.parseProperties(zkProperties);
+
+        // If secureClientPortAddress is set but no TLS config is set, fail to 
start.
+        final boolean isTLSConfigPresent = 
niFiProperties.isTlsConfigurationPresent() || 
niFiProperties.isZooKeeperTlsConfigurationPresent();
+        if (peerConfig.getSecureClientPortAddress() != null && 
!isTLSConfigPresent) {
+            throw new ConfigException(
+                    String.format("Property secureClientPort was set in %s but 
there was no TLS config present in nifi.properties",
+                    
niFiProperties.getProperty(NiFiProperties.STATE_MANAGEMENT_ZOOKEEPER_PROPERTIES)));
+        }
+
+        // If this is an insecure NiFi no changes are needed:
+        if (!isTLSConfigPresent) {
+            logger.info("ZooKeeper is not secure because appropriate TLS 
configuration was not provided. Please refer to administration guide.");
+            return peerConfig;
+        }
+
+        // Otherwise the following sets secure TLS settings for embedded 
Zookeeper
+
+        // Remove plaintext client ports and addresses and warn if set, see 
NIFI-7203:
+        InetSocketAddress clientPort = peerConfig.getClientPortAddress();
+        if (clientPort != null) {
+            zkProperties.remove("clientPort");
+            zkProperties.remove("clientPortAddress");
+            logger.warn("Invalid configuration detected: secure NiFi with 
embedded ZooKeeper configured for insecure connections. " +
+                    "Removed insecure port from embedded ZooKeeper 
configuration to deactivate insecure connections.");
+        }
+
+        // Set base ZooKeeper TLS server properties
+        setTlsProperties(zkProperties, new ZooKeeperServerX509Util(), 
niFiProperties);
+        // Set quorum ZooKeeper TLS server properties
+        setTlsProperties(zkProperties, new ZooKeeperQuorumX509Util(), 
niFiProperties);
+
+        // Set TLS client port:
+        zkProperties.setProperty("secureClientPort", 
getSecurePort(peerConfig));
+
+        // Set the required connection factory for TLS
+        zkProperties.setProperty(ZOOKEEPER_SERVER_CNXN_FACTORY, 
NettyServerCnxnFactory.class.getName());
+        zkProperties.setProperty(ZOOKEEPER_SSL_QUORUM, 
Boolean.TRUE.toString());
+
+        // Port unification allows both secure and insecure connections - 
setting to false means only secure connections will be allowed.
+        zkProperties.setProperty(ZOOKEEPER_PORT_UNIFICATION, 
Boolean.FALSE.toString());
+
+        // Recreate and reload the adjusted properties to ensure they're still 
valid for ZK:
+        peerConfig = new QuorumPeerConfig();
+        peerConfig.parseProperties(zkProperties);
+        return peerConfig;
+    }
+
+    private static void setTlsProperties(Properties zooKeeperProperties, 
X509Util zooKeeperUtil, NiFiProperties niFiProperties) {
+        
zooKeeperProperties.setProperty(zooKeeperUtil.getSslKeystoreLocationProperty(),
+                ZooKeeperClientConfig.getPreferredProperty(niFiProperties, 
NiFiProperties.ZOOKEEPER_SECURITY_KEYSTORE, NiFiProperties.SECURITY_KEYSTORE));
+        
zooKeeperProperties.setProperty(zooKeeperUtil.getSslKeystorePasswdProperty(),
+                ZooKeeperClientConfig.getPreferredProperty(niFiProperties, 
NiFiProperties.ZOOKEEPER_SECURITY_KEYSTORE_PASSWD, 
NiFiProperties.SECURITY_KEYSTORE_PASSWD));
+        
zooKeeperProperties.setProperty(zooKeeperUtil.getSslKeystoreTypeProperty(),
+                ZooKeeperClientConfig.getPreferredProperty(niFiProperties, 
NiFiProperties.ZOOKEEPER_SECURITY_KEYSTORE_TYPE, 
NiFiProperties.SECURITY_KEYSTORE_TYPE));
+        
zooKeeperProperties.setProperty(zooKeeperUtil.getSslTruststoreLocationProperty(),
+                ZooKeeperClientConfig.getPreferredProperty(niFiProperties, 
NiFiProperties.ZOOKEEPER_SECURITY_TRUSTSTORE, 
NiFiProperties.SECURITY_TRUSTSTORE));
+        
zooKeeperProperties.setProperty(zooKeeperUtil.getSslTruststorePasswdProperty(),
+                ZooKeeperClientConfig.getPreferredProperty(niFiProperties, 
NiFiProperties.ZOOKEEPER_SECURITY_TRUSTSTORE_PASSWD, 
NiFiProperties.SECURITY_TRUSTSTORE_PASSWD));
+        
zooKeeperProperties.setProperty(zooKeeperUtil.getSslTruststoreTypeProperty(),
+                ZooKeeperClientConfig.getPreferredProperty(niFiProperties, 
NiFiProperties.ZOOKEEPER_SECURITY_TRUSTSTORE_TYPE, 
NiFiProperties.SECURITY_TRUSTSTORE_TYPE));
+    }
+
+    private static String getSecurePort(QuorumPeerConfig peerConfig) throws 
ConfigException {
+        final InetSocketAddress secureClientAddress = 
peerConfig.getSecureClientPortAddress();
+        String secureClientPort = null;
+
+        if (secureClientAddress != null && secureClientAddress.getPort() >= 
MIN_PORT && secureClientAddress.getPort() <= MAX_PORT) {
+            secureClientPort = String.valueOf(secureClientAddress.getPort());
+            logger.debug("Secure client port retrieved from ZooKeeper 
configuration: {}", secureClientPort);
+            return secureClientPort;
+        } else {
+            throw new ConfigException(String.format("NiFi was configured to be 
secure but ZooKeeper secureClientPort could not be retrieved from 
zookeeper.properties file or it was not " +
+                    "in valid port range %i - %i.", MIN_PORT, MAX_PORT));

Review comment:
       `%i` isn't valid, should be `%d`:
   ```suggestion
                       "in valid port range %d - %d.", MIN_PORT, MAX_PORT));
   ```




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to