VPN con WG-easy y PiHole
Hace un tiempo venía con ganas de meter una forma de acceder a la red de casa desde afuera, por varios motivos:
- En casa tengo PiHole corriendo, y me viene bien tenerlo desde el teléfono fuera de casa.
- A veces estoy en una red no segura y quiero hacer cosas sin preocuparme tanto.
- Quiero poder hacer SSH dentro de casa sin tener que abrir puertos al exterior
El punto 2 lo podría resolver con cualquier VPN, de las que hay miles. Pero el 1 y el 3 no, así que por qué no aprovechar el servidor que ya tengo corriendo.
WG-easy
Miré varias opciones de VPN, pero la verdad es que WG-easy hace todo lo que necesito, y es bien sencilla de instalar. Sólo agregué esto a mi docker-compose.yml:
| |
Es copiado de la documentación de wg-easy, y modificado para mi caso de uso.
Mis modificaciones son:
- Puse la interfaz de administración en un virtual host
- Creé dos redes de docker para el container
Sobre lo segundo, no sé qué tanta seguridad extra me da, pero me siento más cómodo si cada par de contenedores de docker que se tiene que comunicar entre sí tiene una red dedicada para eso. Entonces, para cada servicio que tengo expuesto, tengo una red proxy-{servicio}, y para cada servicio que usa postgres tengo una red psql-{servicio}, y así para smtp, redis, y otros servicios que interactúan entre sí. En este caso, tengo dos redes para wg-easy: una para comunicarse con el proxy, para que funcione el virtual host, y la otra para comunicarse con pihole, que fue la solución que encontré para que funcione el DNS (que, al final, era lo que quería).
Después de levantar el nuevo servicio, entrás a la web de administración, creás usuario y contraseña de administrador, un par de toques de configuración guiada, y estás. Sólo tenés que crear un cliente y configurar tu dispositivo para entrar a la VPN, y lo básico anda.
Desde el teléfono
Para entrar desde el teléfono usé WG Tunnel.
Desde WG Tunnel creás la conexión escaneando un QR que te da WG-easy. Una papa todo.
El maldito DNS y la madre que lo parió
Hasta acá, todo venía re bien, rápido, y sin problemas. Todo simplemente “andaba”, bien fácil. Pero el DNS no andaba bien. Podía conectarme a cualquier otro DNS (por ejemplo, el de Google, o incluso el de mi router que es el “upstream” de mi PiHole), sin ningún problema, pero a PiHole no andaba.
Después de mucha prueba y error usando dig (gracias a termux), encontré los siguientes datos:
| |
Donde $servidor es la IP del servidor donde corro mis contenedores docker, y $router es la IP del router.
Desde la red local, sin la VPN, la resolución en $servidor no tenía ningún problema. El problema era sólo dentro de la VPN, y no sé por qué. Además, resolver usando TCP funcionaba bien, sólo con UDP tenía el problema.
Todavía no sé cuál es el problema. Se escapa un poco de mis conocimientos. Parece estar relacionado con que tanto wg-easy como PiHole están corriendo en distintos contenedores docker dentro del mismo servidor físico.
Tiene que haber una solución mejor, pero por ahora lo solucioné conectando a la misma red virtual dentro de docker a wg-easy y PiHole. Le di una IP fija a PiHole dentro de esa red, y le dije a wg-easy que use ese servidor DNS, y que la conexión VPN salga por esa interfaz.
Me molesta mucho no saber por qué funciona, ni por qué no funciona sin hacer eso, pero por ahora sé que funciona.