Servidor DNS público libre, cifrado y con enfoque en la privacidad, desplegado sobre infraestructura europea.
Para navegadores:
network.trr.uri = https://dns.rocksdns.ovh/dns-queryhttps://dns.rocksdns.ovh/dns-queryPara Android:
dns.rocksdns.ovhVerificación:
curl -H "Accept: application/dns-json" "https://dns.rocksdns.ovh/dns-query?name=example.com&type=A"
| 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% |
| 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 |
Cadena de resolución actual:
Cliente → AdGuard Home (443/853/784) → Unbound (127.0.0.1:5335) → Root Servers → TLD → Autoritativo
Estado:
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:
# 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/
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
[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
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
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
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
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
| 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 |
# Crontab
0 2 * * 1 /usr/bin/certbot renew --quiet && /bin/systemctl reload AdGuardHome
#!/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
# 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é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
Arquitectura:
Seguridad:
Operaciones:
Principios fundamentales:
# 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.
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
Mejoras aplicadas tras validación completa en entorno productivo:
complain, sin denegaciones registradas.root.key para DNSSEC tras conflicto por duplicación de anclas.prefetch, prefetch-keycache-min-ttl: 3600, cache-max-ttl: 86400dnssec-failed.org devuelve SERVFAIL como se esperacloudflare.com resuelve con datos DNSSEC válidoscomplainenforceDENIED tras varias horas en producciónchroot: "" en Unbound permite correcta actualización de anclas# 🧾 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.
Objetivo: Acelerar la primera resolución DNS para los usuarios, precargando dominios populares.
📁 Scripts creados en /opt/:
warmup-fediverso.sh → Mastodon, Pixelfed, PeerTube, etc.warmup-medios.sh → Prensa y medios libres.warmup-correo.sh → Proton, Tutanota, Disroot, Mailbox.org…warmup-gafam.sh → Sitios mainstream (Google, Apple, etc.)warmup-buscadores.sh → DuckDuckGo, Searx, Brave Search…warmup-mensajeria.sh → Signal, Matrix, XMPP, Session…warmup-prensa.sh → Medios generalistas no libres.chmod +x /opt/warmup-*.sh
🔧 Modo de ejecución:
sudo /opt/warmup-fediverso.sh
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
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.
Se instaló cron:
sudo apt install cron
📌 Pendiente: crear entradas crontab para ejecutar los scripts periódicamente.
---
**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 · TransparenteSe 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.
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
unbound-controlSe 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.
127.0.0.1:5335.journalctl ni alertas de seguridad activas.Con estos cambios, el servidor DNS1 (cloud-server-0) está completamente desplegado en producción, validado y sin tareas pendientes.
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.