Ir al contenido
  1. Posts/

Pi-hole + Unbound: DNS y ad-blocking en tu red local

·2281 palabras·11 mins
Tabla de contenido

Llevo años usando Pi-hole en mi red doméstica y es una de esas cosas que instalas una vez y te preguntas cómo vivías sin ella. Ver cómo desaparecen los anuncios de todos los dispositivos conectados (móviles, tablets, smart TVs) sin tocar nada en ellos es satisfactorio. Y cuando le añades Unbound como DNS recursivo, conviertes tu homelab en una fortaleza de privacidad.

Esta guía nace de mi experiencia real. He pasado por varios despliegues de Pi-hole (en Raspberry Pi, en containers Docker, en VMs) y he cometido todos los errores posibles. Aquí te cuento lo que funciona.

Por qué Pi-hole en tu homelab
#

Pi-hole es un servidor DNS que actúa como agujero negro para peticiones a dominios de publicidad y trackers. En lugar de bloquear anuncios en el navegador (como hace uBlock Origin), los bloqueas a nivel de red antes de que lleguen a cualquier dispositivo.

Ventajas reales que noto cada día:

  1. Los anuncios desaparecen de TODO: aplicaciones móviles, YouTube en la smart TV, banners en webs, anuncios in-app. Si el dispositivo está en tu red, está protegido.

  2. Mejora la velocidad: tu conexión no descarga megas de scripts publicitarios. En mi caso, Pi-hole bloquea entre 15% y 25% del tráfico DNS diario. Son gigas de basura que nunca llegan.

  3. Protección para dispositivos “tontos”: smart TVs, asistentes de voz, cámaras IoT. Muchos no tienen forma de instalarles bloqueadores, pero con Pi-hole quedan cubiertos.

  4. Visibilidad del tráfico: la interfaz de Pi-hole te muestra qué dispositivos generan más peticiones DNS y a qué dominios. Es educativo y a veces inquietante. Mi TV Samsung intenta conectar a servidores de telemetría cada 3 minutos.

  5. Sin suscripciones ni pagos: una vez instalado, es gratis y autónomo. NextDNS y servicios similares son buenos pero cobran pasados los límites.

Unbound: el complemento perfecto
#

Por defecto, Pi-hole usa servidores DNS externos (Google 8.8.8.8, Cloudflare 1.1.1.1, etc.) para resolver dominios legítimos. El problema es que esos proveedores ven todas tus consultas DNS. Saben cada web que visitas.

Unbound cambia eso. Es un DNS recursivo que hace las consultas directamente a los servidores raíz autoritativos de Internet. Tu Pi-hole pregunta a Unbound, Unbound pregunta al root DNS, y ningún tercero se entera de qué webs visitas.

Diagrama simplificado del flujo:

1
Dispositivo → Pi-hole (bloqueo) → Unbound (recursivo) → DNS raíz

Con esta configuración, tu homelab tiene control total del DNS. Cero dependencias de Google, Cloudflare o quien sea.

Requisitos previos
#

Necesitas:

  • Hardware: Raspberry Pi 3/4/5 (lo más común), o cualquier VM/container en tu servidor. Yo uso un container Docker en mi cluster K3s porque me resulta más cómodo gestionar.

  • Sistema operativo: Debian o Ubuntu. Pi-hole también funciona en Fedora, CentOS y otros, pero en Debian la documentación es más sólida.

  • IP estática: tu Pi-hole tiene que tener una IP fija en tu red. Si usas DHCP y cambia la IP, todos tus dispositivos pierden el DNS.

  • Acceso al router: vas a tener que cambiar el servidor DNS en la configuración DHCP del router para que todos los dispositivos nuevos que se conecten usen Pi-hole automáticamente.

  • 30 minutos de tiempo: la instalación básica lleva 10 minutos. Configurar Unbound otros 15. Ajustar listas y whitelists puede ser un proceso iterativo.

Instalación de Pi-hole
#

Voy a documentar tres métodos: instalación nativa en Raspberry Pi, Docker Compose, y despliegue en Kubernetes (que es como lo tengo yo ahora). Elige el que mejor se adapte a tu setup.

Método 1: Instalación nativa en Raspberry Pi
#

Este es el clásico. Flasheas Raspberry Pi OS Lite en una SD, conectas el Pi por Ethernet (wifi funciona pero Ethernet es más estable para un servidor DNS), y ejecutas el instalador oficial.

