Apache Knox - Proxying Apache NiFi
TL;DR
There is a working example of Apache Knox and Apache NiFi with Docker here. For all the details about how to set this up and debugging information keep reading.
Overview
Apache Knox is a reverse proxy that simplifies security in front of a Kerberos secured Apache Hadoop cluster and other related components. However, it is not required to have Apache Hadoop to use Knox. One use case for Apache Knox is to provide a single point of entry for disparate components and UIs. Each of these components and UIs can be proxied by Apache Knox.
On the Apache Knox user mailing list the other day, there was an interesting post about using Apache Knox to connect to Apache NiFi. The message author was running into multiple TLS/SSL issues between Apache Knox and Apache NiFi. This post describes how to successfully setup Knox to proxy Apache NiFi.
Apache Knox Support for Apache NiFi
Apache Knox gained support for Apache NiFi in version 0.14.0 with KNOX-970. The Knox 0.14.0 user guide doesn’t have information (yet) about how to setup Knox for proxying NiFi. A prior understanding of how Apache Knox works would help figure out the integration. There is also some Hortonworks Data Flow (HDF) documentation from Hortonworks for setting up Apache Knox with Apache NiFi.
Setting Up Apache Knox and Apache NiFi
There are multiple components involved to setup Apache Knox and Apache NiFi. The Apache NiFi TLS Toolkit helps create TLS/SSL certificates that work for Apache NiFi as well as integrating Apache Knox. Apache NiFi itself will need to be setup. Finally Apache Knox project will be used as both a demo LDAP server and the proxy server. The guide below walks through setting up Apache NiFi secured with TLS, setting up Apache Knox, and finally integrating Apache Knox with Apache NiFi.
Assumptions
- Running macOS for browser
- Apache NiFi 1.5.0 on Linux/macOS
- Apache Knox 1.0.0 on Linux/macOS
Generating SSL/TLS Certificates with Apache NiFi TLS Toolkit
Download and Extract Apache NiFi TLS Toolkit
Download Apache NiFi TLS Toolkit and extract the .tar.gz
file.
tar zxvf nifi-toolkit-1.5.0-bin.tar.gz
cd nifi-toolkit-1.5.0
Generate certificates for Apache NiFi host(s), Apache Knox host(s), and initial admin user
Make sure to fill in the NIFI_FQDN_HOSTNAME
and the KNOX_FQDN_HOSTNAME
.
NIFI_FQDN_HOSTNAME=
./bin/tls-toolkit.sh standalone --hostnames $NIFI_FQDN_HOSTNAME --isOverwrite --trustStorePassword truststore --keyStorePassword nifi --keyStoreType jks
KNOX_FQDN_HOSTNAME=
./bin/tls-toolkit.sh standalone --hostnames $KNOX_FQDN_HOSTNAME --isOverwrite --trustStorePassword truststore --keyStorePassword knox --keyStoreType jks
./bin/tls-toolkit.sh standalone --isOverwrite --clientCertDn CN=nifi-admin,OU=NIFI --clientCertPassword nifi-admin
Note: The above passwords are NOT secure. This is for demo purposes. Removing the --keyStorePassword
, --trustStorePassword
, and --clientCertPassword
options will make the TLS toolkit generate random passwords.
Copy the generated certificates to the correct hosts
For each host that you generated TLS/SSL certificates for, copy the FQDN hostname folder to /opt/certs/
on the node.
Note: If you want to use a different location that is fine just keep track for later.
Configure Browser for Apache NiFi TLS/SSL Authentication
Since Apache NiFi uses 2-way SSL, your browser will have to be configure to provide a client SSL certificate. This was generated above as part of the TLS toolkit steps.
The below steps assume you are on macOS. If you aren’t then search Google for “import ssl certificate browser”.
- Open “Keychain Access”
- Click File -> Import Items
- Import the
CN=nifi-admin_OU=NIFI.p12
file - Enter the password
nifi-admin
when prompted
Setting up Apache NiFi
Download and Extract Apache NiFi
Download Apache NiFi and extract the .tar.gz
file.
tar zxvf nifi-1.5.0-bin.tar.gz
cd nifi-1.5.0
Configure Apache NiFi for TLS/SSL
Set the following properties in conf/nifi.properties
replacing NIFI_FQDN_HOST
with the correct value for your node:
nifi.web.http.port=
nifi.web.https.port=9091
nifi.remote.input.secure=true
nifi.cluster.protocol.is.secure=false
nifi.security.keystore=/opt/certs/NIFI_FQDN_HOSTNAME/keystore.jks
nifi.security.keystoreType=JKS
nifi.security.keystorePasswd=nifi
nifi.security.truststore=/opt/certs/NIFI_FQDN_HOSTNAME/truststore.jks
nifi.security.truststoreType=JKS
nifi.security.truststorePassword=truststore
nifi.security.needClientAuth=true
nifi.web.proxy.context.path=gateway/sandbox/nifi-app
Note: If you let the Apache NiFi TLS Toolkit generate random passwords then they should be specified here instead. If you chose a different location than /opt/certs
put that here as well.
Set the following in conf/authorizers.xml
# Line 52
<property name="Initial User Identity 1">CN=nifi-admin, OU=NIFI</property>
# Line 247
<property name="Initial Admin Identity">CN=nifi-admin, OU=NIFI</property>
Note:
- The space between “, OU” is very important. Apache NiFi is very sensitive to this whitespace.
- If you change the initial admin identity later after starting Apache NiFi, you must delete the generated
conf/users.xml
andconf/authorizations.xml
.
Start Apache NiFi and Check UI
Start Apache NiFi
./bin/nifi.sh start
Open Apache NiFi UI in your browser
https://NIFI_HOST:9091/nifi
NIFI_HOST
- This should be the fully qualified domain name of theNIFI_HOST
- This should prompt for a client certificate, select the
CN=nifi-admin,OU=NIFI
certificate.
Note: It may take a minute or two for Apache NiFi to start. Check the logs
directory for more details.
You should see this:
Configure Apache NiFi for Apache Knox
For Apache Knox to be able to proxy requests to Apache NiFi, there needs to be an Apache Knox user and an authorization policy in Apache NiFi.
For each of the steps below, replace KNOX_FQDN_HOSTNAME
with the correct value for your Apache Knox host.
Add Apache Knox user to Apache NiFi
Open the Apache NiFi hamburger menu | |
Click "Users" | |
Click the "Add User" icon | |
Enter `CN=KNOX_FQDN_HOSTNAME, OU=NIFI` into the "Identity" box and click "OK" | |
Close the "NiFi Users" dialog with the "X" button. |
Add Apache NiFi policy to allow Apache Knox user to proxy requests
Open the Apache NiFi hamburger menu | |
Click "Policies" | |
Select "proxy user requests" from the policy dropdown and client "Create" a new policy | |
Ensure that "proxy user requests" is selected and click the "Add User" icon | |
Add the user `CN=KNOX_FQDN_HOSTNAME, OU=NIFI` and click "Add" | |
Close the "Access Policies" dialog with the "X" button. |
Add admin
user to Apache NiFi for use with Apache Knox
Open the Apache NiFi hamburger menu | |
Click "Users" | |
Click the "Add User" icon | |
Enter `admin` into the "Identity" box and click "OK" | |
Close the "NiFi Users" dialog with the "X" button. |
Add Apache NiFi policy to allow admin
user to view user interface
Open the Apache NiFi hamburger menu | |
Click "Policies" | |
Ensure that "view user interface" is selected and click the "Add User" icon | |
Add the user `admin` and click "Add" | |
Close the "Access Policies" dialog with the "X" button. |
Setting up Apache Knox
Download and Extract Apache Knox
Download Apache Knox 1.0.0 and extract the .zip
file
unzip knox-1.0.0.zip
cd knox-1.0.0
Start Apache Knox Demo LDAP server
./bin/ldap.sh start
Start Apache Knox
./bin/knoxcli.sh create-master
./bin/gateway.sh start
Note: Keep track of the Apache Knox master secret since you will need it later.
Check Apache Knox
Open Apache Knox in your browser
https://KNOX_HOST:8443/gateway/manager/admin-ui/index.html
KNOX_HOST
- This should be the fully qualified domain name of theKNOX_HOST
- Username =
admin
- Password =
admin-password
You should see this:
Setup Apache Knox for Apache NiFi
Add 2-way NiFi TLS/SSL Certificates to Apache Knox
Make sure to enter the KNOX_MASTER_SECRET
value that you used from above.
KNOX_MASTER_SECRET=
keytool -importkeystore -destkeypass $KNOX_MASTER_SECRET -srckeystore /opt/certs/knox/keystore.jks -destkeystore data/security/keystores/gateway.jks -deststoretype JKS -srcstorepass keystore -deststorepass $KNOX_MASTER_SECRET -noprompt
keytool -importkeystore -srckeystore /opt/certs/knox/truststore.jks -destkeystore data/security/keystores/gateway.jks -deststoretype JKS -srcstorepass truststore -deststorepass $KNOX_MASTER_SECRET -noprompt
# Restart Apache Knox to pickup new certificates
./bin/gateway.sh stop
./bin/gateway.sh start
Note: If you let the Apache NiFi TLS Toolkit generate random passwords then they should be specified here instead. If you chose a different location than /opt/certs put that here as well.
Add Apache NiFi to Apache Knox sandbox topology
Add the following to conf/topologies/sandbox.xml
at the end before </topology>
. Replace NIFI_FQDN_HOSTNAME
with the proper value for your Apache NiFi host.
<service>
<role>NIFI</role>
<url>https://NIFI_FQDN_HOSTNAME:9091/</url>
<param name="useTwoWaySsl" value="true" />
</service>
Check Apache Knox proxying of Apache NiFi
https://KNOX_HOST:8443/gateway/sandbox/nifi-app/nifi
KNOX_HOST
- This should be the fully qualified domain name of theKNOX_HOST
- Username =
admin
- Password =
admin-password
You should see this:
Conclusion
By now you should have a working Apache Knox proxying Apache NiFi setup. As configured, the admin
user only has permissons to view the Apache NiFi interface. You would need to add more policies for the admin
user to do more. Apache Knox also has guest
, sam
, and tom
users that you can use to see how different users get passed to Apache Knox. As far as next steps, configuring the Apache NiFi LDAP authorizer to point to Apache Knox LDAP server could be useful for simplifying permissions.
If you are using Hortonworks Data Flow (HDF) and Hortonworks Data Platform (HDP), Apache Ambari manages many of the settings laid out above. You can check the file values against what is recommended here, but you need to use Ambari to configure the different settings.
If you have further questions not answered here, reach out on the Apache Knox user mailing list.
Troubleshooting Apache Knox and Apache NiFi
The troubleshooting steps below are designed to answer questions about Apache Knox and Apache NiFi based on the configurations above. For the most part, they are generic enough for any TLS/SSL debugging and can hopefully point you in the right direction.
Apache NiFi Logs
Apache NiFi logs are located in the logs
directory where you extracted the tar.gz
file. nifi-app.log
will have Apache NiFi application logs. nifi-user.log
will have Apache NiFi user related logs. Most errors due to misconfigured TLS/SSL will be in nifi-app.log
.
Apache Knox Logs
Apache Knox logs are located in the logs
directory where you extracted the .zip
file. gateway.log
will have most of the TLS/SSL related errors. Note that by default Apache Knox only logs ERROR
messages and will not show more details. If you want more details, in conf/gateway-log4j.properties
change log4j.rootLogger=ERROR, drfa
to log4j.rootLogger=INFO, drfa
.
Browser - “Your connection is not private”
Your connection is not private
Attackers might be trying to steal your information from HOSTNAME (for example, passwords, messages, or credit cards).
Your browser does not trust the Apache NiFi TLS Toolkit CA. Typically you can safely ignore this warning. To fix the warning, you need to have your browser turst the Apache NiFi TLS Toolkit CA certificate.
Browser - “This site can’t provide a secure connection”
This site can’t provide a secure connection
The error typically happens when you are trying to connect to an endpoint that doesn’t support SSL/TLS. Note that this message will NOT say “login certificate”. If the message says “login certificate” see the error below. For this error, see details above in “Configure Apache NiFi for TLS/SSL”.
Browser - “This site can’t provide a secure connection” - “login certificate”
This site can’t provide a secure connection
HOSTNAME didn’t accept your login certificate, or one may not have been provided.
The error typically happens when you have a service like Apache NiFi that requires 2 way SSL and the browser doesn’t have a client certificate. See details above in “Configure Browser for Apache NiFi TLS/SSL Authentication”.
Another reason for this could be that Apache NiFi doesn’t trust the client certificate provided. The Apache NiFi truststore configured in nifi.properties
could not trust the certificate provided. There aren’t any errors in nifi-app.log
that would indicate this. See details above in “Configure Apache NiFi for TLS/SSL”.
Apache NiFi - Fails to start - ... no truststore properties are configured.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flowService': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flowController': FactoryBean threw exception on object creation; nested exception is org.apache.nifi.framework.security.util.SslContextCreationException: Need client auth is set to 'true', but no truststore properties are configured.
This happens if the truststore is not configured in nifi.properties
. See details above in “Configure Apache NiFi for TLS/SSL”.
Apache NiFi - Fails to start - Keystore was tampered with, or password was incorrect
2018-03-17 12:58:13,580 WARN [main] org.apache.nifi.web.server.JettyServer Failed to start web server... shutting down.
java.io.IOException: Keystore was tampered with, or password was incorrect
This error occurs when there is a bad password in nifi.properties
for the truststore or keystore. See details above in “Configure Apache NiFi for TLS/SSL”.
Apache NiFi - Unknown user with identity - CN=nifi-admin, OU=NIFI
Unknown user with identity 'CN=nifi-admin, OU=NIFI'. Contact the system administrator.
Most likely means there is a typo in conf/authorizers.xml
. The space between “, OU=” is very important. See details above in “Configure Apache NiFi for TLS/SSL”.
Apache NiFi - Insufficient Permissions - Untrusted proxy
Insufficient Permissions
Untrusted proxy CN=KNOX_FQDN_HOSTNAME, OU=NIFI
This is caused by Apache NiFi not having a user or a policy to allow Apache Knox to act as a trusted proxy. See details above in “Configure Apache NiFi for Apache Knox”.
Apache NiFi - Unknown user with identity - CN=admin, OU=NIFI
Unknown user with identity 'CN=admin, OU=NIFI'. Contact the system administrator.
Most likely means that the admin
user was not setup in Apache NiFi. See details above in “Add admin user to Apache NiFi for use with Apache Knox”.
Apache NiFi - Insufficient Permissions - Unable to view the user interface
Insufficient Permissions
Unable to view the user interface. Contact the system administrator.
Most likely means you missed adding the admin
user to the view user interface
Apache NiFi policy. See details above in “Add Apache NiFi policy to allow admin user to view user interface”.
Apache Knox - Browser - Repeated login boxes
This means that you either have entered the wrong username/password or that the Apache Knox LDAP server is not started. See details above in “Start Apache Knox Demo LDAP server”.
Apache Knox - Fails to start - UnrecoverableKeyException: Cannot recover key
2018-03-17 12:49:02,873 FATAL knox.gateway (GatewayServer.java:main(163)) - Failed to start gateway: java.security.UnrecoverableKeyException: Cannot recover key
This is caused when there is an alias in gateway.jks
that doesn’t have the keypassword
set to the Apache Knox master secret. This happens when you import a certificate from a keystore like KNOX_FQDN_HOSTNAME/keystore.jks
and don’t set the -destkeypass
to the Apache Knox master secret. See details above in “Add 2-way NiFi TLS/SSL Certificates to Apache Knox”.
Apache Knox - Browser - 500 Error
HTTP ERROR 500
Problem accessing /gateway/sandbox/nifi-app/nifi. Reason:
Server Error
This error can manifest itself in a variety of ways with Apache Knox. You need to look at the Apache Knox logs at logs/gateway.log
and look for the specific error. Some errors are below:
Apache Knox - host not reachable?
2018-03-17 12:53:39,558 WARN knox.gateway (DefaultDispatch.java:executeOutboundRequest(147)) - Connection exception dispatching request: https://nifi/?user.name=admin java.net.UnknownHostException: nifi: nodename nor servname provided, or not known
java.net.UnknownHostException: nifi: nodename nor servname provided, or not known
This error happens when you have the wrong <url></url>
set in Apache Knox topology xml file for the Apache NiFi service. See details above in “Add Apache NiFi to Apache Knox sandbox topology”.
Apache Knox - PKIX path building failed
2018-03-17 12:35:46,420 WARN knox.gateway (DefaultDispatch.java:executeOutboundRequest(147)) - Connection exception dispatching request: https://NIFI_FQDN_HOSTNAME:9091/nifi?user.name=admin javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
The errors “PKIX path building failed” and “unable to find valid certification path” happen when Apache Knox doesn’t trust the certificate of Apache NiFi. Most likely the truststore.jks
certificates generated for Apache Knox by the Apache NiFi TLS Toolkit were not imported into gateway.jks
. See details above in “Add 2-way NiFi TLS/SSL Certificates to Apache Knox”.
The second reason this can happen is if <param name="useTwoWaySsl" value="true" />
is missing in Apache Knox topology xml file for the Apache NiFi service. To check and fix this, see details above in “Add Apache NiFi to Apache Knox sandbox topology”.
Apache Knox - Received fatal alert: bad_certificate
2018-03-17 12:41:39,413 WARN knox.gateway (DefaultDispatch.java:executeOutboundRequest(147)) - Connection exception dispatching request: https://NIFI_FQDN_HOSTNAME:9091/nifi?user.name=admin javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
javax.net.ssl.SSLHandshakeException: Received fatal alert: bad_certificate
This is most likely caused by the Apache NiFi TLS Toolkit Apache Knox keystore not being imported into gateway.jks
. To check and fix this, see details above in “Add 2-way NiFi TLS/SSL Certificates to Apache Knox”.
Another reason for this could be that Apache NiFi doesn’t trust the client certificate provided. The Apache NiFi truststore configured in nifi.properties
could not trust the certificate provided. There aren’t any errors in nifi-app.log
that would indicate this. See details above in “Configure Apache NiFi for TLS/SSL”.
Apache Knox - SSLPeerUnverifiedException
javax.net.ssl.SSLPeerUnverifiedException: Certificate for <NIFI-IP-ADDR> doesn't match any of the subject alternative names: [NIFI-IP-ADDR]
In the blog above I don’t recommend using IP addresses since they don’t work well with TLS/SSL certificates. The Apache NiFi TLS Toolkit does not support generating certificates for IP addresses. The error above is because the certificate thinks the IP address is actually a DNS entry and doesn’t match.
Something not mentioned?
If you have further questions not answered here, reach out on the Apache Knox user mailing list.