Wireguard: Controlar el acceso de los clientes

Publicado por P. Ruiz en

VPNCuando estamos usando una conexión VPN, nos pueden surgir inquietudes relacionadas con la privacidad desde dos puntos de vista: el del usuario y el del administrador. Hoy, centrándonos en la configuración de WireGuard que hemos venido haciendo, vamos a tratar de resolver ambas.

Inquietudes del usuario

Cuando un usuario se conecta por primera vez a una VPN, puede pensar de forma justificada que, desde ese momento, todo su tráfico de Internet está pasando por el servidor de esa VPN. Eso significa que el administrador, u otra persona no autorizada, podría tener acceso a dicho tráfico y acceder a información que el usuario no pretendía compartir.

Esa es, precisamente, la intranquilidad que podemos tener cuando usamos un servidor VPN comercial.

Sin embargo, en el caso de WireGuard, la solución es muy sencilla. Imagina, por ejemplo, que eres un usuario de la VPN de tu empresa y el administrador te ha enviado un archivo de configuración con este aspecto:

[Interface]
PrivateKey = 6DPQmCabG4aNykB2JaS4/9EEecFxDhZxht/51XT1GXV=
Address = 10.234.223.2/24
DNS = 8.8.8.8, 4.4.4.4

[Peer]
PublicKey = RVWrLVr5kABBrD33UD17T+MjPYw54F0dAAiOj97FDDk=
PresharedKey = ASnailsGt65vKq6AfN6VhpAOAyHpUlJhDSajoB/ei+N=
Endpoint = 192.168.1.2:51820
AllowedIPs = 0.0.0.0/0, ::0/0

Como hemos dicho, al activar la VPN en tu ordenador, todo tu tráfico va a ser redirigido a través de esa VPN.

Obviamente, este comportamiento es muy interesante en algunos casos. Por ejemplo cuando la VPN es tuya y te estás conectando desde un lugar público (el tráfico irá cifrado hasta tu casa y luego, desde ahí, ya navegarás con normalidad por Internet).

Sin embargo, en el caso que nos ocupa, preferiremos enviar a la VPN solo el tráfico relacionado con nuestro trabajo, permitiendo que el resto de paquetes viajen por nuestra conexión a Internet habitual.

Pues bien, para lograrlo, solo tenemos que observar la última línea. En ella se indica el rango de direcciones IP para el que la VPN enruta el tráfico. Puede incluir diferentes direcciones IP y subredes, separadas por comas, tanto IPv4 como IPv6. En todos los casos, se usará notación CIDR.

El valor predeterminado 0.0.0.0/0, ::0/0 indica que se enviará todo el tráfico (la primera parte representa IPv4 y la segunda IPv6).

Por lo tanto, para completar nuestro objetivo, bastará con cambiar la última línea, de manera que contenga solo la dirección (o direcciones) IP del servidor (o servidores) donde queramos acceder en la empresa. Por ejemplo, algo como esto:

AllowedIPs = 192.168.0.4/32

Cuando terminemos, solo debemos asegurarnos de guardar los cambios.

Wireguard-Controlar-el-acceso-de-los-clientes-001

Inquietudes del administrador de la VPN

Si has leído el apartado anterior, y eres administrador de una red que utiliza una VPN creada con WireGuard, habrá nacido en ti una nueva inquietud (suponiendo que aún no la tuvieses).

La cuestión es que, de lo dicho arriba, se puede deducir que puedes enviarle un archivo de configuración a cualquiera de tus usuarios restringiéndole el uso a un ordenador (o un grupo de ordenadores) de tu red. Sin embargo, el usuario, en lugar de utilizarlo tal cual, puede modificarlo para acceder a otros equipos de la misma red interna o, incluso, a otros ordenadores que se estén conectando a través de la VPN.

