Created on 01-19-2020 06:03 PM - last edited on 01-20-2020 01:22 AM by VidyaSargur
I am invoking a REST API from Nifi using InvokeHTTP processor and wanted to enable mutual certificate authentication between client (nifi) and server.
I enabled StandardRestrictedSSLContextService (controller service) as mentioned in the below screenshot and getting below exception:
InvokeHTTP[id=4a29f282-3665-3703-aab8-9e106c4aa9a4] Failed to properly initialize Processor. If still scheduled to run, NiFi will attempt to initialize and run the Processor again after the 'Administrative Yield Duration' has elapsed. Failure is due to java.lang.reflect.InvocationTargetException: java.lang.reflect.InvocationTargetException
Screenshot:
Am I missing anything, kindly please explain how to enable mutual certificate based authentication?
Created 01-20-2020 05:55 AM
@VijaySankar In a recent Use Case, I had to connect invokeHttp to an API (https) to get an S3 bucket URL and then to Amazon S3 (https) to download the file. Each InvokeHTTP required its own SSL Context Service and for each I complete the following:
Hope this helps get you going...
Created 01-21-2020 02:04 PM
Thanks @stevenmatison
As you mentioned, I have configured the InvokeHttp processor and sent a request to server and received the response.
Is there any way to verify the outgoing request has the certificate attached from Nifi side (client)?
Created 01-21-2020 02:10 PM
If it worked and you got the expected response, you can be sure the cert was used... i don’t think the cert will actually be “sent” but it is used on the Nifi side (client) to communicate “securely”... just make sure you get the expected response and not, for example, an http (not https) error page...
Created 01-22-2020 12:58 PM
Whether a client certificate is required in the TLS connection is controlled by the server side of teh connection and not by the client.
Your SSL context service must include a truststore. The truststore is required whether the TLS secured connection is using mutual authentication or 1-way TLS authentication.
The client initiates a connection to the https server. The server responds with a TLS server hello response. Among other things, the server will include its server certificate, whether a client certificate is required (client certificate must be returned), wanted (client certificate is wanted but connection will proceed even if one is not provided), or none (no client certificate requested), and a list of server side trusted CAs. If the server does require or want a client certificate, the client can only pass a certificate that is signed (issuer) is one of the trusted CAs returned in the Server Hello. If your server endpoint requires a client certificate and non is provided, the server would just close the connection since the TLS handshake failed.
The truststore used in your SSL context service on the client side must be able to trust the server certificate presented (true for mutual auth TLS or 1-way TLS). This means the truststore you use must contain the complete trust chain for the issuer of the server certificate sent by the server.
If you want to see the server hello, you can use openssl as follows:
openssl s_client -connect <server hostname>:<server port>
If you want to get the public certs for the complete trust chain from the server:
openssl s_client -connect <server hostname>:<server port> -showcerts
You can copy each public cert into a cer file and import those it to your truststore used in the SSL context service if missing.
Hope this helps,
Matt
Created 01-27-2020 12:10 PM
As mentioned in the below screenshot, I have added client cert (.jks) in keystore and server cert (.jks) in truststore. Server is expecting a client cert as part of request but when I make a rest call, client certificate is going in the request.
Here is the command that I used to generate a .jks file on top of client certificate:
keytool -importkeystore -srckeystore nifi.com.pfx -srcstoretype pkcs12 -destkeystore nifi.com.jks -deststoretype jks -srckeypass 'abcxyz' -alias data-nifi-cd
Created 01-27-2020 01:55 PM
Unfortunately with the information you have shared, it is not possible for me to validate what the issue is here.
I would need to output from the openssl commands i shared earlier to help.
openssl s_client -connect <server hostname>:<server port>
Also the verbose listing of both your keystore and truststore files would be needed:
keytool -v -list -keystore keystore.jks
keytool -v -list -keystore nifi.com.jks
The target server is what decides if connection is going to use mutual auth or not. The invokeHTTP is the client side of this connection and only provides what the server asks for in the server hello response.
It is possible also in that server hello response that the server wants a client certificate; however, the list of CAs sent in that server hello response does not contain a CA capable of trusting your clientAuth PrivateKeyEntry in your nifi.com.jks. In that case client would not send the client certificate since server is incapable of trusting it.
Matt