- Why GitOps?
- π Installation & Initial Configuration
- π Writing Hostnames
- π GitOps Workflow
- π Bash Sync Script & Cronjob
- π (Optional) GitHub Actions CI Validation
- Visual DNS Flow
- π‘ Benefits & Considerations
Why GitOps?
β‘ It started as a simple typo in /etc/hosts. One wrong hostname. One overlooked IP.
In an instant, my homelab descended into chaos:
- My Proxmox cluster stopped resolving nodes.
- The Ceph distributed storage went offline.
- Every LXC container and VM froze or failed to start.
It was a domino effect: a tiny DNS misconfiguration brought down my entire lab environment.
Thatβs when I realised: manual DNS editing was a ticking time bomb.
Enter GitOps for DNS – a workflow that stores every host entry in a repo under version control, automates deployment, and ensures a single source of truth.
No more human error. No more cascading failures.
Introduction
In this guide, weβll implement GitOps-style DNS using dnsmasq, GitHub, Bash, and a cronjob – making your homelab DNS predictable, maintainable, and secure.
Deploy keys (SSH keys) are used to secure repository access, ensuring only your DNS server can pull updates.
π Benefits of a GitOps DNS Workflow
- π Automated sync β Changes in Git automatically update the DNS server
- π Version-controlled hosts β Every edit is tracked with commit history
- π‘ Security-conscious β Deploy keys and configuration validation reduce risk
- π§© Modular & maintainable β Split hosts into
.cfgfiles for easier management - β Integrate dnsmasq with GitHub Actions for automated validation
π Installation & Initial Configuration
1. Install dnsmasq and Git
sudo yum install -y dnsmasq git # RHEL/CentOS/AlmaLinux
sudo apt install -y dnsmasq git # Debian/Ubuntu
Enter fullscreen mode Exit fullscreen mode
2. Configure dnsmasq
Create a config file in /etc/dnsmasq.d/:
/etc/dnsmasq.d/000-base.conf
domain=safesploit.com
expand-hosts
log-queries
no-hosts
addn-hosts=/etc/hosts.d
listen-address=172.16.5.27
Enter fullscreen mode Exit fullscreen mode
π Tip: Always bind dnsmasq to a specific NIC (
listen-address)β οΈ using
0.0.0.0is not supported.Otherwise, dnsmasq will only respond on
127.0.0.1.(
3. Prepare /etc/hosts.d/ (Optional, Modular Setup)
sudo mkdir -p /etc/hosts.d
sudo touch /etc/hosts.d/000-network.cfg
# sudo touch /etc/hosts.d/XXX-*.cfg # placeholder files
Enter fullscreen mode Exit fullscreen mode
4. Enable & start service
sudo systemctl enable dnsmasq
sudo systemctl start dnsmasq
Enter fullscreen mode Exit fullscreen mode
Now dnsmasq is ready to resolve hostnames from /etc/hosts.d/.
5. (Optional) Test after starting dnsmasq
Use dig @<DNS Server IP> <DNS Entry> to query:
dig @172.16.5.27 ldap.safesploit.com +short
Enter fullscreen mode Exit fullscreen mode
This gives proof it works
π Writing Hostnames
Add new .cfg files to /etc/hosts.d/ following a consistent naming scheme like XXX-<subnet_name>.cfg:
-
005-critical-prod.cfgβ critical production hosts -
081-mgmt.cfgβ management network -
100-storage.cfgβ storage servers
Example hostnames
Each .cfg file contains simple IP hostname mappings (just like /etc/hosts):
172.16.5.10 ldap
Enter fullscreen mode Exit fullscreen mode
172.16.100.10 nas1
Enter fullscreen mode Exit fullscreen mode
β This modular approach makes it easy to version control, review, and expand.
π GitOps Workflow
Assumed Knowledge: that you already know how to create a GitHub repo.
1. Repository Structure
.dns-configs/
βββ dnsmasq/
βββ hosts.d/
βββ 005-critical-prod.cfg
βββ 081-mgmt.cfg
βββ 100-storage.cfg
βββ XXX-*.cfg
Enter fullscreen mode Exit fullscreen mode
2. Secure Access with Deploy Keys
- Generate an SSH key for the DNS server:
ssh-keygen -t ed25519 -f ~/.ssh/id_github_ed25519
Enter fullscreen mode Exit fullscreen mode
- Add the public key to your GitHub repositoryβs Deploy Keys with read-only access.
- GitHub Docs: Managing Deploy Keys
3. Workflow Steps
- Detect changes on
main - Clone repo
- Sync
/etc/hosts.d/viarsync - Restart
dnsmasq - Record applied commit hash
β οΈ Warning: Validate configs before restart:
dnsmasq --test systemctl restart dnsmasq
π Bash Sync Script & Cronjob
DNS GitOps Script:
β οΈ Make sure you adjust these for your setup
- REPO=”dns-configs”
- OWNER=”github_org/username”
- GITHUB_DEPLOY_KEY=”${HOME}/.ssh/id_github_ed25519″
Bash Script
The script handles:
- SSH agent setup
- Change detection via commit hash
- Cloning and syncing
/etc/hosts.d/ - Restarting dnsmasq
- Logging and optional quiet mode
Git Clone Bash Script – git_clone_dns_configs_dnsmasq.sh
Cronjob (every 5 minutes):
*/5 * * * * /root/git_clone_dnsmasq.sh
Enter fullscreen mode Exit fullscreen mode
π§ Automatic updates reduce errors and maintain consistency.
π (Optional) GitHub Actions CI Validation
At this point, the DNS server can pull host updates from Git.
However, blindly syncing DNS records from Git is risky. A bad hosts entry, duplicate hostname, or broken dnsmasq config could break DNS resolution.
To reduce that risk, I added a GitHub Actions workflow that validates the dnsmasq configuration before changes are accepted.
CI Validation
CI check Reason Runs inside AlmaLinux 10 Matches the RHEL-style target environment Installs realdnsmasq service
Validates against the actual service
Copies dnsmasq.d and hosts.d
Tests realistic file layout
Validates host format
Catches malformed records
Detects duplicate hostnames
Prevents ambiguous DNS
Creates CI-safe config
Avoids binding to homelab-only IPs in CI
Starts dnsmasq on 127.0.0.1:5353
Tests real resolution safely
Uses dig tests
Proves records actually resolve
GitHub Actions workflow
GitHub Actions CI Dnsmasq – dnsmasq-ci.yml
Visual DNS Flow
[Client Request]
|
v
[DNS (dnsmasq)]
|
βββββββ΄ββββββ
v v
[Local hosts] [Upstream DNS]
Enter fullscreen mode Exit fullscreen mode
πΌ Shows decision flow for DNS resolution.
π‘ Benefits & Considerations
Benefits:
- β Version-controlled DNS (rollback capable)
- β Modular and maintainable
- β Automatic sync reduces human error
- β CI/CD guardrails for DNS
Security Notes:
- π Protect deploy keys (
chmod 600 ~/.ssh/id_github_ed25519) - π Validate dnsmasq configs before restart
- β οΈ Be careful with
rsync --deleteβ deletions in Git remove files on server
π Next Steps / Future Improvements
- β Integrate dnsmasq with GitHub Actions for automated validation
- β Add linting / syntax checks for host files
- Support multiple domains or overlay networks
- Consider BIND migration for more advanced DNS features
Conclusion
GitOps makes your homelab DNS:
- Predictable β every change tracked
- Secure β deploy keys and validation
- Maintainable β modular files and automation
You now have a fully automated, version-controlled DNS workflow for your homelab.
λ΅κΈ λ¨κΈ°κΈ°