Gabriel Cachadiña

Servidor de WireGuard con Pi-Hole

· Gabriel Cachadiña

En mi cruzada de conseguir una conexión a internet lo más segura posible he configurado mi servidor local para conseguir que todo mi tráfico sea tunelado a través de WireGuard a mi servidor y que, cualquier tráfico que desee acceder a internet, tenga además que pasar por Pi-Hole para conseguir un internet sin anuncios* y más seguro.

¿Qué es WireGuard?

WireGuard es un protocolo VPN moderno que permite establecer túneles cifrados entre pares. WireGuard_VPN WireGuard nos presenta las siguientes ventajas1 frente a otros servidores VPN:

Configuración

Una comunicación mediante WireGuard deberá estar conformado por el servidor y el cliente.

Servidor WireGuard

Para configurar un servidor WireGuard se deberá:

  1. Habilitar el puerto $51820$ en el firewall del router y del servidor. Solo será necesario habilitar el tráfico UDP.
  2. Configurar una regla NAT que establezca que el tráfico de la tarjeta de red que se esté usando (por ejemplo enp1s0) pase por una red interna que por estándar se nombrará wg0.
  3. Se configurarán las llaves del servidor, las cuales usará para encriptar el tráfico de los clientes. Para generar estas llaves se usarán los comandos
1wg genkey > private.key
2wg pubkey < private.key > public.key
  1. Se definirá la IP de la interfaz wg0, la llave privada del servidor y las llaves públicas de los dispositivos que se conectarán al mismo. Además de eso se definirá una IP o rango de IPs que estos dispositivos tomarán en esta red wg0. A continuación se muestra una configuración en NixOS:
 1{
 2  # enable NAT
 3  networking.nat.enable = true;
 4  networking.nat.externalInterface = "enp1s0";
 5  networking.nat.internalInterfaces = [ "wg0" ];
 6  networking.firewall.trustedInterfaces = [ "wg0" ];
 7  networking.firewall.allowedUDPPorts = [ 51820 ];
 8
 9  networking.wireguard.interfaces = {
10    wg0 = {
11      ips = [ "10.100.0.1/24" ];
12      listenPort = 51820;
13
14      privateKey = "${config.globals.wireguard_server_privatekey}";
15      peers = [
16        { # TFN
17  	  publicKey = "${config.globals.wireguard_tfn_publickey}";
18          allowedIPs = [ "10.100.0.2/32" ];
19        }
20        { # NomadUSB
21  	  publicKey = "${config.globals.wireguard_nomadusb_publickey}";
22          allowedIPs = [ "10.100.0.3/32" ];
23        }
24      ];
25    };
26  };
27}

Cliente WireGuard

Se deberán generar una pareja de llaves privada pública y compartir esta llave pública con el servidor al que se desee conectar. Para conectar un cliente se deberán añadir los siguientes parámetros:

Pi-Hole

Pi-hole es una utilidad que crea un servidor DNS que permite almacenar en su memoria páginas visitadas y restringir el acceso a las mismas. Pi-Hole es muy útil si se desea, por temas de seguridad, restringir IPs maliciosas, como páginas que descargan virus; IPs de anuncios, como los dominios de ads.google.com; o dominios que son usados puramente como trackers.

Saber que Pi-Hole no sustituye un firewall ni un sistema IDS, pero reduce considerablemente la exposición a trackers y dominios maliciosos.

Instalación

Para instalar Pi-Hole recomiendo encarecidamente usar docker compose y usar el network mode de host, quedando en NixOS de la siguiente forma:

{ config, pkgs, ... }:

{
  virtualisation.docker.enable = true;
  virtualisation.oci-containers = {
    backend = "docker";
    containers.pihole = {
      image = "pihole/pihole:latest";
      environment = {
        TZ = "Europe/Madrid";
        PUID = "1000";
        PGID = "1000";
	FTLCONF_webserver_api_password = "${config.globals.pihole_password}";
      };
      volumes = [
        "/home/gabriel/Docker/Pihole/etc-pihole:/etc/pihole"
        "/home/gabriel/Docker/Pihole/etc-dnsmasq.d:/etc/dnsmasq.d"
      ];
      ports = [
        "53:53/tcp"
        "53:53/udp"
        "67:67/udp"
        "80:80/tcp"
      ];
      networks = [ "host" ];
      autoStart = true;
    };
  };
  networking.firewall.allowedTCPPorts = [ 80 ];
}

Configuración de Pi-Hole

Con el programa instalado con el scrip anterior, tendremos el puerto $53$ que hará de DNS. Deberemos configurar los dominios de Pi-Hole.

Denotar que, en la configuración anteriormente mostrada, los puertos 53, 67 y 80 están expuestas al exterior de la máquina, por lo que cualquier usuario podría acceder a ellos. Esto ha sido hecho en mi caso ya que deseo que otros usuarios sean capaces de usar este proxy para asegurar su tráfico, pero en el caso de que solo se fuera a usar Pi-Hole para proteger el tráfico de WireGuard recomiendo usar 127.0.0.1:xx:xx para que Pi-Hole solo sea accesible al propio servidor.2

Pi-Hole y WireGuard

Finalmente para que WireGuard use Pi-Hole deberemos configurar desde el cliente que la opción 10.100.0.1. Se podría hacer que docker usara por defecto este DNS, pero eso causaría que, en caso de que Pi-Hole se colgara nos quedaríamos sin acceso a Wireguad. Trafico-Final


  1. Recomiendo encarecidamente leer la página oficial y ver las ventajas del protocolo de forma más detallada del siguiente video↩︎

  2. Algo que me gustaría también aclarar es que todo esto está en mi red local, no teninedo expuestos estos puertos a internet. Si así fuera habría que implementar algún tipo de rate limiting al uso del DNS para evitor un posible ataque DDoS. ↩︎

#self-hosted #gnu/linux

Reply to this post by email ↪