An InfoBlox WAPI webhook for cert-manager.
This project provides a custom ACME DNS01 Challenge Provider as a webhook for Cert Manager. This webhook integrates Cert Manager with InfoBlox WAPI via its REST API. You can learn more about WAPI in this PDF.
This implementation is based on the infoblox-go-client library.
This project is a fork of https://github.com/luisico/cert-manager-webhook-infoblox-wapi, which was forked from https://github.com/cert-manager/webhook-example.
- Requirements
- Installation
- Building
- Contributions
- License
- Author
- InfoBlox GRID installation with WAPI 2.5 or above
- helm v3
- kubernetes 1.21+
- cert-manager 1.5+
Note
Other versions might work, but have not been tested.
There are three steps needed to make this work.
- Install Cert Manager
- Install Infoblox Wapi Webhook (this plugin)
- Create Issuers
Follow the instructions to install Cert Manager.
At a minimum you will need to customize groupName
with your own group name. See deploy/cert-manager-webhook-infoblox-wapi/values.yaml for an in-depth explanation and other values that might require tweaking. With either method below, follow helm instructions to customize your deployment.
Docker images are stored in GitHub's ghcr.io registry, specifically at ghcr.io/sarg3nt/cert-manager-webhook-infoblox-wapi.
helm repo add cert-manager-webhook-infoblox-wapi https://sarg3nt.github.io/cert-manager-webhook-infoblox-wapi
# The values file below is optional, if you don't need it you can remove that line.
helm -n cert-manager install \
cert-manager-webhook \
cert-manager-webhook-infoblox-wapi/cert-manager-webhook-infoblox-wapi \
-f cert-manager-infoblox-values.yaml
Check out this repository and run the following command:
helm -n cert-manager install webhook-infoblox-wapi deploy/cert-manager-webhook-infoblox-wapi
Name | Description | Value |
---|---|---|
nameOverride | String to partially override chart name. | "" |
fullNameOverride | String to fully override chart fullname. | "" |
groupName | The GroupName here is used to identify your company or business unit that created this webhook. This name will need to be referenced in each Issuer's webhook stanza to inform cert-manager of where to send ChallengePayload resources in order to solve the DNS01 challenge. This group name should be unique, hence using your own company's domain here is recommended. |
acme.mycompany.com |
certManager.namespace | Namespace where cert-manager is deployed. | cert-manager |
certManager.serviceAccountName | Service account name of cert-manager. | cert-manager |
rootCACertificate.duration | Duration of root CA certificate | 43800h |
servingCertificate.duration | Duration of serving certificate | 8760h |
image.repository | Deployment image repository | ghcr.io/sarg3nt/cert-manager-webhook-infoblox-wapi |
image.tag | Deployment image tag | 1.5 |
image.pullPolicy | Image pull policy | IfNotPresent |
secretVolume.hostPath | Location of a secrets file on the host file system to use instead of a Kubernetes secret | /etc/secrets/secrets.json |
service.type | Service type to expose | ClusterIP |
service.port | Service port to expose | 443 |
resources | Deployment resource limits | {} |
nodeSelector | Deployment node selector object | {} |
tolerations | Deployment tolerations | [] |
affinity | Deployment affinity | {} |
A user account with the ability to create TXT records in the required domain is needed.
We support two ways of loading this service account.
The first method is to create a Kubernetes secret that include the Infoblox users username
and password
.
apiVersion: v1
kind: Secret
metadata:
name: infoblox-credentials
namespace: cert-manager
type: Opaque
data:
username: dXNlcm5hbWUK # base64 encoded: "username"
password: cGFzc3dvcmQK # base64 encoded: "password"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: webhook-infoblox-wapi:secret-reader
namespace: cert-manager
rules:
- apiGroups: [""]
resources:
- secrets
resourceNames:
- infoblox-credentials
verbs:
- get
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: webhook-infoblox-wapi:secret-reader
namespace: cert-manager
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: webhook-infoblox-wapi:secret-reader
subjects:
- apiGroup: ""
kind: ServiceAccount
name: cert-manager-webhook-cert-manager-webhook-infoblox-wapi
namespace: cert-manager
Then create a ClusterIssuer
with the following in the config
section.
See Issuer Examples
usernameSecretRef:
name: infoblox-credentials
key: username
passwordSecretRef:
name: infoblox-credentials
key: password
The second method is to create a file on the hosts file system that contains the username
and password
.
This file must be created in the path given in secretVolume.hostPath
in the Helm chart's values.yaml
file. Default location is /etc/secrets/secrets.json
.
Example: The values must be base64 encoded.
{
"username": "dXNlcm5hbWUK",
"password": "cGFzc3dvcmQK"
}
Then create a ClusterIssuer
with the following in the config
section.
See Create Issuers
getUserFromVolume: true
An issuer is the method that Cert Manager will use to request a certificate and the configuration Let's Encrypt will use to validate that the requester (you) owns the domain the certificate request is for.
The part of an issuer that defines the use of this webhook plugin starts in the webhook
section as shown in the examples below.
All settings under config
are specific to this plugin. See the list of Issuer Webhook Configuration Options below.
See: Cert Manager Issuers in the official Cert Manager documentation for more information.
There are two different kinds of issuers:
Issuer
is for a specific namespace.ClusterIssuer
is for an entire cluster and is most often used.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
# The email matching the account that your Lets Encrypt account key was created in.
email: your.email@example.com
# What Lets Encrypt server to use. This one is for staging certificates during development.
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-account-key
solvers:
- dns01:
webhook:
# groupName must match the groupName you set while installing this plugin via the Helm chart.
groupName: acme.mycompany.com
solverName: infoblox-wapi
config:
host: my-infoblox.company.com # required
view: "InfoBlox View" # required
usernameSecretRef:
name: infoblox-credentials
key: username
passwordSecretRef:
name: infoblox-credentials
key: password
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-production
spec:
acme:
email: your.email@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-account-key
solvers:
- dns01:
webhook:
groupName: acme.mycompany.com
solverName: infoblox-wapi
config:
host: my-infoblox.company.com
view: "InfoBlox View"
getUserFromVolume: true
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-production
namespace: mesh-system
spec:
acme:
email: your.email@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-account-key
solvers:
- dns01:
webhook:
groupName: acme.mycompany.com
solverName: infoblox-wapi
config:
host: my-infoblox.company.com
view: "InfoBlox View"
getUserFromVolume: true
Note
You can create more than one ClusterIssuer
. For example, one for Let's Encrypt staging and one for Let's Encrypt production. You can then reference which one you want to use when creating a cert or annotating an ingress. See below for examples.
This is the full list of webhook configuration options:
groupName
: This must match thegroupName
you specified in the Helm chart config during install.host
: FQDN or IP address of the InfoBlox server.view
: DNS View in the InfoBlox server to manipulate TXT records in.usernameSecretRef
: Reference to the secret name holding the username for the InfoBlox server (optional if getUserFromVolume is true)passwordSecretRef
: Reference to the secret name holding the password for the InfoBlox server (optional if getUserFromVolume is true)getUserFromVolume: true
: Get the Infoblox user from the host file system. (default: false)port
: Port of the InfoBlox server (default: 443).version
: Version of the InfoBlox server (default: 2.10).sslVerify
: Verify SSL connection (default: false).httpRequestTimeout
: Timeout for HTTP request to the InfoBlox server, in seconds (default: 60).httpPoolConnections
: Maximum number of connections to the InfoBlox server (default: 10).ttl
: The time to live of the TXT record. (default: 90)useTtl
: Whether or not to use the ttl. (default: true)
You can create certificates either manually or via Ingress Annotations.
Now you can create a certificate, for example:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: infoblox-wapi-test
namespace: cert-manager
spec:
commonName: example.com
dnsNames:
- example.com
issuerRef:
# The name of the issuer created above.
name: letsencrypt-production
kind: ClusterIssuer
secretName: infoblox-wapi-test-tls
If you are using Nginx Ingress you can add an annotation and Let's Encrypt will automatically create a certificate for you.
See: Cert Manager Annotated Ingress resource
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# Use the default issuer:
kubernetes.io/tls-acme: "true"
# OR Use a specific issuer:
cert-manager.io/cluster-issuer: letsencrypt-staging
# Rest of normal ingress config goes here.
Note
To use kubernetes.io/tls-acme: "true"
, a defaultIssuerName
must be set.
See: Setting Default Issuer in Let's Encrypt
When deploying the Let's Encrypt Helm chart you can set a default issuer with the following config.
ingressShim:
defaultIssuerName: "letsencrypt-production"
Once this is done you can then use the kubernetes.io/tls-acme: "true"
annotation and the default issuer will be used.
- If you've made any changes to
go.mod
, rungo mod tidy
- Update the
Makefile
with a newIMAGE_TAG
if necessary. - Run
make build
. This will usego
to build the project. - Run
make build-container
. A new Docker container will be generated and tagged as:
$(IMAGE_NAME):$(IMAGE_TAG)-$(GIT_BRANCH)
as given in theMakefile
- Run
make push-container
. This will push the above tagged image to the repo defined in theIMAGE_NAME
If you would like to contribute to this project, please, open a PR via GitHub. Thanks.
This project inherits the Apache 2.0 license from https://github.com/cert-manager/webhook-example.
Modifications to files are listed in NOTICE.
Luis Gracia while at The Rockefeller University, taken over by Dave Sargent:
- dave [at] sarg3.net
- GitHub at sarg3nt