1
2
3
4
5
# Actualizar el sistema
sudo apt update && sudo apt upgrade -y

# Descargar e instalar Pi-hole
curl -sSL https://install.pi-hole.net | bash

El instalador es interactivo. Te pregunta:

  1. Interfaz de red: elige eth0 si usas Ethernet.
  2. Proveedor DNS: da igual, luego configuraremos Unbound.
  3. Listas de bloqueo: deja las predeterminadas por ahora.
  4. Protocolo IP: IPv4 + IPv6 si tu red lo soporta, o solo IPv4.
  5. IP estática: el instalador puede configurarla o puedes hacerlo luego en /etc/dhcpcd.conf.
  6. Interfaz web: sí, la querrás.

Al terminar, te da la contraseña del panel web. Apúntala. Accede desde tu navegador a http://<IP-DEL-PI>/admin.

Método 2: Docker Compose
#

Si prefieres containers (como yo la mayoría del tiempo), aquí va un docker-compose.yml funcional:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
version: "3.8"

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "67:67/udp"  # DHCP (opcional)
      - "8080:80/tcp"  # Web UI
    environment:
      TZ: 'Europe/Madrid'
      WEBPASSWORD: 'tu-password-segura'
      FTLCONF_LOCAL_IPV4: '192.168.0.10'  # Tu IP estática
      PIHOLE_DNS_: '127.0.0.1#5335'  # Apunta a Unbound local
    volumes:
      - './etc-pihole:/etc/pihole'
      - './etc-dnsmasq.d:/etc/dnsmasq.d'
    cap_add:
      - NET_ADMIN
    restart: unless-stopped

Levántalo con:

1
docker-compose up -d

Accede a http://<IP>:8080/admin.

Método 3: Kubernetes (avanzado)
#

En mi cluster K3s tengo Pi-hole como un Deployment con un Service tipo LoadBalancer (usando MetalLB para asignarle una IP fija). No voy a pegar todo el YAML aquí porque ocupa, pero los puntos clave son:

  • PersistentVolumeClaim para /etc/pihole y /etc/dnsmasq.d (para que sobreviva a reinicios del pod).
  • Service tipo LoadBalancer en el puerto 53 UDP/TCP y 80 TCP.
  • ConfigMap con variables de entorno (TZ, WEBPASSWORD, DNS, etc.).
  • Unbound en un pod separado con su propio Service tipo ClusterIP en el puerto 5335.

Si te interesa esta ruta, hay charts de Helm disponibles (mojo2600/pihole) que simplifican el proceso.

Instalación de Unbound
#

Unbound es más simple. Si estás en el mismo sistema que Pi-hole (Raspberry Pi, VM), instala el paquete:

1
sudo apt install unbound -y

Configura Unbound editando /etc/unbound/unbound.conf.d/pi-hole.conf (crea el archivo si no existe):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
server:
    # Escuchar solo en localhost
    interface: 127.0.0.1
    port: 5335
    
    # Responder solo a consultas locales
    access-control: 127.0.0.1/32 allow
    access-control: ::1 allow
    
    # Ocultar información del servidor
    hide-identity: yes
    hide-version: yes
    
    # Optimizaciones de caché
    cache-min-ttl: 3600
    cache-max-ttl: 86400
    
    # Usar TCP para consultas grandes
    do-tcp: yes
    
    # Validación DNSSEC
    module-config: "validator iterator"
    auto-trust-anchor-file: "/var/lib/unbound/root.key"
    
    # Prefetch dominios populares
    prefetch: yes
    prefetch-key: yes
    
    # Threads (ajusta según tus cores)
    num-threads: 2
    
    # Root hints
    root-hints: "/var/lib/unbound/root.hints"

Descarga el archivo de root hints (lista de servidores DNS raíz):

1
sudo curl -o /var/lib/unbound/root.hints https://www.internic.net/domain/named.root

Reinicia Unbound:

1
2
sudo systemctl restart unbound
sudo systemctl enable unbound

Verifica que esté escuchando:

1
sudo netstat -nlp | grep unbound

Deberías ver algo como:

1
2
udp   0.0.0.0:5335   0.0.0.0:*   12345/unbound
tcp   0.0.0.0:5335   0.0.0.0:*   12345/unbound

Unbound en Docker
#

Si usas Docker, añade este servicio a tu docker-compose.yml:

