繁体   English   中英

Getting SSL: CERTIFICATE_VERIFY_FAILED when using python with Apache NIFI rest api

[英]Getting SSL: CERTIFICATE_VERIFY_FAILED when using python with Apache NIFI rest api

我有各种 python 脚本,它们使用 NIFI rest api 进行一些调用。 在我的机器和其他本地机器的本地脚本工作。 我正在尝试通过 Jenkins 运行脚本。 Jenkins 在 AWS EC2 实例上运行。 这些脚本不适用于 Jenkins EC2 实例,但它们将适用于同一 AWS 账户和安全组中的其他 EC2 实例。 我能够让脚本在 Jenkins EC2 实例上运行的唯一方法是使用 (verify=False) 进行 rest 调用。 但是,鉴于我需要进行的某些 rest 调用无法使用它,我需要能够在没有 (verify=False) 的情况下使其在 Jenkins 上工作。

我使用的证书是从我们用于 NIFI 的 p12 文件生成的两个 pem 文件。 证书在其他任何地方都可以使用,所以我认为这不是他们的问题。 我也尝试了各种 Python 版本,但我仍然得到相同的结果,所以我也不认为是这样。 我为端口 22、8443、18443、443、9999、8080、18080 打开了 Jenkins 服务器的公共和私有 ip 地址。所以我也不认为这是一个端口问题。 我对 SSL 没有太多经验,所以我不知道接下来要尝试什么。 但鉴于它在本地工作并在 AWS EC2 实例上工作,我们正在运行 NIFI 开发版本,我没有想法。

Python 脚本(其他脚本有相同的问题和类似的结构):

import json, requests, sys

with open("jenkinsCerts.dat") as props:
certData = json.load(props)
cert = (certData["crt"],certData["key"])

 def makeRestGetCall(url):
#calls a RESTful url and returns the response in json format
if "https" in url:
    response = requests.get(url, cert=cert)
else:
    response = requests.get(url)
print response

with open('servers.txt') as nifi_server_list:
errorCount=0
data = json.load(nifi_server_list)

for server in data:
    try:
        print "trying: "+server["name"]+" ("+server["url"]+")"
        makeRestGetCall(server["url"], verify=False)
    except:
        print server["name"]+" ("+server["url"]+") did not respond"
        errorCount = errorCount + 1
try:
    assert errorCount==0
except AssertionError:
    print errorCount, " servers did not respond"

上面的脚本没有给出任何错误,只是一个 output 不工作但同时在其他机器上工作。

尝试:dev-cluster-node-1 dev-cluster-node-1 没有响应 尝试:dev-cluster-node-2 dev-cluster-node-2 没有响应 尝试:dev-cluster-node-3 dev-cluster -node-3 没有响应尝试:dev-registry dev-registry 没有响应尝试:dev-standalone dev-standalone 没有响应 5 服务器没有响应

这是我从 Jenkins 得到的错误,当我运行一个不同的 Python 脚本时,该脚本使用与上面相同的身份验证,但完整的脚本太长而无法复制并且没有必要:

*requests.exceptions.SSLError: HTTPSConnectionPool(host='ec2-***-***-***.****-1.compute.amazonaws.com', port=8443): Max retries exceeded with url: /nifi-api/flow/process-groups/3856c256-017-****-***** (Caused by SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:727)'),))*

我认为问题在于您的脚本不知道您的 NiFi 服务器的预期公共证书,以便在请求期间验证它们。

您提供的crtkey值应包含 Python 脚本的公共证书私钥,以便对 NiFi 服务器进行身份验证。 在这种情况下,此材料标识客户端,这是相互身份验证 TLS (NiFi 支持的各种身份验证机制之一)所必需的。

但是,对于所有 TLS 握手,服务器还必须提供标识自己的公共证书以及与服务连接的主机名匹配的 CN 或 SAN(例如,如果您访问https://stackoverflow.com ,则该网站需要出示已颁发的证书对于stackoverflow.com ,而不是andys-fake-stackoverflow.com )。

公共互联网上的大多数网站的证书都由证书颁发机构(Let's Encrypt、Comodo、Verisign 等)签名 您的浏览器和许多软件组件都带有这些可信 CA 的集合,以便 TLS 连接开箱即用。 但是,如果您的 NiFi 服务器使用的证书未由这些 CA 之一签名,则默认 Python 列表将不包含其签名者,因此将无法验证这些 NiFi 证书。 您需要向 Python 代码提供签名公共证书以启用此功能。

requests 模块允许您使用签署 NiFi 证书的公共证书配置自定义 CA 捆绑路径。 您可以通过多种方式获得它(您可以直接访问 NiFi 服务器,但任何连接 [通过浏览器, openssl s_clientcurl等] 将允许您获得公共证书链)。 将公共证书 ( nifi_ca.pem ) 以 PEM 格式存储在 Python 脚本的文件夹结构中,并像这样引用它:

response = requests.get(url, cert=cert, verify="nifi_ca.pem")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM