Servidor DNS Público Seguro - dns.rocksdns.ovh

Servidor DNS público libre, cifrado y con enfoque en la privacidad, desplegado sobre infraestructura europea.

Quick Start

Para navegadores:

Para Android:

Verificación:

curl -H "Accept: application/dns-json" "https://dns.rocksdns.ovh/dns-query?name=example.com&type=A"

Infraestructura Técnica

Componente Especificación
Proveedor Ionos Europa
Dirección IP 82.223.31.111
Sistema Operativo Debian 12 (Bookworm)
Software DNS AdGuard Home 0.107.x + Unbound 1.17.x
Dominio dns.rocksdns.ovh
Certificación TLS Let’s Encrypt (auto-renovación cada 60 días)
Uptime SLA >99.5%

Protocolos DNS Soportados

Protocolo Puerto RFC Estado Observaciones
DNS-over-HTTPS (DoH) 443/tcp RFC 8484 Activo HTTP/2, ALPN h2
DNS-over-TLS (DoT) 853/tcp RFC 7858 Activo TLS 1.3 preferido
DNS-over-QUIC (DoQ) 784/udp RFC 9250 Activo QUIC v1
DNS clásico (UDP/TCP) 53 RFC 1035 Deshabilitado Bloqueado por firewall

Arquitectura de Resolución

Cadena de resolución actual:

Cliente → AdGuard Home (443/853/784) → Unbound (127.0.0.1:5335) → Root Servers → TLD → Autoritativo

Estado:

🧩 Upstreams DNS utilizados (fallback)

A pesar de que Unbound realiza resolución directa desde los servidores raíz, se han añadido upstreams de respaldo únicamente como mecanismo de fallback para mejorar la disponibilidad en caso de fallo temporal de resolución directa.

Upstreams definidos:

Servidor IP / URL Política de Privacidad Ubicación Enlace
LibreDNS https://doh.libredns.gr/dns-query Sin logs Grecia 🇬🇷 libredns.gr
Hostux DNS https://dns.hostux.net/dns-query Sin logs Francia 🇫🇷 hostux.net

🔐 Importante:

Beneficios de privacidad


Hardening de Seguridad

Sistema Operativo

# Usuario dedicado
adduser --system --no-create-home --group adguardhome

# Capabilities limitadas
setcap 'cap_net_bind_service=+ep' /opt/AdGuardHome/AdGuardHome

