Nifi:如何使 ListenHTTP 与 SSL 配合使用 [英] Nifi: how to make ListenHTTP work with SSL
问题描述
目标
由于 Nifi 通过 HTTP 与其他工具集成,我必须让 ListenHTTP
处理器面向公众.所有 3 个环境中的 API 网关对我来说都太贵了.因此,我关闭了外部网络的所有 VM 入口端口(除了 ListenHTTP
所需的端口).
问题
我使用 StandardRestrictedSSLContextService
对 ListenHTTP
的配置不起作用.没有 SSL 也能工作,但不安全.
user$ curl -X POST -H "Content-Type: application/json";--数据测试"https://localhost:7070/test% Total % Received % Xferd Average Speed Time Time Time Current下载上传总花费的剩余速度0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (60) SSL 证书问题:自签名证书更多细节在这里:https://curl.haxx.se/docs/sslcerts.htmlcurl 未能验证服务器的合法性,因此无法与其建立安全连接.要了解有关这种情况的更多信息和如何修复,请访问上述网页......user$ curl -X POST -H "Content-Type: application/json";--数据测试"--cacert cacerts.jks https://localhost:7070/testcurl: (77) 错误设置证书验证位置:CA文件:cacerts.jksCApath:无
问题
如何使 ListenHTTP
使用 SSL 证书?我做错了什么?
更详细的问题:
- 我应该将 cacerts.jsk 复制到我发出查询的机器上吗?据我了解,
StandardRestrictedSSLContextService
将验证客户端是否在 TrustStore 中拥有证书. - 如果我只需要使用
ListenHTTP
处理器保护单个端口 - 那么我不需要 .
您正在使用的 SSLContextService
可能不包含由可公开访问的证书颁发机构 (CA) 签署的证书喜欢(仅用于解释目的;不认可)Comodo、Verisign、Let's Encrypt 等
由这些 CA 签署的证书通常会被任意客户端自动信任,因为无论构建客户端的人(Java、Google/Microsoft/Mozilla/Apple 用于浏览器,Microsoft/Apple/Linux Distro 用于操作系统)都预先包含了那些顶级证书——客户端 truststore 中的级别公共证书.您创建的信任库 cacerts.jks
是 Java Keystore 格式,curl
碰巧无法理解.您可以使用 此处的命令,但这只会解决允许 curl
与任意信任库连接的直接问题.
如果您希望通用外部客户端能够通过 TLS 进行连接,您需要使用 NiFi 密钥库中的证书,该证书由知名 CA 签署.您可以为此使用任何商业 CA,但 Let's Encrypt 确实免费提供此服务,并且使用非常广泛.使用由 CA 签署的证书后,任何*客户端都可以连接.
如果这仅供内部/企业使用,并且所有允许的客户端都由您控制,那么您可以使用自签名证书(就像现在按照 Simon 的说明进行操作),并将公共证书导出到您的其他客户端需要的任何格式才能与此特定服务器建立信任.从理论上讲,您还可以强制每个尝试连接的客户端还需要提供一个服务器 (NiFi) 可以验证的证书——这称为相互验证 TLS 和添加了另一层安全性,因为只有经过身份验证的客户端才能向此服务器发出请求.如果您选择这样做,那么 ListenHTTP
中的 SSLContextService
也需要一个信任库组件.
在不知道您的具体情况的情况下,我强烈推荐选项 1(签名证书).
Objective
Because of Nifi integration with other tools through HTTP, I have to make ListenHTTP
processor public facing. API Gateway on all 3 environments is too expensive for me. So I closed all VM ingress ports (except the one needed for ListenHTTP
) for outer networks.
Issue
My configuration of ListenHTTP
with StandardRestrictedSSLContextService
doesn't work. Without SSL it worked, but was unsecure.
user$ curl -X POST -H "Content-Type: application/json" --data "test" https://localhost:7070/test
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
.....
user$ curl -X POST -H "Content-Type: application/json" --data "test" --cacert cacerts.jks https://localhost:7070/test
curl: (77) error setting certificate verify locations:
CAfile: cacerts.jks
CApath: none
Question
How to make ListenHTTP
work with SSL certificates? What am I doing wrong?
More detailed questions:
- Should I copy cacerts.jsk to the machine from which I issue the query? As far as I understand,
StandardRestrictedSSLContextService
will verify if the client has certificate in TrustStore. - If I need to protect only a single port with
ListenHTTP
processor - then I don't need nifi.security.needClientAuth property or all environment variables defined at "Standalone Instance, Two-Way SSL" section, right? I'm little bit confused because both Docker Image andStandardRestrictedSSLContextService
contains the same configs, i.e. KEYSTORE_TYPE.
Already done
- I have a general idea about KeyStore & TrustStore from this question and the documentation.
- I have launched Nifi Docker container v1.10.0 with up & running
ListenHTTP
processor on 7070 port. - I have created keystore.jks and cacerts.jks files due to the instruction inside Nifi container.
- I have configured
ListenHTTP
to useStandardRestrictedSSLContextService
controller with the following configs: .
The SSLContextService
you're using probably doesn't contain a certificate which is signed by a publicly-accessible certificate authority (CA) like (for explanation purposes only; not endorsement) Comodo, Verisign, Let's Encrypt, etc.
Certificates signed by those CAs are generally trusted automatically by arbitrary clients because whoever builds the client (Java, Google/Microsoft/Mozilla/Apple for a browser, Microsoft/Apple/Linux Distro for the OS) has preemptively included those top-level public certs in the truststore of the client. The truststore you created cacerts.jks
is in Java Keystore format, which curl
doesn't happen to understand. You can export the public certificate from that keystore to a standalone file in PEM format using the commands here, but that will only solve the immediate problem of allowing curl
with an arbitrary truststore to connect.
If you want generic external clients to be able to connect over TLS, you'll need to use a certificate in NiFi's keystore that is signed by a well-known CA. You can use any commercial CA for this purpose, but Let's Encrypt does offer this service for free and is very widely used. Once you are using a certificate signed by a CA, any* client will be able to connect.
If this is for internal/enterprise use only, and all allowed clients are controllable by you, then you can use a self-signed certificate (like you are doing now if you followed Simon's instructions), and export the public certificate to whatever format your other clients need in order to establish trust with this particular server. Theoretically, you could also enforce that each client attempting to connect also needs to present a certificate that the server (NiFi) can verify -- this is called mutual-authentication TLS and adds another layer of security because only authenticated clients will be able to make requests to this server. If you choose to do so, that's when the SSLContextService
in ListenHTTP
would need a truststore component as well.
Without knowing your explicit situation, I would heavily recommend option 1 (the signed cert).
这篇关于Nifi:如何使 ListenHTTP 与 SSL 配合使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!