1
2
3
4
5
6
7
8
9
  unbound:
    container_name: unbound
    image: mvance/unbound:latest
    ports:
      - "5335:53/tcp"
      - "5335:53/udp"
    volumes:
      - './unbound:/opt/unbound/etc/unbound'
    restart: unless-stopped

Luego crea ./unbound/unbound.conf con la configuración de arriba (cambiando interface: 0.0.0.0 para que escuche en todas las interfaces del container).

Configurar Pi-hole para usar Unbound
#

En el panel web de Pi-hole:

  1. Ve a SettingsDNS.
  2. Desmarca todos los “Upstream DNS Servers” (Google, Cloudflare, etc.).
  3. Marca Custom 1 (IPv4) e introduce 127.0.0.1#5335 (o la IP del container de Unbound si usas Docker en redes separadas).
  4. Desmarca Use DNSSEC (Unbound ya lo hace).
  5. Guarda.

Comprueba que funciona ejecutando desde tu Pi-hole:

1
dig @127.0.0.1 -p 5335 example.com

Deberías recibir una respuesta válida. Si ves SERVFAIL, revisa los logs de Unbound:

1
sudo journalctl -u unbound -f

Configurar tu red para usar Pi-hole
#

Ahora toca que todos tus dispositivos usen Pi-hole como DNS. Tienes dos opciones:

Opción 1: Configurar el DHCP del router (recomendado)
#

Accede a la interfaz web de tu router (normalmente 192.168.0.1 o 192.168.1.1) y busca la sección DHCP. Los nombres varían: “LAN”, “DHCP Server”, “Network Settings”.

Cambia el Primary DNS Server a la IP de tu Pi-hole (por ejemplo, 192.168.0.10). Deja el Secondary DNS vacío o ponlo a 1.1.1.1 como fallback (aunque eso rompe un poco el propósito de privacidad).

Guarda y reinicia el router. Los dispositivos que se reconecten obtendrán la nueva configuración automáticamente.

Opción 2: Configurar manualmente cada dispositivo
#

Si no tienes acceso al router o prefieres probar antes, configura el DNS manualmente en tu ordenador, móvil, etc.

En Linux/Mac, editas /etc/resolv.conf:

1
nameserver 192.168.0.10

En Windows, vas a “Configuración de red” → “Adaptador de red” → “Propiedades IPv4” → “Usar los siguientes servidores DNS”.

En Android/iOS, en la configuración de wifi puedes cambiar el DNS.

Ajustar listas de bloqueo
#

Por defecto, Pi-hole trae listas de bloqueo básicas. Puedes añadir más desde Group ManagementAdlists en el panel web.

Listas que uso (y recomiendo):

  1. StevenBlack Unified Hosts (viene por defecto, 150k+ dominios bloqueados).
  2. OISD Big List: https://big.oisd.nl/ (muy completa, 1M+ dominios, agresiva pero efectiva).
  3. HaGeZi Pro: https://raw.githubusercontent.com/hagezi/dns-blocklists/main/domains/pro.txt (bien mantenida, equilibrada).
  4. Energized Blu: https://block.energized.pro/blu/formats/domains.txt (más enfocada en trackers).

Después de añadir listas, ve a ToolsUpdate Gravity para aplicar los cambios. El proceso puede tardar un par de minutos si añadiste listas grandes.

Whitelist: dominios que NO quieres bloquear
#

Algunas listas son demasiado agresivas y rompen cosas. Ejemplos comunes:

  • Microsoft Telemetry: si bloqueas todo de Microsoft, Windows Update puede fallar. Yo permito *.microsoft.com y *.windows.com.
  • Smart TVs: algunas apps (Netflix, Prime Video) usan dominios de tracking para analytics. Si los bloqueas, la app puede no cargar contenido.
  • Apps bancarias: muchas usan SDKs de tracking (Adjust, AppsFlyer). Si las bloqueas, la app puede crashear o no dejarte hacer login.

Añade dominios a la whitelist desde Whitelist en el panel web, o vía CLI:

1
pihole -w example.com

Mi consejo: empieza con listas moderadas y ve añadiendo más. Si algo deja de funcionar, revisa el Query Log de Pi-hole para ver qué dominios se bloquearon justo antes del fallo.

Monitorización y estadísticas
#

