Bloqueo de anuncios en el USG + Pihole

Anteriormente ya vimos como instalar PiHole en un contenedor Docker. Ahora mostraré una configuración más avanzada para que en caso de que PiHole por alguna razón caiga o deje de funcionar, el router UniFi Security Gateway (USG) tomé el mando y siga bloqueando anuncios. Este último modo no provee de estadística alguna, pero por lo menos permite navegar sin los molestos ads.

Leyendo en los foros de la comunidad de Ubiquiti existen varias maneras, todas válidas, de proveer bloqueo de anuncios publicitarios. En resumen, lo que vamos a hacer es lo siguiente. Aprovechar el servicio dnsmasq del USG, alimentarlo con un blacklist y programarlo para que se actualice regularmente.

Lo primero será conectarse al USG vía ssh.

$ ssh usuario@192.168.1.1

Una vez dentro, cambiamos a usuario root y luego al directorio scripts y descargamos el archivo zip donde está la lista negra.

$ sudo -i
# cd /config/scripts
# curl 'https://raw.githubusercontent.com/unifiMynet/dnsmasqAdBlock/master/getBlacklistHosts.V8.5.zip' > getBlacklistHosts.zip

Ahora extraemos el archivo

# unzip getBlacklistHosts.zip

Y eliminamos el archivo zip que acabamos de extraer y le damos permisos de ejecución al script getBlacklistHosts.sh y lo ejecutamos.

# rm getBlacklistHosts.zip
# chmod +x getBlacklistHosts.sh
# ./getBlackistHosts.sh

Una vez ejecutado, el script me da esta respuesta:

.    Starting getBlackListHosts V8.5...
.    Purging temporary files...

.    Created default data file which did not exist, the Blacklist Hosts have NOT been updated.
.    Next time the script runs the Blacklist Hosts will be updated.
.    This is so you can adjust settings in /config/scripts/getBlacklistHosts.conf before the first updates.
.    Once you have made changes (or not if you want the defaults), run this script again.

y crea un archivo llamado getBlacklistHosts.conf en el directorio que estamos. Podemos revisar y ajustar este script con vi getBlacklistHosts.conf, luego de afinar los detalles que queremos ejecutamos nuevamente el script con ./getBlacklistHosts.sh para que descargue la listas o actualice en caso que ya este instalado y corriendo. Luego de ejecutarlo por segunda vez, el bloqueo ya estará funcionando.

Actualización automática del script

Las listas de bloqueo cambian constantemente, razón por la cual si no las actualizamos nos dejarán de funcionar tarde o temprano. Para evitar esto, utilizaremos un archivo config.gateway.json en el cual le diremos al controlador (Cloud Key) que actualice la lista de manera diaria a una hora en específico.

El archivo config.gateway.json es un archivo que es persistente entre actualizaciones y cuando añadimos una tarea en él, verifica que el archivo exista y que tenga permisos de ejecución, de lo contrario fallará el aprovisionamiento, así que debemos tener este detalle claro si deseamos remover el script.

Ahora nos conectamos al Cloud Key vía SSH y vamos al directorio /usr/lib/unifi, luego cambiamos al directorio data/sites/default donde «default» sería el nombre de nuestro sitio, por lo que podría ser diferente si lo has cambiado.

$ ssh usuario@ip-cloud-key

  ___ ___      .__________.__
 |   |   |____ |__\_  ____/__|
 |   |   /    \|  ||  __) |  |   (c) 2013-2019
 |   |  |   |  \  ||  \   |  |   Ubiquiti Networks, Inc.
 |______|___|  /__||__/   |__|
            |_/                  http://www.ubnt.com

      Welcome to UniFi CloudKey!

Last login: Mon Mar  9 16:08:44 2020

$ cd /usr/lib/unifi
$ cd data/sites/default

En estos directorios existen varios archivos y directorios sensibles, así que cuidado con eliminar algún archivo por accidente. Ahora creamos el archivo config.gateway.json con este contenido:

# vim config.gateway.json
{
    "system": {
        "task-scheduler":{
            "task":{
                "hostblacklist":{"executable":{"path":"/config/scripts/getBlacklistHosts.sh"},"crontab-spec":"30 3 * * *"}
            }
        }
    }
}

El siguiente paso sería aprovisionar. Como este archivo no es leído inmediatamente se crea, debemos forzar el USG a aprovisionar para que se añada la tarea.

Vamos al Tablero de UniFi, luego a los dispositivos y hacemos click sobre el USG. Luego vamos a la pestaña «Config» y en el menú que se abre vamos a «Force provision»

Forzando el aprovisionamiento

Para verificar que el procedimiento fue exitoso, podemos ingresar vía SSH al USG y entramos al modo configuración y ejecutamos show system task-scheduler lo que nos mostrará la tarea que acabamos de crear.

root@USG:/config/scripts# configure
[edit]
root@USG# show system task-scheduler
 task hostblacklist {
     crontab-spec "30 3 * * *"
     executable {
         path /config/scripts/getBlacklistHosts.sh
     }
 }
[edit]
root@USG# exit

Y de este modo, hemos creado una tarea que se ejecuta a las 3:30 AM de cada día donde se actualiza la lista negra mediante un archivo config.gateway.json.

Añadiendo listas personalizadas

Lista blanca

Si existe un sitio que esta bloqueado por las listas que ya tenemos en el script y deseamos desbloquearlo, solo tenemos que crear el archivo dnswhitelist en el directorio /config/scripts y añadir en cada línea el host/dominio que deseamos desbloquear.

