En la situación de pandemia que vivimos por culpa del COVID19 muchísimos trabajadores están conectándose via VPN a sus empresas para poder operar de forma segura. Por ello, su gran utilidad no es el único motivo para conocer el término, sino que además se trata de una de las tecnologías de moda y por ello es interesante saber de qué se trata.
Wireguard es una aplicación de software libre multiplataforma (Linux, Windows, macOS, Android e iOS) que implementa un tunel VPN, con el objetivo de ser rápida y simple. Nació en 2016 y está escrita por Jason A. Donenfeld en C y Go y publicada bajo GPL.
Como siempre, vamos tratar de dar una definición sencilla de qué es una red privada virtual: Es la extensión segura de una red local sobre redes compartidas, siendo el ejemplo más común aquel en el que usamos como red compartida la red de Internet.
Gracias a una vpn obtenermos seguridad y confidencialidad, puediendo por ejemplo prestar servicios en internet sin exponerlos al público general que no usa la red privada. Además de enmascarar nuestra ip pública con la ip del servidor vpn.
Sus características clave de Wireguard son:
- Muy buen rendimiento, gracias a que el cifrado elegido y a que reside en el kernel de linux. De hecho en Marzo 2020, tras alcanzar su versión estable, se ha añadido al kernel 5.6.
- Simple de configurar: Básicamente lo único que debemos hacer es crear los pares de claves pública/privada para cada peer.
- Utiliza protocolos criptográficos de vanguardia: solo soporta el algoritmo de encriptado simétrico Chacha20, que parece ser tan seguro como AES (el estándar) pero posee un mejor rendimiento cuando se usan arquitecturas que no poseen este juego de instrucciones, como es ARM. Es por ello que ChaCha20 se plantea como su alternativa en caso de necesidad: https://medium.com/asecuritysite-when-bob-met-alice/aes-is-great-but-we-need-a-fall-back-meet-chacha-and-poly1305-76ee0ee61895
- Se ha programado tratando de usar el menor número de líneas de código posible y eso lo hace más seguro. Esto se debe a que con menos código resulta fácilmente auditable, agilizando la detección y correción de agujeros de seguridad.
- Usa únicamente el protocolo UDP, más simple y rápido que TCP, usado habitualmente para streaming, gaming, voip, etc. Admite que los paquetes lleguen desordenados o que se pierdan por el camino, requiriendo, de este modo, menos recursos que su contrapartida.
- Incremento significativo de la duración de batería en móviles y laptops en comparación con openVPN.
Se estima que WireGuard tiene 4000 líneas de código frente a las 100.000 de openvpn, y en la práctica proporciona mejor rendimiento (tanto velocidad como latencia) que el protocolo IPsec y que OpenVPN.
Instalación
Ubuntu
Ya encontramos el paquete wireguard
en las principales distros, como por ejemplo a partir de Ubuntu 18.04:
sudo apt install wireguard
En caso contrario añadimos el repo:
sudo add-apt-repository ppa:wireguard/wireguard
Raspberry OS
El paquete de wireguard no viene en los repositorios oficiales de RaspberryOS Buster:
sudo apt-get install raspberrypi-kernel-headers
echo "deb http://deb.debian.org/debian/ unstable main" | sudo tee --append /etc/apt/sources.list.d/unstable.list
wget -O - https://ftp-master.debian.org/keys/archive-key-$(lsb\_release -sr).asc | sudo apt-key add -
sudo apt update
sudo apt install wireguard -y
Generamos las claves pública/privada
Las almacenaremos en /etc/wireguard/keys
mkdir /etc/wireguard/keys
chmod 700 /etc/wireguard/keys
Con el comando wg genkey
generamos la clave privada, tee, como una redirección simple, la vuelca en un fichero, pero además lo muestra por la salida estándar, donde se redirige de nuevo a wg genkey
** que al recibir la clave privada genera la clave pública.
wg genkey | tee server\_private\_key | wg pubkey > server\_public\_key
Volvemos a hacer lo mismo para las claves de tantos clientes como necesitemos.
wg genkey | tee client\_private\_key | wg pubkey > client\_public\_key
Una vez creados los ficheros de clave debemos darles permisos 600.
PSK
Como extra de seguridad podemos usar una presharedKey única para cada cliente. De este modo estamos añadiendo un cifrado simétrico. Podemos generarla con el siguiente comando:
wg genpsk > client1.psk
Cliente para Windows
Montar la parte servidor en Windows parece que no está oficialmente recomendada. Yo desde luego no me planteo esta opción, prefiero Linux, sobre todo si es un servicio que ha nacido pensando en este sistema. No obstante aquí hay una guía donde explican cómo es posible lograrlo: https://www.henrychang.ca/how-to-setup-wireguard-vpn-server-on-windows/
Para montar el cliente lo primero es descargar el instalador de wireguard: https://download.wireguard.com/windows-client Después será tan sencillo como importar el mismo fichero de configuración del cliente que hubieramos creado para linux.
Cliente para Android
Podemos descargar el cliente oficial del Google play store: https://play.google.com/store/apps/details?id=com.wireguard.android
Para configurar el cliente Android lo más fácil es crear el perfil mediante el código QR generado en el servidor.
Debemos tener instalado qrencode
en el servidor: sudo apt install qrencode
.
De modo que podemos transformar la config del cliente en un código qr con el siguiente comando:
qrencode -t ansiutf8 < /etc/wireguard/wg0-client.conf
Una vez tengamos el código QR en pantalla vamos a:
Configuración
Vamos a ver cómo sería su configuración en un escenario "road warrior", dónde el bloque de configuración "Peer" de cada cliente hace referencia al servidor, mientras que el servidor tiene tantos bloques "Peer" como clientes tenga.
Perfil para el servidor
Cada archivo de configuración qute tengamos, uno por máquina, tendrá siempre dos bloques: interface y peer. El primero hace referencia a la interfaz de red (adaptador de red en Windows) que va a levantar para efectuar la conexión. Por otro lado el Peer hace referencia al cliente que va a estar conectándose en el otro extremo de la red.
Notación CIDR: Permite definir espacios de direcciones IP usando máscaras de subred, señalando al router qué parte de la dirección va a reservar para hosts. Por ejemplo la máscara 255.255.255.0 equivale a /24, dejando 8 bits para las direcciones de los hosts.
Interface del servidor
PrivateKey = <clave privada del servidor>
Address = 10.6.0.1/24 # Es ip virtual del servidor (10.6.0.1) y al mismo tiempo la red(10.6.0.0) que usaremos en notación CIDR /24 => 255.255.255.0.
ListenPort = 51820 # Es el puerto por defecto pero podemos cambiarlo, DEBEREMOS ABRIRLO EN EL FIREWALL Y EN EL ROUTER SI ESTAMOS DETRÁS DE NAT
DNS = 8.8.8.8 # El dns que van a usar los clientes
PARA LINUX SI ESTAMOS USANDO IPTABLES COMO FIREWALL
Con las siguientes línes permitimos la redirección del tráfico entre la interfaz virtual de wireguard y la # interfaz de red física.
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o enxb827eb95b695 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o enxb827eb95b695 -j MASQUERADE
Borramos la regla cuando desactivamos la interfaz de wireguard
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o enxb827eb95b695 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o enxb827eb95b695 -j MASQUERADE
Peer del servidor
Tendremos tantos bloques peer como clientes de la vpn.
PublicKey = <clave pública del cliente>
PresharedKey = <PSK del cliente 1>
AllowedIPs = 10.6.0.2/32 # la ip de la máquina, al no estar indicando una red sino solo una dirección, no dejamos ningún bit para el direccionamiento, es decir /32 => 255.255.255.255
Perfil para el cliente
La configuración del cliente se almacena en linux en /etc/wireguard/wg0-client.conf
(para una interfaz de nombre wg0-client).
Interface del cliente
Address = 10.6.0.2/24 # Es ip virtual del cliente (10.6.0.2) y al mismo tiempo la red(10.6.0.0) que usaremos en notación CIDR /24 => 255.255.255.0
PrivateKey = <clave privada del cliente>
DNS = 8.8.8.8 # El dns que van a usar los clientes
Peer del cliente
PublicKey = <clave pública del servidor>
PresharedKey = <PSK del cliente 1> # mejora opcional en la seguridad.
Endpoint = <ip pública del servidor>:51820
AllowedIPs = 0.0.0.0/0 # en principio permitimos tráfico desde cualquier ip
PersistentKeepalive = 20 # Tiempo en segundos para enviar periodicamente mensajes "keepalive" para asegurar que no se pierde la conexión. Útil si estamos detrás de NAT. Por defecto viene deshabilitada a valor 0.
Preparando el servicio y arrancando
Habilitamos el IP forwarding (Ip routing) editando el fichero /etc/sysctl.conf
y añadiendo:
net.ipv4.ip\_forward=1
El Ip forwarding es la capacidad del sistema operativo de aceptar paquetes en una interfaz y, a pesar de que no tengan como destino la propia máquina, redirigirlos a otra interfaz.
chown -v root:root /etc/wireguard/wg0.conf
chmod -v 600 /etc/wireguard/wg0.conf
sudo systemctl enable wg-quick@wg0.service
sudo wg
Para ver su estado:
sudo wg
Para reiniciar podemos desactivar y volver a activar la interfaz:
sudo wg-quick down wg0
sudo wg-quick up wg0
# o bien reinciar el servicio:
sudo systemctl restart wg-quick@wg0.service