Overview
Securing your Ignition gateway is an important step to a proper deployment. This involves setting up TLS certificates for both the Ignition Web Server and the Gateway Network. We've touched briefly on how to leverage cert-manager integration for configuring redundancy. This section will cover additional aspects of securing your Ignition Gateway deployment using cert-manager.
Ignition Helm Chart and cert-manager​
The integration with cert-manager is enabled by setting certManager.enabled=true
. There are four separate configuration aspects that relate to Ignition:
- Gateway Network Issuer -
certManager.ganIssuer
- Gateway Network Certificate -
certManager.ganCertificate
- Web Server Issuer -
certManager.tlsIssuer
- Web Server Certificate -
certManager.tlsCertificate
The default configuration will create cert-manager Issuer
resources and generate self-signed certificates. The TLS issuer and certificate is only rendered if you've enabled TLS for the Ignition Gateway. You can customize many aspects of both the issuers and the resultant certificates. In the following sections, we'll dive a little deeper on how to enable and customize the system.
Setting up Web Server TLS​
To enable the creation of a web server TLS certificate, use the following values:
# testing.yaml
gateway:
tls:
enabled: true
certManager:
enabled: true
ingress:
tls:
enabled: true
This configuration will setup the following:
Issuer
(and backing self-signedCertificate
) for issuing TLS certificates.Certificate
for the Ignition web server.- Ignition startup automation to prepare the PKCS12 keystore accordingly.
Enabling certificate rotation​
When you use cert-manager to manage your certificates, they'll automatically be renewed when necessary with the corresponding Secret
resource dynamically updated. However, since Ignition requires additional PKCS12 keystore preparations, a separate CronJob
must be defined to rotate in the new certificate on the desired schedule. You can activate this by setting certManager.tlsCertificate.rotationEnabled=true
.
# testing.yaml
# ...
certManager:
tlsCertificate:
rotationEnabled: true
# -- Configure the frequency for cert rotation, defaults to once a day at 7am.
rotationFrequency: "0 7 * * *"
With this in place, any updates to the underlying TLS secret will be rotated into the PKCS12 keystore that Ignition uses for its web server TLS certificate. Ignition will re-read this keystore every 15 minutes.
Setting up Gateway Network TLS​
The Gateway Network is used for establishing communication between Ignition Gateways. It is the principal channel for Ignition Redundancy among other services. In this section, we'll go into more depth than the brief introduction in the previous section on redundancy.
Customizing the Gateway Network Certificate​
To customize aspects of the applied Gateway Network certificate, you can modify certManager.ganCertificate
:
# testing.yaml
certManager:
enabled: true
ganCertificate:
spec:
commonNameOverride: "ignition.demo.svc.cluster.local"
dnsNames:
- "ignition.demo.svc.cluster.local"
duration: "17520h" # 2 years
## ...
If you apply changes to the Gateway Network certificate to an existing release, the certificate will not take effect immediately. It will be applied at either the next pod restart or rotation event (when enabled)
Using an external issuer​
If you have an external cert-manager issuer that you'd like to use, you can configure the Gateway Network issuer with the appropriate reference, but set certManager.ganIssuer.create=false
.
# testing.yaml
certManager:
enabled: true
ganIssuer:
create: false
kind: "ClusterIssuer"
group: "cert-manager.io"
nameOverride: "my-external-issuer"
ganCertificate:
# ...
In the example above, an external ClusterIssuer is referenced. Typically, this will mean that the associated secret for this issuer is in a different namespace (i.e. cert-manager
, typically). The Ignition pod will attempt to bind to a secret named my-external-issuer
to establish a trust anchor for that issuer using its public tls.crt
certificate. You may notice the Ignition pod stuck in Init:0/1
state, waiting on being able to bind to that secret.
You may need to leverage a separate tool to synchronize that secret into the namespace where you're deploying Ignition. You only need the tls.crt
key that represents the CA's public certificate.
You should avoid synchronizing the entire secret that could contain the CA's private key. While Ignition doesn't mount the private key, having the full Secret in other namespaces outside of cert-manager could compromises the integrity of the CA.
Sharing a namespaced issuer​
If you're deploying multiple releases of the Ignition Helm Chart as part of a broader architecture, you can benefit from sharing a Gateway Network issuer among the Ignition Gateways to leverage automated connectivity between them.
A suggested pattern is to have one release be responsible for creating the GAN issuer with a shared name, and having the other releases reference it. In the examples below, we'll define two sets of values overrides files, backend.yaml
for a backend redundant pair, and frontend.yaml
for a scale-out frontend set of Ignition Gateways.
# backend.yaml
certManager:
enabled: true
ganIssuer:
nameOverride: "shared-gan-issuer"
# frontend.yaml
gateway:
gan:
outgoingConnections:
- host: "backend-ignition"
certManager:
enabled: true
ganIssuer:
create: false
nameOverride: "shared-gan-issuer"
Let's install these individual releases (make sure to include auto-commissioning values if applicable, they're omitted above for brevity):
$ helm upgrade --install backend inductiveautomation/ignition --values backend.yaml
# ...
$ helm upgrade --install frontend inductiveautomation/ignition --values frontend.yaml
The result is a backend/frontend set of Ignition Gateways that have out-of-box Gateway Network connectivity using certificates issued by their shared (and trusted) issuer. 😎
In the example above, we're also establishing an outgoing Gateway Network connection using the hostname "backend-ignition" which resolves to our headless ClusterIP service and ultimately the IP of the backend Ignition pod. See Kubernetes DNS for Services and Pods for some insights into DNS resolution in K8s.