This guide provides a step-by-step process for setting up a PowerDNS server with a MySQL backend and integrating it with Proxmox VE (PVE) SDN.

Pre-required

Install PowerDNS and MariaDB

First, set up a dedicated server (VM or container) for PowerDNS. This example uses a Debian 13 (Trixie) at proxmox LXC.

Prepare system + MariaDB

Update and install base tools

apt update && apt install -y curl ca-certificates gnupg lsb-release mariadb-server

PowerDNS Authoritative Server

Create the file ‘/etc/apt/sources.list.d/pdns.list’ with this content:

deb [signed-by=/etc/apt/keyrings/auth-50-pub.asc] http://repo.powerdns.com/debian trixie-auth-50 main

Put this in ‘/etc/apt/preferences.d/auth-50’:

Package: pdns-*
Pin: origin repo.powerdns.com
Pin-Priority: 600

and execute the following commands:

install -d /etc/apt/keyrings
curl https://repo.powerdns.com/FD380FBB-pub.asc | tee /etc/apt/keyrings/auth-50-pub.asc
apt-get update
apt-get install -y pdns-server pdns-backend-mysql mariadb-server mariadb-client

Setting MariaDB

mariadb-secure-installation

You’ll then likely be asked a few more questions to secure your MariaDB installation. Here are the typical recommendations:

  • Switch to unix_socket authentication [Y/n] Press `Y` and then Enter.
  • Change the root password? [Y/n] n (You already set it, and unix_socket is now preferred for root access from the local machine.)
  • Remove anonymous users? [Y/n] Y
  • Disallow root login remotely? [Y/n] Y (This is important for security.)
  • Remove test database and access to it? [Y/n] Y
  • Reload privilege tables now? [Y/n] Y

Configure MariaDB Database

PowerDNS needs a database to store its zones and records.

  1. Log in to MariaDB:

    mariadb -u root -p
  2. Create the database and user: Replace pdns_password with a strong, unique password.

    CREATE DATABASE powerdns;
    CREATE USER 'pdns'@'127.0.0.1' IDENTIFIED BY 'pdns_password';
    GRANT ALL PRIVILEGES ON powerdns.* TO 'pdns'@'127.0.0.1';
    FLUSH PRIVILEGES;
    EXIT;
  3. Import the PowerDNS schema: The installation provides a default schema. Import it into the newly created database.

    mariadb -u root -p powerdns < /usr/share/doc/pdns-backend-mysql/schema.mysql.sql

Configure PowerDNS

Now, configure the PowerDNS server to use the new database and enable its API.

Edit the configuration file /etc/powerdns/pdns.conf

launch=gmysql
gmysql-host=127.0.0.1
gmysql-dbname=powerdns
gmysql-user=pdns
gmysql-password=StrongPasswordHere
gmysql-dnssec=yes
 
api=yes
api-key=your_super_secret_api_key (35952075bacf8b703ae0807c551538210dc4787e5606bbf66c2752542f61a362)
webserver=yes
webserver-address=0.0.0.0
webserver-port=8081
webserver-allow-from=0.0.0.0/0

Note:

  • Replace your_super_secret_api_key with a secure, generated key. You can generate one using `openssl rand -hex 32`.
  • Ensure this exact key is used when configuring the PowerDNS provider in the Proxmox UI.
  • For production environments, restrict `webserver-allow-from` to only your Proxmox nodes’ IP addresses for enhanced security.

Important: If PowerDNS fails to start after configuration (e.g., with an “Address already in use” error), please refer to the Troubleshooting section for common solutions related to port conflicts.

Start and enable PowerDNS

systemctl enable --now pdns
systemctl status pdns

Test API

curl -H 'X-API-Key: 35952075bacf8b703ae0807c551538210dc4787e5606bbf66c2752542f61a362' \
      http://127.0.0.1:8081/api/v1/servers/localhost/zones

Test from public

curl -H 'X-API-Key: 35952075bacf8b703ae0807c551538210dc4787e5606bbf66c2752542f61a362'       http://192.168.1.23:8081/

Configure Proxmox VE SDN

With PowerDNS running, add it as a DNS provider in Proxmox.

  1. Navigate to SDN DNS: In the Proxmox web UI, go to `Datacenter SDN Options DNS`.

  2. Add PowerDNS Server:

    • Click Add and select PowerDNS.
    • ID: Give it a name (e.g., `powerdns1`).
    • URL: The REST API endpoint of your PowerDNS server (e.g., `http://192.168.1.23:8081/api/v1/servers/localhost`).
    • API Key: The `api-key` you set in `api.conf`.
    • TTL: The default TTL for records (e.g., `3600` for 1 hour).

