How to set up Dynamic DNS on FreeIPA for your Kubernetes Cluster
I have a FreeIPA server that serves DNS on my home network. I wanted to automatically configure it with my Kubernetes ingresses using ExternalDNS. There doesn’t seem to be much documentation for this specific setup, so I thought to put together this guide!
Requirements
This guide will assume that you have the following set up already:
- A Kubernetes cluster running on your network
- A FreeIPA server (let’s say
ipa0.p.astrid.tech
) serving DNS for a certain zone you want as the domain suffixes (call its.astrid.tech
) - An app (or apps) on the Kubernetes cluster exposed on an Ingress (we’ll assume
it’s
firefly.s.astrid.tech
)
In addition, I used the following guides to assemble this guide:
- FreeIPA - Howto/ISC DHCPd and Dynamic DNS update
- FreeIPA - Howto/DNS updates and zone transfers with TSIG
- Flylib.com - Allowing Dynamic Updates
- ExternalDNS - Configuring RFC2136 provider
- bitnami/external-dns Helm chart
1. Generate a TSIG key and register it
We will need to generate a TSIG key first.
Choose a name for your key. I called mine k8s
but we’ll call it keyname
.
Then on your FreeIPA server, execute
$ dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST keyname
and you will get 2 files in your working directory that are probably called
something like Kkeyname.+165+44840.key
and Kkeyname.+165+44840.private
. Open
up the .private
one:
$ cat Kkeyname.+165+44840.private
Private-key-format: v1.3
Algorithm: 165 (HMAC_SHA512)
Key: zeOLcYcv/95yZX1KSLDreZyMtAsy5Ci5xwC9gW7XAgtOnOTIJpyr03CNDA8sUxfrkhb6Hjs90d3zRGm2g0XDaQ==
Bits: AAA=
Created: 20210418040622
Publish: 20210418040622
Activate: 20210418040622
and copy the part after Key:
.
Finally, add the following to your /etc/named.conf
, but substitute the key for
your key:
key "keyname" {
algorithm hmac-sha512;
secret "zeOLcYcv/95yZX1KSLDreZyMtAsy5Ci5xwC9gW7XAgtOnOTIJpyr03CNDA8sUxfrkhb6Hjs90d3zRGm2g0XDaQ==";
};
Repeat this for every FreeIPA server you have, and we can move onto the next step.
2. Enable DDNS on your FreeIPA server
This step can be done via UI or CLI, but I did it via UI.
First, navigate to your DNS zone’s settings page.
Scroll down to where it says “Dynamic update” and set that to True.
Additionally, add the following line1 to “BIND update policy,”
replacing keyname
with your key and s.astrid.tech
with your zone:
grant keyname subdomain s.astrid.tech ANY;
Now, your UI should look something like this:
Save your changes, and anyone with that secret key can add anything to that subdomain.
3. Install ExternalDNS on your Kubernetes cluster
ExternalDNS is an addon for Kubernetes that has functionality to provide DNS updates over RFC2136. I installed the bitnami/external-dns Helm chart using the following Helmfile:
repositories:
- name: bitnami
url: https://charts.bitnami.com/bitnami
releases:
- name: freeipa-dns-sync
namespace: external-dns
chart: bitnami/external-dns
installed: true
values:
- provider: rfc2136
logFormat: json
domainFilters:
- s.astrid.tech # only handle DDNS for *.s.astrid.tech domains
rfc2136:
host: ipa0.p.astrid.tech # replace with your host
zone: s.astrid.tech # replace with your zone
tsigKeyname: keyname # replace with your keyname
tsigSecretAlg: hmac-sha512
secretName: freeipa-rfc2136
After deploying this with helmfile apply
, I then installed the following
secret:
apiVersion: v1
kind: Secret
metadata:
name: freeipa-rfc2136
namespace: external-dns
type: Opaque
stringData:
# replace with your secret
rfc2136_tsig_secret: zeOLcYcv/95yZX1KSLDreZyMtAsy5Ci5xwC9gW7XAgtOnOTIJpyr03CNDA8sUxfrkhb6Hjs90d3zRGm2g0XDaQ==
And that’s it! You should soon see DNS records show up in FreeIPA automatically.
For debugging, you may want to check external DNS’s logs using
kubectl logs [podname]
.
-
Note that this is a deviation from this guide, where it says to write
grant keyname name s.astrid.tech ANY;
.name
only allows you to changes.astrid.tech
, whilesubdomain
allows you to change every domain like*.s.astrid.tech
, as described here. ↩