Files
homelab/dns-server/SETUP.md
T

5.3 KiB

Proxmox DNS Server - Setup Guide

This guide walks you through deploying the Proxmox DNS server in your homelab.

Prerequisites

  1. Proxmox cluster up and running
  2. OpenTofu installed and configured
  3. Ansible installed with vault password set up
  4. Network access to Proxmox API

Step 1: Verify Proxmox API Token

The DNS server uses the existing Proxmox API token already configured in the Ansible vault.

The following variables are used from the vault and group_vars:

  • pve_api_url: Proxmox API URL (e.g., https://jupiter.renner.uno:8006)
  • pve_user: Proxmox user (e.g., root@pam)
  • pve_token_id: API token ID (e.g., ansible)
  • pve_token_secret: API token secret (stored in vault)

These are already configured for your infrastructure, so no additional setup is needed!

Step 2: Deploy with OpenTofu

cd opentofu

# Review what will be created
tofu plan

# Apply (creates LXC 118)
tofu apply

# The ansible_playbook parameter will automatically run the Ansible role
# to install and configure the DNS server

If you prefer to deploy the LXC manually or the automatic provisioning fails:

# Deploy LXC only (comment out ansible_playbook in lxc_118_proxmox_dns.tf)
tofu apply

# Then run Ansible manually
cd ../ansible
ansible-playbook -i inventory/ plays/install-proxmox-dns.yml

Note: The playbook automatically uses the vault password from .vault_pass via the ANSIBLE_VAULT_PASSWORD_FILE environment variable set in .envrc.

Step 3: Verify Installation

# SSH to the DNS server
ssh root@10.2.40.53

# Check service status
systemctl status proxmox-dns

# View logs
journalctl -u proxmox-dns -f

# Test DNS resolution locally
dig @localhost gitea.srv.renner.uno

From another machine:

# Test from external host
dig @10.2.40.53 gitea.srv.renner.uno

# Should return the IP of your gitea VM/LXC

Step 4: Configure UniFi to Use DNS Server

  1. Log into UniFi Controller
  2. Navigate to Settings > Networks
  3. Edit your LAN network
  4. Scroll to DHCP
  5. Set DHCP Name Server: Manual
  6. DNS Server 1: 10.2.40.53 (Proxmox DNS)
  7. DNS Server 2: 10.2.40.1 or 8.8.8.8 (fallback)
  8. Click Apply Changes

All DHCP clients will now use the Proxmox DNS server.

For VMs to be discoverable, they need the QEMU guest agent installed:

Debian/Ubuntu VMs:

apt update
apt install qemu-guest-agent
systemctl enable --now qemu-guest-agent

Rocky/AlmaLinux/RHEL VMs:

dnf install qemu-guest-agent
systemctl enable --now qemu-guest-agent

In Proxmox UI:

  1. Select the VM
  2. Go to Options
  3. QEMU Guest Agent: Enable
  4. Reboot the VM

LXC containers don't need any special configuration - IPs are read directly from Proxmox.

Testing

After setup, test that hostnames resolve:

# From any machine on the network
ping gitea.srv.renner.uno
ping authentik-db-1.renner.uno

# Using dig
dig @10.2.40.53 rustfs-1.srv.renner.uno

# Check DNS server logs for queries
ssh root@10.2.40.53 journalctl -u proxmox-dns -f

Troubleshooting

DNS server not starting

# Check logs for errors
journalctl -u proxmox-dns -n 100

# Common issues:
# - Invalid Proxmox token
# - Network connectivity to Proxmox API
# - Port 53 already in use

VM not resolving

  1. Check VM is running: Proxmox UI
  2. Verify guest agent is installed and running: systemctl status qemu-guest-agent
  3. Check Proxmox can see guest network:
    qm guest cmd <vmid> network-get-interfaces
    

LXC not resolving

  1. Verify container is running
  2. Check network configuration in Proxmox UI
  3. For DHCP LXCs, ensure they have received an IP:
    pct exec <ctid> -- ip addr show
    

DNS queries timing out

  1. Check firewall rules allow UDP/53
  2. Verify DNS server is listening:
    ssh root@10.2.40.53 netstat -ulnp | grep 53
    
  3. Test locally first:
    ssh root@10.2.40.53 dig @localhost test.renner.uno
    

Maintenance

Updating DNS Server

# Update code
cd ~/homelab
git pull

# Re-run Ansible
cd ansible
ansible-playbook -i inventory/ plays/install-proxmox-dns.yml --vault-password-file ../.vault_pass

# Or restart service if only config changed
ssh root@10.2.40.53 systemctl restart proxmox-dns

Rotating API Token

  1. Create new token in Proxmox UI
  2. Update Ansible vault:
    ansible-vault edit inventory/group_vars/all/vault.yml
    # Update pve_token_secret value
    
  3. Re-run Ansible to deploy new config
  4. Delete old token in Proxmox UI

Viewing Cache

The DNS server logs cache statistics on startup and refresh:

ssh root@10.2.40.53 journalctl -u proxmox-dns | grep "Fetched"

Architecture Notes

  • Cache TTL: 60 seconds (configurable in role defaults)
  • DNS Response TTL: 300 seconds (5 minutes)
  • Query Pattern: Background thread refreshes cache, DNS queries served from cache
  • Fallback: Returns REFUSED for non-Proxmox queries (clients will try upstream DNS)

Security Considerations

  • API token has full read access to Proxmox (needed to query all nodes)
  • DNS server runs as root (required for port 53)
  • Config file contains API token (mode 0640, root:root)
  • Systemd security hardening applied (ProtectSystem, PrivateTmp)
  • No write operations to Proxmox - read-only