# Permisos de certificados
chmod 640 /opt/AdGuardHome/certs/*.pem
chown adguardhome:adguardhome /opt/AdGuardHome/certs/

AppArmor personalizado (aislamiento de AdGuard Home)

Se ha implementado un perfil personalizado de AppArmor para AdGuard Home para reforzar el aislamiento del binario y limitar sus permisos al mínimo necesario. El perfil opera inicialmente en modo complain para observar sin bloquear, con opción a pasar a modo enforce tras validación.

📄 Archivo de perfil: /etc/apparmor.d/opt.AdGuardHome.AdGuardHome

@{PROC}=/proc/
@{HOMEDIRS}=/home/
@{run}=/run/

# Perfil AppArmor para AdGuard Home
/opt/AdGuardHome/AdGuardHome flags=(complain) {
  # Cargar abstracciones comunes
  include <abstractions/base>
  include <abstractions/nameservice>

  # Acceso completo a su propio directorio
  /opt/AdGuardHome/** rw,
  /opt/AdGuardHome/AdGuardHome rix,

  # Lectura de certificados TLS
  /etc/ssl/** r,
  /etc/letsencrypt/** r,

  # Lectura del resolv.conf
  /etc/resolv.conf r,

  # Acceso de red
  network inet stream,
  network inet6 stream,
  network inet dgram,
  network inet6 dgram,

  # Permitir bind en puertos <1024
  capability net_bind_service,

  # Acceso a recursos del sistema
  /dev/urandom r,
  /proc/sys/net/core/somaxconn r,
  /proc/sys/net/ipv4/tcp_fastopen r,

  # Denegar todo lo demás
  deny /** mrwklx,
}

🔍 Verificación de estado:

sudo aa-status

⚠️ Activación en modo enforce: Una vez validado que no hay denegaciones relevantes:

sudo aa-enforce /etc/apparmor.d/opt.AdGuardHome.AdGuardHome

Aislamiento adicional vía Systemd

[Service]
# Capabilities mínimas
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
NoNewPrivileges=true

# Aislamiento del sistema de archivos
ProtectSystem=full
ProtectHome=true
ReadOnlyPaths=/etc /usr /boot
ReadWritePaths=/opt/AdGuardHome /run
PrivateTmp=true
PrivateDevices=true

# Aislamiento del sistema
ProtectHostname=true
RestrictRealtime=true

# Restricciones de red
RestrictAddressFamilies=AF_INET AF_INET6

# Seguridad de memoria
MemoryDenyWriteExecute=true
LockPersonality=true

# Límites de recursos
MemoryMax=512M
TasksMax=50

# Syscalls permitidas
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM

Firewall UFW

ufw allow 443/tcp comment 'DoH HTTPS'
ufw allow 853/tcp comment 'DoT TLS'
ufw allow 784/udp comment 'DoQ QUIC'
ufw deny 53 comment 'DNS clásico bloqueado'
ufw allow 22/tcp comment 'SSH administrativo'

ufw --force enable
ufw logging medium

Configuración de Clientes

Firefox (recomendado)

about:config:
network.trr.mode = 3
network.trr.uri = https://dns.rocksdns.ovh/dns-query
network.trr.bootstrapAddress = 82.223.31.111
network.trr.early-AAAA = true

Chrome/Chromium

chrome://settings/security → Usar DNS seguro → Personalizado → https://dns.rocksdns.ovh/dns-query

Sistemas Operativos

Android 9+

Ajustes → Conexiones → DNS privado → Nombre del host del proveedor DNS privado
dns.rocksdns.ovh

iOS 14+ (Perfil DNS)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PayloadContent</key>
    <array>
        <dict>
            <key>DNSSettings</key>
            <dict>
                <key>DNSProtocol</key>
                <string>HTTPS</string>
                <key>ServerURL</key>
                <string>https://dns.rocksdns.ovh/dns-query</string>
            </dict>
        </dict>
    </array>
</dict>
</plist>

Linux systemd-resolved

sudo systemctl edit systemd-resolved
[Service]
Environment=SYSTEMD_RESOLVED_DNS_SERVERS=82.223.31.111#dns.rocksdns.ovh
Environment=SYSTEMD_RESOLVED_DNS_OVER_TLS=yes
Environment=SYSTEMD_RESOLVED_DNSSEC=yes

Testing y Validación

Comandos de Verificación

DNS-over-HTTPS

kdig @dns.rocksdns.ovh example.com A +https +tls-host=dns.rocksdns.ovh
curl -H "Accept: application/dns-json" "https://dns.rocksdns.ovh/dns-query?name=example.com&type=A"

DNS-over-TLS

kdig @dns.rocksdns.ovh example.com A +tls +tls-host=dns.rocksdns.ovh

DNS-over-QUIC

dnsping -Q -p 784 -s 82.223.31.111 example.com

Validación DNSSEC

# Verificación local (Unbound)
dig @127.0.0.1 cloudflare.com +dnssec
dig @127.0.0.1 dnssec-failed.org +dnssec  # Debe fallar

# Verificación adicional de estado DNSSEC
unbound-control dump_cache | grep -i 'dnssec'

# Verificación vía DNS cifrado
dig @82.223.31.111 cloudflare.com +dnssec +tcp +tls
dig @82.223.31.111 dnssec-failed.org +dnssec +tcp +tls  # Debe fallar

Herramientas de Testing Online

Servicio URL Resultado Esperado
DNS Leak Test https://dnsleaktest.com Solo 82.223.31.111
Cloudflare Test https://1.1.1.1/help Secure DNS: Yes
DNSSEC Analyzer https://dnssec-analyzer.verisignlabs.com Validación correcta
Browser Leaks https://browserleaks.com/dns dns.rocksdns.ovh

Mantenimiento

Renovación Automática de Certificados

# Crontab
0 2 * * 1 /usr/bin/certbot renew --quiet && /bin/systemctl reload AdGuardHome

Actualización de AdGuard Home

#!/bin/bash
LATEST_VERSION=$(curl -s https://api.github.com/repos/AdguardTeam/AdGuardHome/releases/latest | grep -Po '"tag_name": "\K[^"]*')
wget "https://github.com/AdguardTeam/AdGuardHome/releases/download/${LATEST_VERSION}/AdGuardHome_linux_amd64.tar.gz"

systemctl stop AdGuardHome
tar -xzf AdGuardHome_linux_amd64.tar.gz
cp AdGuardHome/AdGuardHome /opt/AdGuardHome/
chown adguardhome:adguardhome /opt/AdGuardHome/AdGuardHome
systemctl start AdGuardHome

Backup Automatizado

# Crontab para backup semanal
0 3 * * 0 tar -czf /backup/adguard-$(date +%Y%m%d).tar.gz /opt/AdGuardHome/AdGuardHome.yaml /opt/AdGuardHome/certs/
find /backup/ -name "adguard-*.tar.gz" -mtime +28 -delete

Métricas de Rendimiento

Métrica Valor Target Medición Herramienta
Latencia DoH <25ms Europa Occidental kdig + time
Latencia DoT <20ms Europa Occidental kdig + time
Latencia DoQ <18ms Europa Occidental dnsping
Disponibilidad >99.5% Mensual Monitorización continua
Throughput >1000 qps Pico sostenido Stress testing

Ubicación de test: Madrid, ES
Metodología: Promedio de 100 consultas cada 4 horas


Limitaciones Técnicas

Protocolos

DNSSEC

Compatibilidad


Roadmap

Q3 2025

Q4 2025

Q1 2026

Completado


Sello de Buenas Prácticas

Arquitectura:

Seguridad:

Operaciones:


Filosofía del Proyecto

Principios fundamentales:

Configuración de No-Logging

# AdGuardHome.yaml (extracto)
dns:
  anonymize_client_ip: true
  edns_client_subnet: false
log:
  enabled: false
  file: ""
statistics:
  enabled: false
querylog:
  enabled: false
  size_memory: 0
# Unbound (rocksdns.conf extracto)
server:
    dnssec: yes
    val-permissive-mode: no
    chroot: ""
    verbosity: 0
    logfile: ""
    use-syslog: no

⚠️ Nota técnica: Se ha configurado chroot: "" para evitar fallos de acceso, y el servicio puede actualizar el ancla de confianza (root.key) mediante unbound-anchor.service.


Información del Mantenedor


Versión de documentación: 4.0
Última actualización: Junio 2025
Próxima revisión: Septiembre 2025

Estado del servicio: OPERACIONAL
SLA: 99.5% uptime mensual
Soporte: Comunidad open source

📌 Cambios en la versión 4.1 (Junio 2025)

Mejoras aplicadas tras validación completa en entorno productivo:

🛡️ Seguridad

⚙️ Rendimiento y resolución

🧩 Verificaciones adicionales

# 🧾 Documentación Técnica - Configuración DNS Pública `rocksdns.ovh`  
📅 **Fecha:** 16 de junio de 2025

---

## ✅ 1. Protección con Fail2Ban

**Objetivo:** Defender AdGuard Home contra accesos maliciosos.

- **Jail definido en** `/etc/fail2ban/jail.local`:
  ```ini
  [adguardhome]
  enabled = true
  filter = adguardhome
  logpath = /var/log/adguardhome.log
  maxretry = 5
  bantime = 600
  findtime = 600

Se ajustó la ruta del log para que fuera accesible.

Fail2Ban arrancó sin errores tras reiniciar el servicio.


✅ 2. Warmup Manual (Precarga de Caché DNS)

Objetivo: Acelerar la primera resolución DNS para los usuarios, precargando dominios populares.

📁 Scripts creados en /opt/:

chmod +x /opt/warmup-*.sh

🔧 Modo de ejecución:

sudo /opt/warmup-fediverso.sh

✅ 3. Optimización del rendimiento con Unbound

Archivo: /etc/unbound/unbound.conf

Se añadieron parámetros para aprovechar los 4 núcleos del VPS:

server:
  interface: 127.0.0.1
  port: 5335
  do-ip4: yes
  do-udp: yes
  do-tcp: yes
  access-control: 127.0.0.0/8 allow

  # Optimización
  num-threads: 4
  so-reuseport: yes

  # Seguridad y rendimiento
  root-hints: "/var/lib/unbound/root.hints"
  hide-identity: yes
  hide-version: yes
  qname-minimisation: yes
  harden-glue: yes
  harden-dnssec-stripped: yes
  prefetch: yes
  prefetch-key: yes

📌 Se reinició el servicio y se comprobó la activación de los hilos:

ps -eLf | grep unbound

✅ 4. Validaciones con dig

Se probó con múltiples dominios para comprobar el efecto de la caché:

dig @127.0.0.1 -p 5335 duckduckgo.com +stats
dig @127.0.0.1 -p 5335 mastodon.social +stats
dig -x 142.250.200.110 @127.0.0.1 -p 5335

🟢 Respuestas en 0 ms en las consultas cacheadas.


✅ 5. Preparación para automatización

Se instaló cron:

sudo apt install cron

📌 Pendiente: crear entradas crontab para ejecutar los scripts periódicamente.


🔜 Pendientes


---

**Próximo paso recomendado:**  
Si tras unos días no se detectan errores, pasar el perfil `AppArmor` de AdGuard Home a modo `enforce`:
```bash
sudo aa-enforce /etc/apparmor.d/usr.bin.adguardhome

### 🔧 Cambios aplicados – Junio 2025 (Parte 2)

- **Validación completa de DNSSEC** con `unbound-anchor` y limpieza del archivo `root.key` corrupto.
- **Unbound configurado como full resolver** con caché optimizada (`cache-min-ttl: 3600`, `cache-max-ttl: 86400`), `prefetch` y `prefetch-key` habilitados para máxima velocidad en consultas recurrentes.
- Añadida opción de **precarga manual de caché** mediante script `warmup.sh` para acelerar respuestas a dominios críticos como `mastodon.social`, `liberapay.com`, `google.com`, `microsoft.com` y medios alternativos.

---

Libre · Seguro · Privado · Transparente

Cambios aplicados - Junio 2025 (DNS1)

✅ Activación de IPv6 en AdGuard Home

Se reactivó correctamente la escucha en direcciones IPv6 tras corregir conflictos de duplicación y errores de sintaxis en AdGuardHome.yaml.

Verificado con kdig y resolución externa por DoT y DoQ. Firewall actualizado para permitir tráfico IPv6.

✅ AppArmor en modo enforce

Tras pruebas exhaustivas con el perfil en modo complain, se aplicó enforce sin errores DENIED.

Archivo de perfil activo: /etc/apparmor.d/usr.bin.adguardhome

✅ Configuración de unbound-control

Se ha activado unbound-control para la gestión avanzada del resolver y verificación en caliente de la caché, estadísticas y estado DNSSEC.

El socket de control se encuentra operativo en /var/run/unbound.sock.

🔍 Verificación y estado

📊 Recursos

⏭️ Estado actual

Con estos cambios, el servidor DNS1 (cloud-server-0) está completamente desplegado en producción, validado y sin tareas pendientes.

🛰️ Servidor DNS2 – Hetzner (Finlandia)

📌 Infraestructura

🚀 Estado de despliegue

🔁 Objetivo

Proveer redundancia geográfica con ubicación en Europa del Norte, mejorar tiempos de respuesta en el norte de Europa, y preparar una futura arquitectura con balanceo por round robin o clúster DNS.