Hardening ZooKeeper Znodes for NiFi security
By default, the ZooKeeper Znodes used by NiFi are not secured, which can expose sensitive data to unauthorized access. This section provides instructions for identifying, validating, and hardening the ZooKeeper Znodes used by NiFi. These steps are essential for securing NiFi’s interaction with ZooKeeper in a production environment.
Preparations
Run the following commands on one of your NiFi nodes.
-
Identify the unhardened Znode.
By default, the Znode used by NiFi in Zookeeper is not secured. To identify the root Znode used by NiFi in your Zookeeper cluster, follow these steps:
-
Identify the Znode used by NiFi.
grep "nifi.zookeeper.root.node" $(ps -aux | grep -Eo "[***/var/[^=]*nifi\.properties***]")
This command checks the nifi.properties file for the nifi.zookeeper.root.node property and outputs the exact Znode name. For example:
[root@ccycloud-4.quasar-nncuew.root.comops.site 215-nifi-NIFI_NODE]# grep "nifi.zookeeper.root.node" nifi.properties nifi.zookeeper.root.node=/1
Use this Znode name in all subsequent steps to ensure you are modifying the correct configuration.
-
Verify the current Znode configuration.
Once you have determined your Znode, you can validate it and its subnodes in Zookeeper, using the following commands. For demonstration, in the syntax Znode is referred to as /BASE. Replace it with your determined Znode name.
- List the contents of the
Znode:
[zk: localhost:2181(CONNECTED) 2] ls /BASE [leaders]
- Check the access control list (ACL) of the
Znode:
[zk: localhost:2181(CONNECTED) 3] getAcl /BASE 'world,'anyone : cdrwa
- Check the ACL of
subnodes:
[zk: localhost:2181(CONNECTED) 4] getAcl /BASE/leaders 'world,'anyone : cdrwa
- List the contents of the
Znode:
-
Identify the Znode used by NiFi.
-
Prepare the JAAS file.
-
Create a JAAS configuration file to Kerberize the NiFi ZooKeeper
client.
Example configuration:
Client { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true keyTab="/hadoopfs/fs1/working-dir/nifi.keytab" storeKey=true useTicketCache=false principal="nifi/zz-mwies-nifi-nifi1.zz-mwies.a465-9q4k.cloudera.site@ZZ-MWIES.A465-9Q4K.CLOUDERA.SITE"; };
- Keytab path
- The keytab file path is typically located where nifi.working.directory is configured. For on-premises deployments, the default path is /var/lib/nifi, unless otherwise specified.
- Per-node configuration
- If you have multiple nodes, remember that the principal name is unique to each node because it includes the hostname. You will need to create a slightly modified JAAS configuration for each node to reflect its specific principal.
- Principal
- To determine the exact principal:
- Log in to the Cloudera Manager UI.
- Go to Administration > Security > Kerberos Credentials.
- Locate the principal for NiFi.
- Save this file in a location accessible to NiFi, such as /etc/nifi-jaas/jaas.conf.
-
Create a JAAS configuration file to Kerberize the NiFi ZooKeeper
client.
-
Validate the JAAS file.
To ensure the JAAS configuration file is valid, test it against Zookeeper to see if SASL authentication is successful.
-
Export the JVM flags.
export CLIENT_JVMFLAGS="-Djava.security.auth.login.config=/etc/nifi-jaas/jaas.conf"
-
Connect to ZooKeeper.
zookeeper-client -server $(hostname -f):2181
-
Confirm the output.
Connecting to zz-mwies-nifi-nifi1.zz-mwies.a465-9q4k.cloudera.site:2181 Welcome to ZooKeeper! JLine support is enabled [zk: zz-mwies-nifi-nifi1.zz-mwies.a465-9q4k.cloudera.site:2181(CONNECTING) 0] WATCHER:: WatchedEvent state:SyncConnected type:None path:null WATCHER:: WatchedEvent state:SaslAuthenticated type:None path:null
- Optional: If you see state:SaslAuthenticated, the JAAS file has been created correctly. If there are any issues, use the cat -vet command to identify and fix malformations in the file.
- Distribute the JAAS files to each NiFi node and change the hostname accordingly.
-
Export the JVM flags.
Reconfiguring NiFi
This section guides you through reconfiguring NiFi for secure communication with ZooKeeper using Kerberos authentication. The process involves updating several NiFi configuration files with advanced settings (safety valves) to ensure proper integration and security.
-
For each safety valve, add the corresponding XML snippet.
NiFi Node Advanced Configuration Snippet (Safety Valve) for staging/bootstrap.conf.xml:
<property><name>java.arg.15</name><value>-Djava.security.auth.login.config=/etc/nifi-jaas/jaas.conf</value></property>
NiFi Node Advanced Configuration Snippet (Safety Valve) for staging/nifi.properties.xml:
<property><name>nifi.zookeeper.auth.type</name><value>sasl</value></property><property><name>nifi.zookeeper.kerberos.removeHostFromPrincipal</name><value>true</value></property><property><name>nifi.zookeeper.kerberos.removeRealmFromPrincipal</name><value>true</value></property>
NiFi Node Advanced Configuration Snippet (Safety Valve) for staging/state-management.xml:
<property><name>xml.state-management.cluster-provider.zk-provider.property.Access Control</name><value>CreatorOnly</value><final>true</final></property>
- Save all the changes made to the configuration files.
-
Stop NiFi.
Znode hardening
-
Back up Components Znode.
Before proceeding, in case there is a
components
Znode, ensure a backup of it is created./opt/cloudera/parcels/CFM-***[version]***/TOOLKIT/bin/zk-migrator.sh -r -z $(hostname -f):2181/BASE/components -k /etc/nifi-jaas/jaas.conf -f components-backup.json
This command saves the content of
components
Znode into a JSON file. -
Recreate Components Znode.
-
Delete the existing
components
Znode in Zookeeper.[zk: zz-mwies-nifi-nifi2.zz-mwies.a465-9q4k.cloudera.site:2181(CONNECTED) 0] deleteall /BASE/components [zk: zz-mwies-nifi-nifi2.zz-mwies.a465-9q4k.cloudera.site:2181(CONNECTED) 1] ls /BASE [] [zk: zz-mwies-nifi-nifi2.zz-mwies.a465-9q4k.cloudera.site:2181(CONNECTED) 2] quit WATCHER:: WatchedEvent state:Closed type:None path:null
-
Re-import the
components
Znode from the backup file.[root@zz-mwies-nifi-nifi2 backup]# /opt/cloudera/parcels/CFM-***[version]***/TOOLKIT/bin/zk-migrator.sh -s -z $(hostname -f):2181/BASE/components -k /etc/nifi-jaas/jaas.conf -f components-backup.json --ignore-source
-
After recreating the
components
Znode, verify that it has the correct permissions and content.[zk: zz-mwies-nifi-nifi2.zz-mwies.a465-9q4k.cloudera.site:2181(CONNECTED) 0] ls /BASE [components] [zk: zz-mwies-nifi-nifi2.zz-mwies.a465-9q4k.cloudera.site:2181(CONNECTED) 1] getAcl /BASE/components 'sasl,'nifi : cdrwa [zk: zz-mwies-nifi-nifi2.zz-mwies.a465-9q4k.cloudera.site:2181(CONNECTED) 2] ls -R /BASE/components /BASE/components /BASE/components/0c2f3aaf-0188-1000-ffff-ffffa939f0e7 [zk: zz-mwies-nifi-nifi2.zz-mwies.a465-9q4k.cloudera.site:2181(CONNECTED) 3] getAcl /BASE/components/0c2f3aaf-0188-1000-ffff-ffffa939f0e7 'sasl,'nifi : cdrwa [zk: zz-mwies-nifi-nifi2.zz-mwies.a465-9q4k.cloudera.site:2181(CONNECTED) 4]
-
Delete the existing
-
Set the permissions for BASE Znode.
To harden the BASE Znode, open Zookeeper and set the appropriate ACL using the following command.
[zk: zz-mwies-nifi-nifi2.zz-mwies.a465-9q4k.cloudera.site:2181(CONNECTED) 5] setAcl /BASE sasl:nifi:cdrwa,world:anyone:r [zk: zz-mwies-nifi-nifi2.zz-mwies.a465-9q4k.cloudera.site:2181(CONNECTED) 6] getAcl /BASE 'sasl,'nifi : cdrwa 'world,'anyone : r
If you have a /BASE/leaders Znode, set its ACL recursively.
Similarly, set the ACL for /BASE/components with the same permissions:
setAcl /BASE/components sasl:nifi:cdrwa,world:anyone:r
-
Start NiFi.
Once all configurations are verified and updated, you can safely start the NiFi service.