Afortunadamente, en el servidor tenemos a nuestra disposición iptables, un cortafuegos incluido en el núcleo de GNU/Linux, que nos permite controlar fácilmente dos cosas:

  1. Los paquetes de datos que pueden entrar desde una determinada dirección IP (o grupo de direcciones), y por qué puertos.

  2. Los paquetes de datos que pueden salir, hacia qué dirección IP (o grupo de direcciones), y por qué puerto.

Filtrar de entrada a la red

Debemos tener en cuenta que Wireguard asigna una dirección IP específica para cada ordenador implicado, que será independiente de la dirección IP del ordenador cliente, en la red local del usuario, y del servidor, en la red local del servidor (o servidores).

Esto nos permite que podamos establecer reglas en el cortafuegos, que afecten únicamente a los paquetes de WireGuard que provengan de un ordenador (o grupo de ordenadores) específico.

Por ejemplo, imagina que tienes en tu red un servidor Proxmox VE, ubicado en la dirección IP 172.26.0.4 y  escuchando por el puerto 8006. Para que los usuarios puedan acceder desde sus casas únicamente al servidor, bastaría con usar estas dos reglas:

iptables -A FORWARD -i wg0 -d 192.168.0.4 -p tcp --dport 8006 -j ACCEPT
iptables -A FORWARD -i wg0 -d 192.168.0.0/16 -j DROP

Como la sintaxis puede resultar un poco críptica, vamos a explicarla con más detalle:

  1. El argumento -A FORWARD añade la regla a la cadena FORWARD, que se encarga de filtrar los paquetes que se reenvían a través del servidor. Es decir, el servidor no es el origen ni el destino del paquete, solo el puente para pasar de una red a otra.

  2. El argumento -i wg0 indica la interfaz de entrada. Es decir, en este caso, la regla afectará a los paquetes que vengan desde la interfaz wg0, que es la interfaz virtual que crea WireGuard de forma predeterminada. Ten en cuenta que, en tu caso, podría llamarse de otro modo.

  3. El argumento -d 192.168.0.4 hace referencia a la dirección de destino de los paquetes. En la segunda regla estamos (la que rechaza el tráfico indeseado), hace referencia a todas las direcciones con la estructura 192.168.x.x.

  4. El argumento -p tcp especifica que la regla está destinada únicamente a los paquetes TCP. De este modo, vemos que también se puede filtrar tráfico en función del protocolo (TCP, UDP, ICMP, etc.).

  5. El argumento –dport 8006 indica el puerto de destino de los paquetes. En este caso, el puerto utilizado por Proxmox VE.

  6. El argumento -j establece la acción que debe tomarse con los paquetes identificados en la regla. El valor ACCEPT indica que el paquete debe seguir su curso normal y DROP indica que el paquete se elimine de forma silenciosa, es decir, sin enviar respuesta al emisor.

Por lo tanto, como ya habrás deducido, la primera línea es la que permite el tráfico de paquetes al destino que queremos y la segunda rechaza cualquier otro tráfico existente.

Crear excepciones

Imagina ahora que tienes un usuario concreto, por ejemplo un administrador, que debe tener acceso a toda la red desde el exterior. Si a ese usuario se la asignado WireGuard la dirección 10.234.223.5/24, bastaría con añadir una regla como esta:

iptables -A FORWARD -i wg0 -s 10.234.223.5 -j ACCEPT

En este caso, el argumento -s indica la dirección de origen de los paquetes a los que se aplicará la regla. Como no estamos restringiendo ni puerto, ni protocolo, vamos a permitir que el cliente acceda a cualquier servicio en la red local.

Qué hacer con el resto del tráfico

En realidad, ya casi hemos terminado. Al principio, hemos creado un archivo de configuración para cada usuario donde indicamos que, sólo debe dirigirse a la VPN, el tráfico que tenga como destino el servidor (o servidores) que nos interese.

Después, hemos configurado iptables para que redirija el tráfico destinado al servidor y deseche el destinado al resto de nuestra red.

