En el siguiente post, vamos a configurar unbound para bloquear publicidad, dominios maliciosos y lo que queramos. Los bloqueos se realizarán a nivel de resolución DNS, retornando una IP incorrecta a los clientes que consulten un dominio que se encuentre en una de las blacklist de unbound.

Una blacklist es un listado de dominios para los que no devolveremos su IP real, de forma que el navegador o aplicación no cargue el contenido. Dependiendo de las listas que carguemos, podemos mejorar nuestra experiencia en la red de distintas maneras:

  1. Eliminar anuncios.
  2. Mejorar nuestra privacidad.
  3. Optimizar el uso de datos de red.
  4. Controlar el acceso a ciertos dominios.

Para empezar a cargar nuestras blacklist, partiremos de un servidor DNS recursivo configurado y sirviendo las peticiones de los clientes en nuestra red local. Podemos seguir los pasos que hay en el post Unbound: nuestro propio servidor DNS recursivo.


Crear una blacklist de forma manual

Unbound por defecto carga todos los ficheros de configuración en el directorio /etc/unbound/unbound.conf.d/, para crear una blacklist simplemente creamos un fichero en el directorio anterior con el siguiente contenido:

$ cat /etc/unbound/unbound.conf.d/my-blacklist.conf
server:
  local-zone: "facebook.com" always_nxdomain

Con la configuración anterior, indicamos que si no existe una entrada local indicando la IP del dominio, se retornará un mensaje NXDOMAIN, que significa que el dominio no existe.

Si antes de reiniciar unbound pedimos a nuestro servidor DNS que nos resuelva el dominio facebook.com, obtendremos su IP real:

$ dig facebook.com

; <<>> DiG 9.11.5-P4-5.1+deb10u3-Debian <<>> facebook.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17322
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;facebook.com.			IN	A

;; ANSWER SECTION:
facebook.com.		300	IN	A	31.13.83.36

;; Query time: 17 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Apr 03 18:04:25 CEST 2021
;; MSG SIZE  rcvd: 57

Ahora vamos a reiniciar unbound para cargar la blacklist y resolver de nuevo el dominio facebook.com:

$ sudo systemctl restart unbound.service
$ dig facebook.com

; <<>> DiG 9.11.5-P4-5.1+deb10u3-Debian <<>> facebook.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 12673
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;facebook.com.		IN	A

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Apr 03 22:23:53 CEST 2021
;; MSG SIZE  rcvd: 49

Con este ejercicio, hemos verificado el funcionamiento de una blacklist en unbound, dejando de resolver la verdadera dirección IP del dominio. Ahora, nadie usando nuestro servidor DNS podrá acceder a facebook.com.

Podemos añadir tantos dominios como queramos en el fichero anterior siguiendo la misma sintaxis:

local-zone: "DOMINIO" always_nxdomain

Configurar una blacklist de la comunidad

Actualmente podemos encontrar multitud de blacklist por internet, por ejemplo Steven Black, que contiene distintas blacklist para anuncios, redes sociales, webs sospechosas de publicar fake news, etc.

La idea es descargar una de estas listas que se actualizan periódicamente y configurarla para funcionar en nuestro servidor DNS. El problema es que no están en el formato que vimos en el punto anterior, por lo que hay que procesarlas y adecuarlas al formato esperado por unbound.

Para automatizar lo anterior, he preparado un pequeño script que descarga y genera una configuración válida de unbound.

Descargamos el script que se encuentra en github:

$ git clone https://github.com:alexsotoaguilera/unbound-blacklist.git

Generamos un paquete .deb para que sea más sencillo y limpio instalar o desinstalar el script y servicio (podemos instalarlo manualmente si lo preferimos):

$ cd unbound-blacklist
$ dpkg-deb --build --root-owner-group unbound-blacklist

Instalamos el paquete generado:

$ sudo dpkg -i unbound-blacklist.deb

En los logs del sistema veremos lo siguiente:

$ systemctl status unbound-blacklist-updater.service
● unbound-blacklist-updater.service - Unbound blacklist updater
   Loaded: loaded (/etc/systemd/system/unbound-blacklist-updater.service; static; vendor preset: enabled)
   Active: inactive (dead) since Sun 2021-04-04 19:03:45 CEST; 2min 50s ago
  Process: 26762 ExecStart=/usr/local/bin/unbound-blacklist (code=exited, status=0/SUCCESS)
  Process: 26765 ExecStart=/bin/systemctl stop unbound.service (code=exited, status=0/SUCCESS)
  Process: 26803 ExecStart=/bin/systemctl start unbound.service (code=exited, status=0/SUCCESS)
 Main PID: 26803 (code=exited, status=0/SUCCESS)

Apr 04 19:03:42 raspberrypi systemd[1]: Starting Unbound blacklist updater...
Apr 04 19:03:43 raspberrypi unbound-blacklist[26762]: unbound-checkconf: no errors in /tmp/tmpv9w9ssvg
Apr 04 19:03:44 raspberrypi unbound-blacklist[26762]: Info: generating stevenblack blacklist configuration file for unbound.
Apr 04 19:03:44 raspberrypi unbound-blacklist[26762]: Info: downloading blacklist https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts.
Apr 04 19:03:44 raspberrypi unbound-blacklist[26762]: Info: configuration file is valid and will be installed on /etc/unbound/unbound.conf.d/unbound-blacklist_stevenblack.con
Apr 04 19:03:45 raspberrypi systemd[1]: unbound-blacklist-updater.service: Succeeded.
Apr 04 19:03:45 raspberrypi systemd[1]: Started Unbound blacklist updater.

Como se ve en los logs, el script, ha descargado la blacklist, ha generado un fichero de configuración compatible con unbound y ha reiniciado el servidor para aplicar los cambios. Por lo que ya tenemos todo instalado y funcionando.

Además de lo anterior, se ha configurado un timer de systemd que actualizará la lista cada 24 horas.

Si queremos usar una lista distinta, simplemente modificamos la configuración localizada en /etc/unbound-blacklist/config.json