PKIX 路径构建 - NIFI 在通过 InvokeHTTP 处理器调用 API 时抛出错误

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

当我调用托管在另一台服务器上的 API 时,我在 NIFI 中收到以下错误。 (源和目标是 Linux 个服务器)

我需要在当前服务器中添加服务器证书才能解决此问题。

任何人都可以提供我需要执行的分步命令来解决这个问题吗?

尼菲日志:

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.run(TimerDrivenSchedulingAgent.java:117)
        at org.apache.nifi.engine.FlowEngine.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.access1(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

NiFi 中的 InvokeHTTP 是您 API 的客户端。这意味着 InvokeHTTP 需要能够信任您的远程服务器以确保它没有连接到恶意服务。为此,我们需要将远程服务的 Certificate Authority/Root Authority 添加到 InvokeHTTP 的信任库中。所需的 CA 将显示在服务服务器证书的 'Issuer' 字段中。

要获取 CA,您可以关注此博客:https://daniel.haxx.se/blog/2018/11/07/get-the-ca-cert-for-curl/,并将 CA 检索到 pem 文件中:

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

然后,您可以使用 Keystore Explorer (https://keystore-explorer.org) 创建一个新的信任库文件(这是一种更容易管理的方法 key/truststores),并导入证书 cacert.pem进入这个信任库。

然后您在 InvokeHTTP 处理器中配置一个 SSL 上下文服务,它引用您创建的信任库。

我尝试按照以下步骤操作。并重新启动 NIFI 实例。它开始工作了。

1. echo -n | openssl s_client -connect <server name>:<port> |sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/examplecert.crt

2. keytool -import -trustcacerts -keystore /apps/java/jdk1.8.0_211-amd64/jre/lib/security/cacerts  -storepass changeit -noprompt -alias mito -file /tmp/examplecert.crt