Skip to content

KittyKatt/external-dns-opnsense-bind-webhook

Repository files navigation

ExternalDNS Webhook Provider for OPNsense

GitHub Release

This webhook graciously stolen from inspired by crutonjohn's OPNSense Unbound Webhook (which in turn was inspired by Kashall's Unifi Webhook).

Warning

This software is experimental and NOT FIT FOR PRODUCTION USE!

ExternalDNS is a Kubernetes add-on for automatically managing DNS records for Kubernetes ingresses and services by using different DNS providers. This webhook provider allows you to automate DNS records from your Kubernetes clusters into your OPNsense Firewall's os-bind plugin.

🗒️ Important Notes

As of this writing this webhook supports A, AAAA, TXT, and absolute FQDN CNAME records using the BIND plugin's API.

Usage of a registry is supported, though only tested with TXT type registry.

🚫 Limitations

  • As mentioned above, with CNAME records this only works when the target of our record is an absolute FQDN. Relative targets like "beep" or "beep.boop" will not work. Future work may make this possible, but right now I haven't figured out how to determine what to do with a relative target and how to handle it.
  • Wildcard CNAME records are not supported at this time. Attempting to use this provider to create them will result in the ExternalDNS process crashing. I am very welcome to PRs to figure this out.

A Note About Manually Created Records

Warning

If you don't follow this, manually entered A/AAAA/CNAME records can be permanently destroyed

Note

This only applies if you are using registry=noop with policy=sync. If you plan to use the TXT registry along with policy=sync, then this warning should not apply to you as records will be skipped if they are missing the required TXT ownership records.

If you have records that are managed manually or by some process other than this webhook and you intend for those records to share a domain, then you must use policy=upsert-only or policy=create-only with your ExternalDNS deployment. If you use policy=sync, this will attempt to reconcile the zone by deleting all A/AAAA/CNAME records not currently defined by a supported ExternalDNS source in-cluster.

A Note About TXT Registry

Warning

It is highly recommended to set a unique txtOwnerId for each ExternalDNS deployment, including this one. Not doing so will result in Bad Situations™ if you attempt to use multiple ExternalDNS providers with the same domains.

The TXT registry is supported with this provider. There is special instructions if you would like to use this provider to manage the apex records of a domain (ie the @ record for example.com in the example.com domain). If you would like to do this and use the TXT registry, it is required that you use a txtPrefix value that ends in a singular period character .. Example: reg-%{record_type}-externaldns.

Failing to do this will result in this provider crashing ExternalDNS if you attempt to create TXT registry entries for apex records due to it attempting to create TXT records like a-example.com rather than a.example.com.

⛵ Deployment

  1. Create a local user with a password in your OPNsense firewall. System > Access > Users

  2. Create an API keypair for the user you created in step 1.

  3. Create (or use an existing) group to limit your user's permissions. The known required privileges are:

  • Services: BIND
  • Status: Services
  1. Add the ExternalDNS Helm repository to your cluster.

    helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
  2. Create a Kubernetes secret called external-dns-opnsense-secret that holds api_key and api_secret with their respective values from step 1:

    apiVersion: v1
    stringData:
      api_secret: <INSERT API SECRET>
      api_key: <INSERT API KEY>
    kind: Secret
    metadata:
      name: external-dns-opnsense-secret
    type: Opaque
  3. Create the helm values file, for example external-dns-webhook-values.yaml:

    fullnameOverride: external-dns-opnsense
    logLevel: debug
    provider:
      name: webhook
      webhook:
        image:
          repository: ghcr.io/KittyKatt/external-dns-opnsense-bind-webhook
          tag: main # replace with a versioned release tag
        env:
          - name: OPNSENSE_API_SECRET
            valueFrom:
              secretKeyRef:
                name: external-dns-opnsense-secret
                key: api_secret
          - name: OPNSENSE_API_KEY
            valueFrom:
              secretKeyRef:
                name: external-dns-opnsense-secret
                key: api_key
          - name: OPNSENSE_HOST
            value: https://192.168.1.1 # replace with the address to your OPNsense router
          - name: OPNSENSE_SKIP_TLS_VERIFY
            value: "true" # optional depending on your environment
          - name: LOG_LEVEL
            value: debug
        livenessProbe:
          httpGet:
            path: /healthz
            port: http-webhook`
          initialDelaySeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          httpGet:
            path: /readyz
            port: http-webhook`
          initialDelaySeconds: 10
          timeoutSeconds: 5
    extraArgs:
      - --ignore-ingress-tls-spec
    policy: sync # can be upsert-only, create-only, or sync
    sources: ["ingress", "service", "crd"]
    registry: txt # can be noop or txt
    domainFilters: ["example.com"] # replace with your domain
    txtPrefix: reg-%{record_type}-externaldns.
    txtOwnerId: opnsense-bind
  4. Install the Helm chart

    helm install external-dns-opnsense external-dns/external-dns -f external-dns-opnsense-values yaml -n external-dns

👷 Building & Testing

Build:

go build -ldflags "-s -w -X main.Version=test -X main.Gitsha=test" ./cmd/webhook

Run:

OPNSENSE_HOST=https://192.168.0.1 OPNSENSE_API_SECRET=<secret value> OPNSENSE_API_KEY=<key value> ./webhook

🤝 Gratitude and Thanks

Thank you to @crutonjohn @kashalls for their wonderful work that allowed me to create this and get it working with minimal effort.

About

ExternalDNS webhook to manage OPNsense BIND Plugin DNS records.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors