【问题标题】:Getting SSL: CERTIFICATE_VERIFY_FAILED when using python with Apache NIFI rest api获取 SSL:将 python 与 Apache NIFI rest api 一起使用时出现 CERTIFICATE_VERIFY_FAILED
【发布时间】:2020-10-02 09:54:31
【问题描述】:

我有各种使用 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"

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

正在尝试: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-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)'),))*

【问题讨论】:

    标签: python amazon-web-services ssl jenkins apache-nifi


    【解决方案1】:

    我认为问题在于您的脚本不知道您的 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 代码提供签名公共证书才能启用此功能。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多