Hi Erik,

Thanks for reaching out for assistance on this topic. I’ll try to answer your 
questions in order. 

> Short Version:
> When running the NiFi toolkit ../bin/tls-toolkit.sh server, how do I get the 
> server to include an additional public certificate of authority in the 
> returned truststore.jks file (../bin/tls-toolkit.sh client calls)


The quick answer is that there is currently a feature availability difference 
between the standalone mode and the client/server mode of the TLS Toolkit. The 
behavior you are requesting is currently in the standalone mode but not in the 
client/server mode. This is due to a difference in their implementation logic, 
which is being addressed as part of a larger refactoring under NIFI-5462 [1], 
which is a component of the TLS Toolkit epic NIFI-5458 [2]. 

If you need that functionality out of the box right now, using the standalone 
mode with the --additionalCACertificate flag [3] will allow you to provide 
further CA certificates into the signing process.  

However, there is a current workaround for the client/server mode which may be 
acceptable to you. Rather than manually signing each issued node certificate 
with your enterprise CA, you can sign the NiFi CA certificate with the 
enterprise CA (following the same CSR steps you already do), and then 
subsequent signing operations using the toolkit should propagate this 
information via the certificate chain. There are explicit instructions for 
performing these actions in the Admin Guide under "Using An Existing 
Intermediate Certificate Authority (CA)” [4] and "Signing with 
Externally-signed CA Certificates” [5]. I’ve also included example output below 
showing a keystore containing a private key entry with 2 certificates 
demonstrating the Root CA signing an Intermediate CA, which signed the node 
certificate. 

Your further questions are regarding the configuration of shared trust with the 
NiFi Registry instance. I’ll offer some quick background in response to your 
last statements and then try to address each component directly. 

The NiFi TLS Toolkit was designed to facilitate the deployment and 
configuration of TLS behavior _in an environment lacking an enterprise security 
team_. By design, the toolkit assumes a completely isolated environment where 
an individual admin was deploying NiFi as a proof of concept, development 
system. The toolkit is _not_ designed to replace an enterprise security team, 
and in environments where this expertise and these services are available, that 
process should be followed. I am sorry if the documentation feels lacking to 
you. These are very complicated processes, and it’s written to be targeted to 
an “advanced beginner” — someone who understands the general concepts but isn’t 
familiar with every openssl setting, and benefits from some level of 
abstraction. With that in mind, we still tried to make the steps clear for the 
common use cases we expect users to encounter. If you have suggestions for 
improving the documentation (specific steps that were unclear, etc.) we welcome 
those. 

In response to the specific issue you are encountering, I am surprised this is 
occurring. The toolkit is designed to issue certificates properly signed with 
the CA, so any “node” should be trusted automatically. 

I understand this seems pedantic, but definitions and terminology are critical 
in security, so I want to clarify that your command to issue a certificate for 
NiFi Registry is not issuing a _client_ certificate. It is issuing a server 
certificate which will be used in a server role when the Registry is hosting a 
web service (API/UI) and external entities connect to it (Registry Client in 
NiFi, a user via browser, the NiFi CLI toolkit, etc.). The command you’re using 
to issue a cert for the CLI is doing the same thing. The instructions on 
configuring security for the CLI [6] assume you are using an actual _client_ 
certificate, for example one issued for a human user which has been loaded into 
the browser to allow authenticated access. The differences in issuing a 
_client_ certificate include the command-line flags for the toolkit (-C), the 
key usages and roles assigned, the output format (JKS vs PKCS12), etc. 

I am sorry the PKIX error message is unclear. The error is a Java-native 
exception and we can make an effort to capture it and provide a more 
user-friendly message in the future. However, searching "PKIX path building 
failed nifi” [7] does return a number of helpful articles and Q/A posts with 
instructions to resolve the issue. 

Your statement about needing to run a meddler-in-the-middle is confusing to me. 
It appears that the issued truststore does not contain the specific CA entry 
you need in order to form a complete certificate chain and authenticate the 
service. A MitM won’t resolve this, and the commands you included don’t run a 
MitM; rather you make a TLS connection to the server using openssl s_client and 
retrieve the server’s public certificate, then import that into the truststore. 
This process makes sense but should be unnecessary. Can you share the command 
you use to generate the truststore initially, and the state of the truststore 
upon generation? Any truststore generated by the (same instance of the) toolkit 
should contain the public certificate of the CA, which is what signed all node 
certificates in the environment, so they should all be cross-trusted. Needing 
to import the public certificate of an external CA goes back to the first part 
of your email. The local/NiFi CA certificate should be present by default. The 
capability to capture the external CA is already recorded in NIFI-5460 [8]. 
I’ve marked the issue you reported as a duplicate of that. Please provide any 
feedback if you feel this is incorrect. 


>> This is a mess of undocumented black magic.
>> 
>> I dont expect the public root CA to change.
>> 
>> Is there a way to simplify this process? Cant we ignore this whole chain 
>> thing? Maybe include the public CA cert in the nifi-ca-keystore.jks on the 
>> server running the
>> ../bin/tls-toolkit.sh server
>> 
>> This voodoo process really is too much guys and needs to be simplified. 
>> Suggestions are welcome.


Again, I apologize that the documentation wasn’t helpful to you during this 
time. Your statement on not expecting the public root CA to change feels 
specific to your environment. Other enterprise organizations rotate that 
certificate on regular intervals and on any kind of compromise, so building in 
static preset values is not something we are prepared to do. Similarly, 
automatically importing the JRE cacerts default truststore would provide 
out-of-the-box compatibility with many publicly accessible commercial CA 
services, but this would invisibly expose many additional risks, as a user 
could be expecting to send data to an internal service, signed only by an 
internal CA, and accidentally misconfigure the processor/reporting task to 
validate a certificate signed by any arbitrary provider on the internet, 
leading to massive, invisible data leakage. We try to align to the principle of 
least surprise, and requiring users in a secured environment to perform some 
manual (while automatable) tasks is preferable to exposing these risks out of 
the box to all users. 

Many users of Apache NiFi are deploying to large enterprise environments using 
the currently available tools. While we do try to simplify this process for all 
users of NiFi, if your needs are such that the current tooling is insufficient 
to manage this and your existing corporate procedures do not align with what is 
available, you may be well served in investigating commercial vendor support. 

I encourage you to share further thoughts on concrete steps to improve this 
process that do not open users up to unseen security risks, and to follow the 
Jiras discussed above for further developments in improving the behavior and 
ease-of-use of the TLS Toolkit. 


------

Example keytool output for keystore with external CA public certificate in 
chain:

...resto/Workspace/scratch/certs/externalCA (master) 😉
🔒 3s @ 19:01:57 $ keytool -list -v -keystore 
intermediate_signed.nifi.apache.org/keystore.jks
Enter keystore password:

Keystore type: jks
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: nifi-key
Creation date: Aug 2, 2018
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=intermediate_signed.nifi.apache.org, OU=NIFI
Issuer: CN=Intermediate CA
Serial number: 164fd79074700000000
Valid from: Thu Aug 02 18:48:44 PDT 2018 until: Sun Aug 01 18:48:44 PDT 2021
Certificate fingerprints:
         MD5:  BA:0F:14:50:71:7A:DD:D3:10:CD:DA:B8:09:2A:6D:FE
         SHA1: EE:D6:76:25:68:64:45:ED:74:21:9C:20:7B:05:13:C0:7A:BB:A3:E9
         SHA256: 
C2:EA:C4:EC:B4:2D:13:E6:86:0D:E7:4D:48:B8:98:E1:18:2B:AB:3D:F1:0E:AD:58:CE:3D:AC:C1:83:31:9F:2B
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3

Extensions:
...

#5: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  DNSName: intermediate_signed.nifi.apache.org
]
...

Certificate[2]:
Owner: CN=Intermediate CA
Issuer: CN=Root CA
Serial number: 164fd68928600000000
Valid from: Thu Aug 02 18:30:46 PDT 2018 until: Fri Aug 03 18:30:46 PDT 2018
Certificate fingerprints:
         MD5:  85:70:4E:B4:CB:FC:E7:89:DE:13:36:6E:B0:A0:74:51
         SHA1: 09:6B:94:51:DA:BD:75:6E:35:EC:E4:5A:ED:6B:D0:BA:A4:69:58:82
         SHA256: 
D7:67:4F:3A:4F:40:7B:D2:1A:E5:A2:84:39:19:15:73:84:13:43:E2:46:3E:2A:52:2E:74:06:65:B6:79:CE:84
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
...


*******************************************

[1] https://issues.apache.org/jira/browse/NIFI-5462
[2] https://issues.apache.org/jira/browse/NIFI-5458 
<https://issues.apache.org/jira/browse/NIFI-5458>
[3] 
https://nifi.apache.org/docs/nifi-docs/html/administration-guide.html#standalone
 
<https://nifi.apache.org/docs/nifi-docs/html/administration-guide.html#standalone>
[4] 
https://nifi.apache.org/docs/nifi-docs/html/administration-guide.html#using-an-existing-intermediate-certificate-authority-ca
[5] 
https://nifi.apache.org/docs/nifi-docs/html/administration-guide.html#signing-with-externally-signed-ca-certificates
 
<https://nifi.apache.org/docs/nifi-docs/html/administration-guide.html#signing-with-externally-signed-ca-certificates>
[6] 
https://github.com/apache/nifi/tree/master/nifi-toolkit/nifi-toolkit-cli#security-configuration
 
<https://github.com/apache/nifi/tree/master/nifi-toolkit/nifi-toolkit-cli#security-configuration>
[7] https://www.google.com/search?q=PKIX+path+building+failed+nifi
[8] https://issues.apache.org/jira/browse/NIFI-5460 
<https://issues.apache.org/jira/browse/NIFI-5460>


Andy LoPresto
alopre...@apache.org
alopresto.apa...@gmail.com
PGP Fingerprint: 70EC B3E5 98A6 5A3F D3C4  BACE 3C6E F65B 2F7D EF69

> On Feb 8, 2019, at 8:56 AM, Erik Anderson <eand...@pobox.com> wrote:
> 
> I am not sure if this is a NiFi dev or NiFi user question. Seems more dev 
> based
> 
> Short Version:
> When running the NiFi toolkit ../bin/tls-toolkit.sh server, how do I get the 
> server to include an additional public certificate of authority in the 
> returned truststore.jks file (../bin/tls-toolkit.sh client calls)
> 
> Long version:
> When running tls-toolkit.sh as the CA for NiFi instances
> ../bin/tls-toolkit.sh server -D "CN=nifi-ca.blah.blah.bloomberg.com, OU=NIFI" 
> -t mysupersecrettoken-p 8443 -d 1826
> 
> And I call the CA to request a 
> /bb/nifi-toolkit/nifi-toolkit-1.7.1/bin/tls-toolkit.sh client -c 
> nifi-ca.blah.com -t mysupersecrettoken-p 8443 -D 
> "CN=nifi-myproject.blah.blah.bloomberg.com, OU=NIFI, O=Bloomberg L.P., L=New 
> York, ST=New York, C=US"
> 
> The toolkit gives me a keystore.jks
> 
> I need to get this certificate signed by an external entity so I dont have 
> issues with the browsers.
> 
> Basically I do
> keytool -certreq -alias nifi-key -file csr.txt -keystore keystore.jks
> 
> I the the certificate signing request, csr.txt, I feed it to the public 
> certificate of authority, I get a signed certificate back.
> 
> I convert the format of the certificate like so
> openssl x509 -outform der -in new_cert.pem -out new_cert.crt
> 
> Now I import the certificate back into my keystore.
> keytool -import -alias nifi-key -file new_cert.crt -keystore keystore.jks
> 
> Now I have solved the certificate warning errors in the browser when I 
> connect to the NiFi UI.
> 
> ------------
> 
> Now I want to use the NiFi cli to  to automate data flows between the 
> registry and the NiFi instances so I generate a client cert
> 2) ../bin/tls-toolkit.sh client -c nifi-ca.blah.blah.bloomberg.com -t 
> mysupersecrettoken-p 8443 -D "CN=nifi-cli, OU=NIFI" -T PKCS12
> 
> I setup nifi.prop, I also add "CN=nifi-cli, OU=NIFI" as a user to the NiFi UI
> 
> Now I call the NiFi instane as so
> ../bin/cli.sh nifi pg-list -verbose -p 
> /bb/nifi-toolkit/nifi-toolkit-1.7.1/nifi.prop 
> 
> And I get this error
> org.apache.nifi.toolkit.cli.api.CommandException: Error executing command 
> 'pg-list' : sun.security.validator.ValidatorException: PKIX path building 
> failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to 
> find valid certification path to requested target
> 
> ***
> BTW, this error message and it gives you little to go on. Really sucks. Its 
> not covered in any mailing list, topics, howto, nothing. This is a massive 
> issue at an enterprise company.
> 
> Regardless I figure this out.
> ***
> 
> To fix this problem, anytime I call the
> ../bin/tls-toolkit.sh client
> 
> I need to install my own man-in-the-middle and extract the root certificate 
> like so
> 
> openssl s_client -connect nifi-myproject.blah.blah.bloomberg.com:443 
> -showcerts
> 
> Extract the root CA certificate
> 
> post modify the truststore.jks file to include the root CA certificate that 
> signed the .csr
> 
> cat > /bb/nifi-toolkit/nifi-toolkit-1.7.1/certs/digicert.crt <<EOF
> -----BEGIN CERTIFICATE-----
> MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh
> MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
> d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
> QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT
> MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg
> U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
> ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83
> nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd
> KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f
> /ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX
> kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0
> /RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C
> AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY
> aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6
> Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1
> oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD
> QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
> d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh
> xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB
> CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl
> 5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA
> 8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC
> 2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit
> c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0
> j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz
> -----END CERTIFICATE-----
> EOF
> 
> keytool -import -v -trustcacerts -alias digicert-ca -file digicert.crt 
> -keystore truststore.jks
> 
> 
> Now, finally,
> 
> ../bin/cli.sh nifi pg-list -verbose -p 
> /bb/nifi-toolkit/nifi-toolkit-1.7.1/nifi.prop 
> 
> Works! Now I am happy.
> 
> This is a mess of undocumented black magic.
> 
> I dont expect the public root CA to change.
> 
> Is there a way to simplify this process? Cant we ignore this whole chain 
> thing? Maybe include the public CA cert in the nifi-ca-keystore.jks on the 
> server running the
> ../bin/tls-toolkit.sh server
> 
> This voodoo process really is too much guys and needs to be simplified. 
> Suggestions are welcome.
> 
> Erik Anderson
> Bloomberg

Reply via email to