Skip to main content
Version: v0.13.0

Securing NiFi with SSL

The NiFi operator makes securing your NiFi cluster with SSL. You may provide your own certificates, or instruct the operator to create them for from your cluster configuration.

Below this is an example configuration required to secure your cluster with SSL:

apiVersion: nifi.konpyutaika.com/v1alpha1
kind: NifiCluster
...
spec:
...
managedAdminUsers:
- identity: "alexandre.guitton@konpyutaika.com"
name: "aguitton"
...
readOnlyConfig:
# NifiProperties configuration that will be applied to the node.
nifiProperties:
webProxyHosts:
- nifistandard2.trycatchlearn.fr:8443
...
...
listenersConfig:
internalListeners:
- type: "https"
name: "https"
containerPort: 8443
- type: "cluster"
name: "cluster"
containerPort: 6007
- type: "s2s"
name: "s2s"
containerPort: 10000
sslSecrets:
tlsSecretName: "test-nifikop"
create: true
  • managedAdminUsers: list of users account which will be configured as admin into NiFi cluster, please check for more information.
  • readOnlyConfig.nifiProperties.webProxyHosts: A list of allowed HTTP Host header values to consider when NiFi is running securely and will be receiving requests to a different host[:port] than it is bound to. web-properties

If listenersConfig.sslSecrets.create is set to false, the operator will look for the secret at listenersConfig.sslSecrets.tlsSecretName and expect these values:

keyvalue
caCertThe CA certificate
caKeyThe CA private key
clientCertA client certificate (this will be used by operator for NiFI operations)
clientKeyThe private key for clientCert

Using an existing Issuer

As described in the Reference section, instead of using a self-signed certificate as CA, you can use an existing one. In order to do so, you only have to refer it into your Spec.ListenerConfig.SslSecrets.IssuerRef field.

Example: Let's encrypt

Let's say you have an existing DNS server, with external dns deployed into your cluster's namespace. You can easily use Let's encrypt as authority for your certificate.

To do this, you have to:

  1. Create an issuer:
apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
name: letsencrypt-staging
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: <your email address>
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource used to store the account's private key.
name: example-issuer-account-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
ingressTemplate:
metadata:
annotations:
"external-dns.alpha.kubernetes.io/ttl": "5"
  1. Setup External dns and correctly create your issuer into your cluster configuration:
apiVersion: nifi.konpyutaika.com/v1alpha1
kind: NifiCluster
...
spec:
...
clusterSecure: true
siteToSiteSecure: true
...
listenersConfig:
clusterDomain: <DNS zone name>
useExternalDNS: true
...
sslSecrets:
tlsSecretName: "test-nifikop"
create: true
issuerRef:
name: letsencrypt-staging
kind: Issuer

Create SSL credentials

You may use NifiUser resource to create new certificates for your applications, allowing them to query your Nifi cluster.

To create a new client you will need to generate new certificates sign by the CA. The operator can automate this for you using the NifiUser CRD:

cat << EOF | kubectl apply -n nifi -f -
apiVersion: nifi.konpyutaika.com/v1alpha1
kind: NifiUser
metadata:
name: example-client
namespace: nifi
spec:
clusterRef:
name: nifi
secretName: example-client-secret
EOF

This will create a user and store its credentials in the secret example-client-secret. The secret contains these fields:

keyvalue
ca.crtThe CA certificate
tls.crtThe user certificate
tls.keyThe user private key

You can then mount these secret to your pod. Alternatively, you can write them to your local machine by running:

kubectl get secret example-client-secret -o jsonpath="{['data']['ca\.crt']}" | base64 -d > ca.crt
kubectl get secret example-client-secret -o jsonpath="{['data']['tls\.crt']}" | base64 -d > tls.crt
kubectl get secret example-client-secret -o jsonpath="{['data']['tls\.key']}" | base64 -d > tls.key

The operator can also include a Java keystore format (JKS) with your user secret if you'd like. Add includeJKS: true to the spec like shown above, and then the user-secret will gain these additional fields:

keyvalue
tls.jksThe java keystore containing both the user keys and the CA (use this for your keystore AND truststore)
pass.txtThe password to decrypt the JKS (this will be randomly generated)