Create Primary and Reverse Zones in PowerDNS

Before Create an EVPN Zone, you need create primary DNS Zone as parent zones, when you Configure DNS in the EVPN Zone. Before Add Subnets within Your VNet, you need create a DNS reverse zones, when you Configure a Subnet in Proxmox.

Create them using pdnsutil on your PowerDNS server.

pdnsutil create-zone pve.internal.lab ns1.pve.internal.lab
pdnsutil create-zone 10.in-addr.arpa ns1.pve.internal.lab

This creates the `pve.internal.lab` forward zone and `10.in-addr.arpa` reverse zone.

list all zones

pdnsutil list-all-zones

delete zones

pdnsutil delete-zone 10.60.10.in-addr.arpa

Configure DNS in the EVPN Zone

Now that you have the PowerDNS controller configured, you need to associate it with your EVPN Zone and define the primary DNS zones.

  1. Edit your EVPN Zone: In the Proxmox web UI, navigate to `Datacenter SDN Zones`. Select your EVPN Zone (e.g., `evpntest`) and click Edit.

  2. Configure DNS Settings:

    • DNS Server: Select the PowerDNS server you added (e.g., `powerdns1`).
    • Reverse DNS Server: Select the PowerDNS server you added (`powerdns1`).
    • DNS Zone: Enter your primary forward DNS zone (e.g., `pve.internal.lab`). This zone must exist in PowerDNS.

Note on Reverse DNS Zone: Proxmox VE automatically determines the appropriate reverse DNS zone name (e.g., `10.in-addr.arpa` for a 10.x.x.x subnet) based on the subnet’s IP range. You must still ensure that this reverse zone is explicitly created in your PowerDNS server.

Configure a DNS for Subnet in Proxmox

Please, Create a VXLAN VNet first. When configuring a subnet, DNS settings like the PowerDNS controller and the parent DNS Zone are implicitly inherited from the EVPN Zone’s configuration.

  • Go to `Datacenter SDN VNets.
  • Select a VNet and click Create Subnet.
  • Fill in the Subnet and Gateway (e.g., 10.60.10.0/24 and 10.60.10.1).
    • Tip for DNS Zone Prefix: Choose a short, descriptive, and unique name (e.g., web-dmz, db-zone, vnet01). This prefix will form a sub-zone within your parent DNS Zone (e.g., `vnet01.pve.internal.lab`). Important: You must manually create this sub-zone in PowerDNS. For example:
      pdnsutil create-zone vnet01.pve.internal.lab ns1.pve.internal.lab
    • Tip for Reverse DNS Zones: For this subnet (e.g., `10.60.10.0/24`), ensure the corresponding reverse DNS zone (`10.60.10.in-addr.arpa`) has been created in your PowerDNS server using `pdnsutil`. Proxmox relies on this pre-existing zone to automatically add PTR records.

Apply SDN Configuration:

Go to `Datacenter SDN` and click the Apply button.

Verification

Finally, create a VM to see if DNS records are generated automatically.

  1. Create a VM: Create a new VM and for its network device, select the VNet you configured.

  2. Check DNS Records: Once the VM is running and has an IP, check PowerDNS for the new record on the PowerDNS server.

    pdnsutil list-zone vnet01.pve.internal.lab

    You should see `A` and `PTR` records for your new VM, created automatically by Proxmox.

Troubleshooting

Missing DNS Records

If your zone exists but is empty (no A or PTR records for your VMs), it is likely because the VM was started before the zone was created in PowerDNS. Proxmox only attempts to register records on state changes (start/stop).

Solution: Restart the VM or Container to trigger the DNS registration again.

`pdns.service` fails with “Address already in use”

If `systemctl status pdns` shows an error like `Unable to bind UDP socket to ‘0.0.0.0:53’: Address already in use`, it means another service is occupying the DNS port.

  1. Find the conflicting service: Run this command to see what process is using port 53. The most common culprit is `systemd-resolved`.

    sudo ss -ulpn | grep ':53'
  2. Disable `systemd-resolved`‘s stub listener: If `systemd-resolved` is the issue, you can disable its listener.

    a. Edit the configuration file:

    sudo nano /etc/systemd/resolved.conf

    b. Find the line `#DNSStubListener=yes`, uncomment it, and change it to `no`:

    [Resolve]
    DNSStubListener=no

    c. Restart the services for the changes to take effect:

    sudo systemctl restart systemd-resolved
    sudo systemctl restart pdns

Reference List

  1. https://www.powerdns.com/
  2. https://pve.proxmox.com/pve-docs/chapter-pvesdn.html#pvesdn_dns_powerdns