*dominio.com # desbloquea dominio y todos su subdominios
subdominio.dominio.com # desbloquea específicamente el subdominio

Lista negra

Si deseamos añadir un sitio a lista negra para ser bloqueado, solo tenemos que crear el archivo dnsblacklist en el directorio /config/scripts y añadir en cada línea el host/dominio que deseamos bloquear.

dominio.com # bloquea todo incluyendo subdominios
subdominio.dominio.com # bloquea solamente el subdominio específicado

Evitando que los clientes salten el bloqueo

Es posible navegar saltando el filtro del PiHole y del USG si cuando configuramos la conexión en el dispositivo, fijamos un DNS. Para evitar que esto ocurra, solo es cuestión de configurar nuestro USG para que las todas las peticiones DNS las obligue a pasar por el mismo USG así obteniendo un filtrado también para los rebeldes. Esto es útil sobre todo en dispositivos IoT donde no podemos controlar este aspecto y no sabemos si están compartiendo información sobre nosotros o nuestra red.

Para empezar vamos al tablero de UniFi, en el Cloud Key añadiremos los servidores DNS en la red LAN en orden de prioridad, primero el PiHole, luego el USG y en la red WAN utilizaremos los DNS que queramos, no la dirección del PiHole.

DNS del PiHole y USG en la red LAN
DNS de la red WAN

Ahora accedemos al panel de control del PiHole: pi.hole/admin. Una vez dentro vamos a Settings > DNS. En el campo Upstream DNS Servers añadimos en custom IPv4, la dirección de nuestro USG, en mi caso 192.168.1.1 y desactivamos cualquier otra opción.

Servidor DNS upstream personalizado con la ip del USG

Hasta este punto, tenemos configurada nuestra resolución de DNS, ahora solo falta forzar a los clientes rebeldes a pasar sus peticiones por nuestro DNS filtrado, para ello necesitaremos la ayuda nuevamente del archivo config.gateway.json, añadiendo este texto que básicamente lo que configura es una redirección de peticiones DNS.

    "service":{
        "nat":{
            "rule":{
                "1":{
                    "description": "Redirect DNS queries",
                    "destination":{
                        "port": "53",
                        "address": ["!192.168.1.9-192.168.1.1"]
                    },
                    "source":{
                        "address": ["!192.168.1.9-192.168.1.1"]
                    },
                    "inside-address": {
                        "address": ["192.168.1.9-192.168.1.1"],
                        "port": "53"
                    },
                    "inbound-interface": ["eth0"],
                    "protocol": "tcp_udp",
                    "type": "destination"
                },
                "5001": {
                    "description": "Translate reply back",
                    "destination": {
                        "address": ["192.168.1.9-192.168.1.1"],
                        "port": "53"
                    },
                    "outbound-interface": ["eth0"],
                    "protocol": "tcp_udp",
                    "type": "masquerade"
                }
            }
        }
    }

El objeto service añadido lo que hace es verificar si la petición DNS va dirigida a nuestro DNS, si no es así, la redirecciona tanto al PiHole como al USG. Si el PiHole, no está disponible por alguna razón, el USG continua con el bloqueo como ya lo hemos configurado previamente.

Ahora solo es cuestión de aprovisionar el USG nuevamente y ya estaremos filtrando las peticiones DNS de cualquier cliente rebelde.

Removiendo el script

Remover este script es un poco laborioso considerando que existen varios archivos que hay que buscar manualmente para borrar. Lo primero es eliminar la tarea, ya sea que la eliminemos del archivo config.gateway.json o desde el mismo USG mediante comandos.

$ sudo -i
$ configure
$ delete system task-scheduler task hostblacklist
$ commit
$ save
$ exit

Ahora, eliminamos las listas generadas y reiniciamos dnsmasq

sudo -i
rm /etc/dnsmasq.d/blackhost*
/etc/init.d/dnsmasq force-reload
exit

Por último, eliminamos los archivos generados por el script. Según las opciones que tengamos activadas, puede que no todos los archivos de esta lista existan.

sudo -i
rm /var/log/getBlackListHosts.log
rm /config/scripts/dnswhitelist
rm /config/scripts/dnsblacklist
rm /config/scripts/getBlacklistHosts.oldcount
rm /config/scripts/getBlacklistHosts.currentcount
rm /config/scripts/BlacklistHistoryCount.txt
rm /config/scripts/getBlacklistHosts.sh
rm /config/scripts/getBlacklistHosts.conf
rm /config/scripts/nonFilteredHosts
rm /config/scripts/filteredHosts
rm /config/scripts/finalHosts
rm /tmp/tmp.gzippedhosts.tar.gz
rm /etc/dnsmasq.d/getBlacklistOptions.conf
rm /config/scripts/getBlacklistPostRun.sh
exit

Al completar todos los pasos anteriores eliminamos por completo la presencia del script en nuestro USG. El script de bloqueo fue extraído desde los foros de la comunidad de Ubiquiti, el contenido original esta disponible aquí.


avatar
Moisés Serrano Samudio Médico de atención primaria, fotógrafo aficionado, apasionado de las tecnologías relacionadas con el EdTech y el eHealth y diseñador/desarrollador de sitios web de salud. Médico, apasionado del EdTech/eHealth y diseñador/desarrollador de sitios web de salud.

Comentarios

Deja una respuesta

Su email no será publicado. Required fields are marked *