获取SSL:CERTIFICATE_VERIFY_FAILED将python与Apache NIFI rest api一



我有各种使用NIFI rest api进行调用的python脚本。在我的机器和其他本地机器的本地机器上,脚本可以工作。我正在尝试通过 Jenkins 运行脚本。Jenkins 在 AWS EC2 实例上运行。这些脚本不适用于 Jenkins EC2 实例,但它们将在同一 AWS 账户和安全组内的其他 EC2 实例上运行。我能够让脚本在 Jenkins EC2 实例上运行的唯一方法是对其余调用使用 (verify=False(。但是,我需要能够在没有(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"

上面的脚本不会给出任何错误,只是一个不起作用但同时在其他机器上运行的输出。

尝试:开发群集节点 1 dev-cluster-node-1 没有响应 正在尝试:开发群集节点 2 dev-cluster-node-2 没有响应 尝试:开发群集节点 3 dev-cluster-node-3 没有响应 尝试:开发注册表 开发注册表未响应 尝试:开发独立 独立开发未响应 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 代码提供签名公共证书才能启用此功能。

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

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

最新更新