问题
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: .
回答1:
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).
来源:https://stackoverflow.com/questions/62695524/nifi-how-to-make-listenhttp-work-with-ssl