Instalación y Configuración de PowerDNS
PowerDNS es un servidor DNS autoritativo de alto rendimiento y código abierto que soporta múltiples backends de base de datos (MySQL, PostgreSQL, SQLite) para almacenar zonas y registros, lo que permite su gestión mediante API REST y herramientas externas. Con soporte completo para DNSSEC y una API moderna, es la elección preferida en entornos de hosting y proveedores DNS. Esta guía cubre la instalación de PowerDNS con backend MySQL, gestión de zonas y configuración DNSSEC.
Requisitos Previos
- Ubuntu 22.04/Debian 12 o CentOS 9/Rocky Linux 9
- MySQL 8.0 o MariaDB 10.6+ (o PostgreSQL 14+)
- Mínimo 1 GB de RAM
- Puerto 53 TCP/UDP disponible
- Acceso root al servidor
Instalación de PowerDNS
# Ubuntu/Debian: usar el repositorio oficial de PowerDNS
# (los paquetes de distribución suelen ir atrasados)
curl -fsSL https://repo.powerdns.com/FD380FBB-pub.asc | \
gpg --dearmor -o /usr/share/keyrings/powerdns-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/powerdns-archive-keyring.gpg] \
https://repo.powerdns.com/ubuntu $(lsb_release -cs)-auth-master main" | \
tee /etc/apt/sources.list.d/pdns.list
# Dar prioridad al repositorio de PowerDNS sobre los de Ubuntu
cat > /etc/apt/preferences.d/pdns << 'EOF'
Package: pdns-*
Pin: origin repo.powerdns.com
Pin-Priority: 600
EOF
apt-get update
apt-get install -y pdns-server pdns-backend-mysql
# CentOS/Rocky Linux
dnf install -y epel-release
dnf install -y pdns pdns-backend-mysql
# Verificar la instalación
pdns_server --version
Configuración del Backend MySQL
# Instalar MySQL si no está disponible
apt-get install -y mysql-server # Ubuntu/Debian
# dnf install -y mysql-server && systemctl enable --now mysqld # CentOS
# Crear la base de datos y usuario para PowerDNS
mysql -u root << 'EOF'
CREATE DATABASE pdns CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'pdns'@'localhost' IDENTIFIED BY 'password_seguro_pdns';
GRANT ALL PRIVILEGES ON pdns.* TO 'pdns'@'localhost';
FLUSH PRIVILEGES;
EOF
# Importar el esquema de base de datos de PowerDNS
mysql -u pdns -p pdns < /usr/share/doc/pdns-backend-mysql/schema.mysql.sql
# Verificar que las tablas se crearon correctamente
mysql -u pdns -ppassword_seguro_pdns pdns -e "SHOW TABLES;"
# Debe mostrar: comments, cryptokeys, domainmetadata, domains, records, supermasters, tsigkeys
Configuración del Servidor
# Hacer copia de seguridad de la configuración por defecto
cp /etc/powerdns/pdns.conf /etc/powerdns/pdns.conf.original
# Configuración principal de PowerDNS
cat > /etc/powerdns/pdns.conf << 'EOF'
# Backend de base de datos
launch=gmysql
# Configuración del backend MySQL
gmysql-host=127.0.0.1
gmysql-port=3306
gmysql-dbname=pdns
gmysql-user=pdns
gmysql-password=password_seguro_pdns
gmysql-dnssec=yes # Habilitar soporte DNSSEC en la base de datos
# Configuración de red
local-address=0.0.0.0
local-port=53
allow-axfr-ips=127.0.0.1,10.0.1.0/24 # IPs permitidas para transferencias de zona
# API REST (necesaria para gestión programática)
api=yes
api-key=tu_api_key_seguro_aqui
webserver=yes
webserver-address=127.0.0.1
webserver-port=8081
webserver-allow-from=127.0.0.1,10.0.0.0/8
# Rendimiento
max-tcp-connections=20
cache-ttl=20
negquery-cache-ttl=60
query-cache-ttl=20
# Logging (reducir en producción)
loglevel=4
log-dns-queries=no
# Seguridad
setuid=pdns
setgid=pdns
EOF
# Iniciar y habilitar PowerDNS
systemctl enable --now pdns
# Verificar que el servicio arrancó correctamente
systemctl status pdns
Gestión de Zonas y Registros
Gestiona zonas mediante la herramienta de línea de comandos pdnsutil:
# Crear una zona nueva
pdnsutil create-zone empresa.com
# Añadir registros a la zona
pdnsutil add-record empresa.com @ SOA "ns1.empresa.com. admin.empresa.com. 1 3600 900 604800 300"
pdnsutil add-record empresa.com @ NS ns1.empresa.com
pdnsutil add-record empresa.com @ NS ns2.empresa.com
pdnsutil add-record empresa.com @ A 93.184.216.34
pdnsutil add-record empresa.com www A 93.184.216.34
pdnsutil add-record empresa.com mail MX "10 mail.empresa.com"
pdnsutil add-record empresa.com mail A 93.184.216.50
pdnsutil add-record empresa.com @ TXT "v=spf1 mx -all"
# Verificar los registros de la zona
pdnsutil list-zone empresa.com
# Verificar la consistencia de la zona
pdnsutil check-zone empresa.com
# Incrementar el número de serie (SOA serial)
pdnsutil increase-serial empresa.com
# Gestión directa con MySQL (alternativa)
mysql -u pdns -ppassword_seguro_pdns pdns << 'EOF'
-- Insertar zona
INSERT INTO domains (name, type) VALUES ('empresa.com', 'NATIVE');
-- Obtener el ID de la zona
SELECT id FROM domains WHERE name='empresa.com';
-- Insertar registros (usar el ID obtenido)
INSERT INTO records (domain_id, name, type, content, ttl)
VALUES
(1, 'empresa.com', 'A', '93.184.216.34', 300),
(1, 'www.empresa.com', 'CNAME', 'empresa.com', 300);
EOF
API REST
PowerDNS expone una API REST completa para automatización:
# Variable para la API key
API_KEY="tu_api_key_seguro_aqui"
API_URL="http://localhost:8081/api/v1"
# Listar todas las zonas
curl -H "X-API-Key: $API_KEY" "$API_URL/servers/localhost/zones" | python3 -m json.tool
# Crear una zona nueva via API
curl -X POST -H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
"$API_URL/servers/localhost/zones" \
-d '{
"name": "nuevazona.com.",
"kind": "Native",
"nameservers": ["ns1.empresa.com.", "ns2.empresa.com."]
}'
# Añadir registros a una zona via API
curl -X PATCH -H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
"$API_URL/servers/localhost/zones/nuevazona.com." \
-d '{
"rrsets": [{
"name": "www.nuevazona.com.",
"type": "A",
"ttl": 300,
"changetype": "REPLACE",
"records": [{"content": "93.184.216.34", "disabled": false}]
}]
}'
# Obtener detalles de una zona
curl -H "X-API-Key: $API_KEY" \
"$API_URL/servers/localhost/zones/empresa.com." | python3 -m json.tool
# Eliminar un registro
curl -X PATCH -H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
"$API_URL/servers/localhost/zones/empresa.com." \
-d '{
"rrsets": [{
"name": "old.empresa.com.",
"type": "A",
"changetype": "DELETE"
}]
}'
Configuración DNSSEC
# Activar DNSSEC para una zona
pdnsutil secure-zone empresa.com
# Verificar las claves DNSSEC generadas
pdnsutil show-zone empresa.com
# Obtener los registros DS para enviar al registrar del dominio
pdnsutil export-zone-ds empresa.com
# Los DS records deben configurarse en el panel del registrar del dominio
# Rectificar la zona (necesario tras cambios con DNSSEC activo)
pdnsutil rectify-zone empresa.com
# Verificar la firma DNSSEC
pdnsutil check-zone empresa.com
# Probar la resolución con DNSSEC
dig +dnssec empresa.com @localhost
dig +dnssec empresa.com DS @8.8.8.8 # Verificar el DS en el padre
# Rotación de claves (KSK - Key Signing Key)
pdnsutil generate-zone-key empresa.com ksk 257 13 # Algoritmo ECDSA P-256
pdnsutil activate-zone-key empresa.com <key-id>
pdnsutil deactivate-zone-key empresa.com <old-key-id>
Ajuste de Rendimiento
# Parámetros de rendimiento en pdns.conf
# cache-ttl=20 - TTL de la caché interna en segundos
# max-queue-length=5000 - Máxima longitud de la cola de consultas
# receiver-threads=4 - Hilos receptores (ajustar según CPUs)
# distributor-threads=3 - Hilos distribuidores de consultas
# Optimización de MySQL para PowerDNS
mysql -u root << 'EOF'
-- Índices adicionales para mejorar el rendimiento de consultas frecuentes
ALTER TABLE records ADD INDEX rec_name_index (name, type);
ALTER TABLE records ADD INDEX domain_id (domain_id);
EOF
# Verificar estadísticas de PowerDNS
pdns_control show '*'
pdns_control show cache-hits
pdns_control show cache-misses
pdns_control show queries
# Limpiar la caché de PowerDNS
pdns_control purge
pdns_control purge empresa.com # Solo para un dominio específico
Solución de Problemas
# Ver logs en tiempo real
journalctl -u pdns -f
# Verificar que PowerDNS responde consultas
dig @localhost empresa.com SOA
dig @localhost www.empresa.com A
# Verificar la conectividad a la base de datos
pdns_server --daemon=no --log-dns-queries=yes --loglevel=7 2>&1 | head -50
# Comprobar la configuración sin iniciar el servicio
pdns_server --config
# Verificar que el backend está respondiendo
pdnsutil check-all-zones
# Problema: "Unable to determine backend" - verificar gmysql-* en pdns.conf
# Problema: "Operationally down" - verificar que MySQL está activo
systemctl status mysql
mysql -u pdns -ppassword_seguro_pdns pdns -e "SELECT COUNT(*) FROM domains;"
Conclusión
PowerDNS con backend MySQL ofrece una plataforma DNS autoritativa robusta y gestionable programáticamente, ideal para proveedores de hosting y entornos donde los registros DNS cambian frecuentemente. La API REST y el soporte completo de DNSSEC, combinados con su alto rendimiento demostrado en producción, hacen de PowerDNS la opción más completa para gestión DNS empresarial a escala.