El dashboard de Pi-hole es adictivo. Muestra:

  • Total de consultas: cuántas peticiones DNS ha procesado hoy.
  • Consultas bloqueadas: porcentaje y número absoluto.
  • Top clientes: qué dispositivos generan más tráfico DNS.
  • Top dominios bloqueados: qué anunciantes intentan colarte más basura.
  • Top dominios permitidos: a qué webs legítimas accedes más.

En mi caso, el porcentaje de bloqueo oscila entre 18% y 28% según el día. Los fines de semana sube (más tiempo navegando, más apps abiertas).

Troubleshooting común
#

Algunos sitios no cargan
#

Revisa el Query Log. Si ves dominios legítimos bloqueados (ejemplo: *.example.com en rojo), añádelos a la whitelist.

Pi-hole deja de responder
#

Si usas Raspberry Pi, comprueba la SD. Las SDs baratas se corrompen con el tiempo. Considera pasarte a un SSD via USB.

Si usas Docker, revisa que no haya conflictos de puertos. El puerto 53 suele estar ocupado por systemd-resolved en Ubuntu. Deshabilítalo:

1
2
3
4
sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
sudo rm /etc/resolv.conf
sudo echo "nameserver 1.1.1.1" > /etc/resolv.conf

Rendimiento lento
#

Unbound puede ser pesado si tienes muchos dispositivos. Aumenta num-threads en la configuración de Unbound y asegúrate de que cache-min-ttl esté en al menos 3600.

También puedes habilitar DNSSEC en Unbound para validar respuestas (más seguro pero más lento). Yo lo tengo activado porque el impacto es mínimo en mi setup.

Dispositivos que ignoran Pi-hole
#

Algunas apps (Google Chrome, algunas apps de Android) tienen DNS hardcodeado (usan 8.8.8.8 sin importar la configuración de red). Solución:

  • En tu firewall/router, bloquea el puerto 53 hacia fuera EXCEPTO desde la IP de Pi-hole. Así fuerzas a todos los dispositivos a usar tu DNS.
  • Configura reglas de NAT que redirijan cualquier petición al puerto 53 hacia Pi-hole.

En OPNsense o pfSense es trivial. En routers domésticos no siempre es posible.

Backup y recuperación
#

Haz backups periódicos de la configuración de Pi-hole. Desde el panel web: SettingsTeleporterBackup.

Descarga el archivo .tar.gz. Contiene todas tus listas, whitelist, configuraciones. Si tu Pi muere, instalas Pi-hole en otro lado y restauras ese archivo.

Si usas Docker, los volúmenes ./etc-pihole y ./etc-dnsmasq.d YA son tu backup. Solo cópialos a otro sitio.

Extras: Pi-hole como DHCP server
#

Pi-hole puede reemplazar el servidor DHCP de tu router. Ventaja: asigna IPs y configura el DNS en un solo paso. Desventaja: si Pi-hole cae, nadie en tu red obtiene IP.

Solo actívalo si tienes redundancia (dos Pi-holes en HA, por ejemplo). En mi caso prefiero dejar el DHCP en el router y solo apuntar el DNS a Pi-hole.

Alternativas y comparaciones
#

NextDNS: servicio en la nube, muy bueno, pero limitado a 300k consultas/mes en el plan gratuito. Yo supero eso en una semana.

AdGuard Home: similar a Pi-hole pero escrito en Go (Pi-hole es PHP). Más moderno, más rápido en teoría, pero con menos comunidad. He probado ambos y me quedo con Pi-hole por la madurez del ecosistema.

pfBlockerNG (en pfSense/OPNsense): si ya tienes un firewall dedicado, esto es más potente. Bloquea a nivel de firewall, no solo DNS. Pero requiere hardware más robusto.

Conclusión: vale cada minuto invertido
#

Montar Pi-hole + Unbound es de esas cosas que haces una vez y te cambia la experiencia de navegación para siempre. Cero anuncios en el móvil, cero trackers en la smart TV, cero telemetría de apps que no controlo.

El esfuerzo inicial (30 minutos, siendo generoso) se amortiza en la primera semana. Y luego lo olvidas porque simplemente funciona. De vez en cuando entro al dashboard a cotillear las estadísticas, pero fuera de eso es transparente.

Si tienes un homelab (o aunque no lo tengas, con una Raspberry Pi vale), monta esto. Tu privacidad y tu ancho de banda te lo agradecerán.


Recursos útiles: