Wednesday, March 16, 2022

[SOLVED] PKIX path building - NIFI is throwin an error when calling API via InvokeHTTP processor

Issue

I am getting the below error in NIFI when I call an API which is hosted in another server. (source and destination are Linux servers)

I need to add the server certificates in my current server to resolve this issue.

Can anyone provide the step by step commands that I need to execute to resolve this issue?

Nifi ERROR

Nifi Log:

2021-05-11 16:56:40,619 ERROR [Timer-Driven Process Thread-4] o.a.nifi.processors.standard.InvokeHTTP InvokeHTTP[id=0176115c-90fb-164a-a491-7eb6554327bc] Routing to Failure due to exception: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:327)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:270)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:265)
        at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:646)
        at sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(CertificateMessage.java:465)
        at sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(CertificateMessage.java:361)
        at sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:376)
        at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:451)
        at sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:428)
        at sun.security.ssl.TransportContext.dispatch(TransportContext.java:184)
        at sun.security.ssl.SSLTransport.decode(SSLTransport.java:154)
        at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1198)
        at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1107)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:400)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:372)
        at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:281)
        at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:251)
        at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:151)
        at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:195)
        at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)
        at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)
        at okhttp3.RealCall.execute(RealCall.java:69)
        at org.apache.nifi.processors.standard.InvokeHTTP.onTrigger(InvokeHTTP.java:850)
        at org.apache.nifi.processor.AbstractProcessor.onTrigger(AbstractProcessor.java:27)
        at org.apache.nifi.controller.StandardProcessorNode.onTrigger(StandardProcessorNode.java:1174)
        at org.apache.nifi.controller.tasks.ConnectableTask.invoke(ConnectableTask.java:213)
        at org.apache.nifi.controller.scheduling.TimerDrivenSchedulingAgent$1.run(TimerDrivenSchedulingAgent.java:117)
        at org.apache.nifi.engine.FlowEngine$2.run(FlowEngine.java:110)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:439)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306)
        at sun.security.validator.Validator.validate(Validator.java:271)
        at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:312)
        at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:221)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:128)
        at sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkServerCerts(CertificateMessage.java:630)
        ... 43 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434)
        ... 49 common frames omitted

Solution

The InvokeHTTP in NiFi is a client of your API. This means that the InvokeHTTP needs to be able to trust your remote server to ensure it's not connecting to a malicious service. To do this, we need to add the Certificate Authority/Root Authority of the remote service to InvokeHTTP's truststore. The CA required will be shown in the 'Issuer' fields of the service's server certificate.

To get the CA, you can follow this blog: https://daniel.haxx.se/blog/2018/11/07/get-the-ca-cert-for-curl/, and retrieve the CA into a pem file with:

echo quit | openssl s_client -showcerts -servername server -connect server:443 > cacert.pem

Then, you can use Keystore Explorer (https://keystore-explorer.org) to create a new truststore file (which is a much easier way to manage key/truststores), and import the certificate cacert.pem into this truststore.

You then configure an SSL Context Service in the InvokeHTTP processor, which references the truststore you created.



Answered By - returntosender404
Answer Checked By - David Marino (WPSolving Volunteer)