Hasta aquí bien, pero, ¿que pasaría si un usuario quisiera encaminar todo su tráfico de Internet a través de nuestro servidor? La respuesta es que solo tendría que modificar su archivo de configuración para que AllowedIPs volviera a tener el aspecto original, es decir:

AllowedIPs = 0.0.0.0/0, ::0/0

Sin embargo, también podemos resolver esa situación de un modo sencillo con iptables. Bastaría con añadir una nueva línea como esta:

iptables -A FORWARD -i wg0 ! -d 192.168.0.0/16 -j DROP

Aquí la novedad es que es que usamos el carácter ! para negar cualquier tráfico que tenga como destino una dirección que se encuentre fuera del rango 192.168.x.x. Así, si un usuario modifica su archivo de configuración, el nuevo tráfico generado hacia la VPN será ignorado automáticamente.

Automatizar los cambios

Bueno, pues ahora que ya lo tenemos claro, creo que lo ideal es crear un script que automatice el proceso. Comenzará guardando la configuración anterior (la que existe en el sistema antes de hacer cambios), por si algo sale mal. Lo conseguiremos con una orden como esta:

iptables-save > /root/iptables.copia

Yo he decidido guardar la copia en la carpeta /root, pero puedes ajustar la ruta según tus necesidades.

A continuación eliminamos la configuración actual de iptables:

iptables -F

Por último, reiniciamos el cortafuegos con:

service ufw restart

Y añadimos las reglas necesarias.

En definitiva, los pasos son:

  1. Crear una carpeta donde guardar tus scripts (si aún no la tienes). Yo suelo usar una, llamada precisamente scripts y situada en el directorio raíz, para que esté accesible. Para crearla, puedes usar una orden como esta:

    mkdir /scripts
  2. Usar el editor de textos para escribir el contenido del script. Yo usaré nano, y llamare a mi script acceso.sh. Por lo tanto, la orden quedaría así:

    nano /scripts/acceso.sh

    Creamos la carpeta y abrimos el editor.

    Wireguard-Controlar-el-acceso-de-los-clientes-002

  3. Con esto, estaré listo para escribir el contenido de mi script, que será algo como esto:

    #!/bin/bash
    # Guardar la configuración actual de iptables
    iptables-save > /root/iptables.copia
    
    #Eliminar las reglas actuales
    iptables -F
    
    #Reiniciar el cortafuegos
    service ufw restart
    
    #Permitir a todos los clientes usar solo 192.168.0.4:8006
    iptables -A FORWARD -i wg0 -d 192.168.0.4 -p tcp --dport 8006 -j ACCEPT
    iptables -A FORWARD -i wg0 -d 192.168.0.0/16 -j DROP
    #
    #Permitir al cliente 10.234.223.2 acceso completo
    iptables -A FORWARD -i wg0 -s 10.234.223.2 -j ACCEPT
    #
    #Rechazar cualquier trafico que no vaya destinado a la red local
    iptables -A FORWARD -i wg0 ! -d 192.168.0.0/16 -j DROP
    
    echo "Cambios aplicados."

    Cuando terminemos, salimos del editor, asegurándonos de guardar los cambios

    Wireguard-Controlar-el-acceso-de-los-clientes-003

  4. Una vez guardados los cambios, debemos otorgar los permisos adecuados para que pueda ejecutarse. Lo haremos con los siguientes comandos:

    chmod 711 /scripts/acceso.sh

    El valor concreto puede cambiar según tus necesidades.

    Wireguard-Controlar-el-acceso-de-los-clientes-004

Y, con esto, hemos acabado nuestra tarea de hoy. A partir de este momento, cuando necesites cambiar el acceso de los clientes a la VPN, solo tendrás que modificar el script y volver a ejecutarlo.

Espero que te haya resultado útil.

Puedes consultar todos los artículo publicados en  SomeBooks.es sobre WireGuard en este enlace.