PiHole desde un contenedor Podman

Desde hace unos días he estado haciendo algunas modificaciones a mi homelab y la red. A raíz de las polémicas recientes entre IBM/Red Hat y la comunidad, he terminado explorando Red Hat Enterprise Linux para uso en varios de mis mini servidores, entre ellos, hobbiton que ahora tiene RHEL 9.2. Salvando algunas diferencias con respecto a mi habitual uso de Debian GNU/Linux en mis servidores y Fedora /Arch Linux en algunas de mis Thinkpads termine reconstruyendo todo.

RHEL 9.2 trae podman para gestionar contenedores de manera predeterminada, así que decidí aprender algo sobre la marcha y hacer docker a un lado. Este cambio trae algunas consecuencias, sobre todo porque no se ejecuta como un daemon, sino en espacio de usuario y hay que tomar algunos workarounds para gestionar los contenedores que impactan puertos de red <1024 por tema de permisos.

Estuve explorando la opción que plantea Juanma en su blog, pero el tráfico aparece en el PiHole como proveniente en su totalidad del localhost y no separado por cliente como ocurre normalmente.

Lo primero, es el tema de los puertos. El PiHole funciona con varios puertos como indica la documentación, para el fin que persigo, limpiar la red de la casa de los molestos ads solo necesito hacer andar el puerto 53 que esta destinado al DNS. Los puertos 53/tcp y 53/udp requieren permisos de superusuario para su uso, pero esto se puede solucionar con un forward en el firewall hacia un puerto no privilegiado.

1
2
3
4
sudo firewall-cmd --zone=public --add-forward-port=port=53:proto=tcp:toport=1053:toaddr= --permanent
sudo firewall-cmd --zone=public --add-forward-port=port=53:proto=udp:toport=1053:toaddr= --permanent

sudo firewall-cmd --reload

Lo siguiente es editar el comando original de ejecución de docker (aquí hay una excelente explicación sobre esto), pero antes necesitaremos crear dos volumenes.

1
2
podman volume create pihole_pihole
podman volume create pihole_dnsmasq

Finalmente estando en la cli, lanzo el comando podman run ... tal cual se muestra a continuación:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
podman run -d \
--name pihole \
--hostname=pihole \
--cap-add=NET_ADMIN \
--net=slirp4netns:port_handler=slirp4netns \
--dns=1.1.1.1 \
--dns=1.0.0.1 \
-e TZ="America/Panama" \
-e SERVERIP=192.168.1.9 \
-e WEBPASSWORD=añadir-contraseña \
-e DNS1=1.1.1.1 \
-e DNS2=1.0.0.1 \
-e TEMPERATUREUNIT=c \
-v pihole_pihole:/etc/pihole:Z \
-v pihole_dnsmasq:/etc/dnsmasq.d:Z \
-p 1053:53/tcp \
-p 1053:53/udp \
-p 8080:80/tcp \
-e VIRTUAL_HOST="pihole" \
-e PROXY_LOCATION="pihole" \
-e INTERFACE="tap0" \
--security-opt label=disable \
pihole/pihole:latest

Ya después de todo, podremos conectarnos a nuestro pihole y verificar que todo funciona:

Interfaz web de PiHole corriendo con podman

Por si necesitamos cambiar la clave de login por una diferente a la que pusimos en los parámetros de podman:

1
podman exec -it pihole pihole -a -p

También podemos verificar que esta corriendo adecuadamente el contenedor en cockpit

Contenedor PiHole Visible desde cockpit

Ahora es momento de crear una unidad para systemd para que pihole inicie al arrancar el servidor. Antes debemos eliminar el contenedor que levantamos de prueba, pues con systemd será ejecutado por el superusuario y no queremos errores por contenedores que se llamen igual.

1
2
podman stop pihole
podman rm pihole

Necesitamos también habilitar los puertos en el firewall:

1
2
3
4
5
sudo firewall-cmd --permanent --zone=public --add-port=53/tcp
sudo firewall-cmd --permanent --zone=public --add-port=53/udp
sudo firewall-cmd --permanent --zone=public --add-port=8080/tcp

sudo firewall-cmd --reload

Podemos validar estos cambios y las redirecciones de puerto con el comando sudo firewall-cmd --list-all

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eno1
  sources:
  services: cockpit dhcpv6-client ssh
  ports: 53/tcp 53/udp 8080/tcp
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
    port=53:proto=tcp:toport=1053:toaddr=
    port=53:proto=udp:toport=1053:toaddr=
  source-ports:
  icmp-blocks:
  rich rules:

Ahora creamos el archivo /etc/systemd/system/pihole.service con el contenido a continuación:

1
2
3
4
5
6
7
8
9
10
Description=Pi-Hole Podman Container
After=firewalld.service

[Service]
ExecStart=/usr/bin/podman run --name pihole --hostname=pihole --cap-add=NET_ADMIN --net=slirp4netns:port_handler=slirp4netns --dns=1.1.1.1 --dns=1.0.0.1 -e TZ="America/Panama" -e SERVERIP=192.168.1.9 -e WEBPASSWORD=añadir-contraseña -e DNS1=1.1.1.1 -e DNS2=1.0.0.1 -e TEMPERATUREUNIT=c -v pihole_pihole:/etc/pihole:Z -v pihole_dnsmasq:/etc/dnsmasq.d:Z -p 1053:53/tcp -p 1053:53/udp -p 8080:80/tcp -e VIRTUAL_HOST="pihole" -e PROXY_LOCATION="pihole" -e INTERFACE="tap0" --security-opt label=disable pihole/pihole:latest
ExecStop=/usr/bin/podman stop -t 2 pihole
ExecStopPost=/usr/bin/podman rm pihole

[Install]
WantedBy=multi-user.target

Por último, necesitamos un ajuste en la configuración del PiHole, sin el cual no funciona ni identifica el tráfico. En Settings > DNS, vamos a la sección Interface settings y seleccionamos la opción Respond only on interface tap0. Esta opción debería habilitarse con el parámetro -e INTERFACE="tap0" pero por alguna razón no lo hace, una vez hecho y guardado el cambio, las siguientes veces que reiniciemos el contenedor no habrá que volver a hacer el ajuste a menos que eliminemos los volúmenes.

Habilitando la interfaz tap0

Finalmente seteamos el inicio del contenedor con systemd

1
2
3
systemctl daemon-reload
systemctl enable pihole.service
systemctl start pihole.service

Hasta aquí tendremos funcionando un contenedor con PiHole que hará desaparecer la mayor parte de la publicidad mientras navegas en la red de tu casa así como otros códigos maliciosos que podrían ejecutarse en un navegador. Para mejorar el PiHole en estos menesteres es necesario añadir otras listas de bloqueo, las listas que yo utilizo las importo desde aquí. Escogiendo 2 de cada sección, de las que están marcadas en verde.


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.
Moisés Serrano Samudio

@linkmoises

Médico de atención primaria, fotógrafo aficionado, apasionado de las tecnologías relacionadas con el EdTech y el eHealth.

Entradas relacionadas

  1. Aún no hay comentarios...

Deja una respuesta

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