Skip to content

sarg3nt/cert-manager-webhook-infoblox-wapi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

83 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cert Manager Webhook for InfoBlox WAPI

OpenSSF Scorecard CodeQL trivy Release Weekly Release
Scorecard Analyzer Dependabot Updates Dependency Review


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

  • 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.

Installation

There are three steps needed to make this work.

  1. Install Cert Manager
  2. Install Infoblox Wapi Webhook (this plugin)
  3. Create Issuers

Install Cert Manager

Follow the instructions to install Cert Manager.

Install Infoblox Wapi Webhook

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.

Using the Public Helm Chart

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

From Source

Check out this repository and run the following command:

helm -n cert-manager install webhook-infoblox-wapi deploy/cert-manager-webhook-infoblox-wapi

Values

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 {}

Infoblox User Account

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.

Kubernetes Secret

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

Hostpath Volume Mount

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

Create Issuers

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.

Cluster Issuer for Let's Encrypt Staging using Secrets For the Infoblox Account

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: [email protected]
    # 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

Cluster Issuer for Let's Encrypt Production using Volume Mount For the Infoblox Account

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-production
spec:
  acme:
    email: [email protected]
    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

Issuer for Let's Encrypt Production using Volume Mount For the Infoblox Account

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: letsencrypt-production
  namespace: mesh-system
spec:
  acme:
    email: [email protected]
    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.

Issuer Webhook Configuration Options

This is the full list of webhook configuration options:

  • groupName: This must match the groupName 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)

Creating Certificates

You can create certificates either manually or via Ingress Annotations.

Manually

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

Ingress Annotations

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

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.

Building

  1. If you've made any changes to go.mod, run go mod tidy
  2. Update the Makefile with a new IMAGE_TAG if necessary.
  3. Run make build. This will use go to build the project.
  4. Run make build-container. A new Docker container will be generated and tagged as:
    $(IMAGE_NAME):$(IMAGE_TAG)-$(GIT_BRANCH) as given in the Makefile
  5. Run make push-container. This will push the above tagged image to the repo defined in the IMAGE_NAME

Contributions

If you would like to contribute to this project, please, open a PR via GitHub. Thanks.

License

This project inherits the Apache 2.0 license from https://github.com/cert-manager/webhook-example.

Modifications to files are listed in NOTICE.

Author

Luis Gracia while at The Rockefeller University, taken over by Dave Sargent:

  • dave [at] sarg3.net
  • GitHub at sarg3nt