Wireguard con Raspberry Pi
Published: 2020-05-08 15:49:01

Hola a tod@s! vamos a intentar instalar una VPN casera. Lo primero de todo voy a intentar explicar por encima qué es una VPN.

Una VPN (Virtual Private Network) o en español un Red Privada Virtual es una tecnología que nos permite crear un túnel virtual que emula una conexión directa a nuestro router aunque nos econtremos a kilómetros de distanca. (Obviamente usando una conexión de red primero como puede ser la de la red móvil o una red Wi-Fi. (si fuera un cable directo a nuestro router sería la leche xD)
![cap1](https://i.ibb.co/RvbNTKs/cap1.png)
Creo que [este vídeo](https://www.youtube.com/watch?v=M5TdFKUaNxM) lo explica bastante bien aunque en el vídeo se muestra otro proceso.

Una de las muchas utilidades que se le puede dar al uso de una VPN que podemos mencionar, por ejemplo, es el cifrado que llevan los paquetes que pasan por esta misma.

Imaginemos que estamos en una cafetería que tiene un punto de acceso Wi-Fi y vamos a conectarnos a ella. No sabemos bien quién puede estar capturando los paquetes o interviniendo en esa red, si usamos nuestra VPN estaríamos añadiendo una capa más de seguridad a nuestro datos, claro está que nada es 100% seguro y la información mejor protegida es aquella que está en tu mente y no ha salido de ahí (por ahora). En Internet la seguridad es relativa.

Bueno dicho esto, vamos al lío!

---
## Instalación de Wireguard
---
Vamos a montar una VPN en nuestra Raspberry Pi con [Wireguard](https://www.wireguard.com/), para ello necesitamos añadir algunos repositorios, instalarlo y configurarlo. Para eso vamos a seguir estos pasos:

Lo primero debemos tener actualizado nuestro sistema, para ello ejecutamos estos comandos:
```bash
sudo apt update
sudo apt upgrade 
```
Ahora vamos a instalar los headers del kernel de GNU/Linux:
```bash
sudo apt-get install raspberrypi-kernel-headers
```
Como [aún no se ha incluído Wireguard] (https://arstechnica.com/gadgets/2020/03/wireguard-vpn-makes-it-to-1-0-0-and-into-the-next-linux-kernel/) como parte del kernel de GNU/Linux hay que instalarlo, pero como no se encuentra en los repositorios de Raspbian, vamos a añadir los repositorios de Debian, además así podemos mantener Wireguard actualizado usando el típico *apt update*:
Ahora vamos a instalar los headers del kernel de GNU/Linux:
```bash
echo "deb http://deb.debian.org/debian/ unstable main" | sudo tee --append /etc/apt/sources.list
```
A continuación vamos a añadir las keys para la distro de Debian:
```bash
sudo apt-key adv --keyserver   keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC

sudo apt-key adv --keyserver   keyserver.ubuntu.com --recv-keys 648ACFD622F3D138
```
Bien, ahora lo que vamos a hacer con el siguiente comando es prevenir que nuestra Raspberry use los repositorios de Debian como repositorios normales de Raspbian:
```bash
sudo sh -c 'printf "Package: *\nPin: release a=unstable\nPin-Priority: 90\n" > /etc/apt/preferences.d/limit-unstable'
```
Ahora toca actualizar nuestra lista de paquetes:
```bash
sudo apt-get update
```
Con todo esto hecho ahora podemos instalar Wireguard ejecutando lo siguiente:
```bash
sudo apt install wireguard
```
Procedemos a comprobar que se ha instalado viendo si existen **/usr/bin/wg** y **/usr/bin/wg-quick**, para ello ejecutamos estos comandos:
```bash
which wg
which wg-quick
```
---
## Generando Claves
---

Por ahora todo ha ido bien, entonces vamos a proceder a generar las claves privadas y públicas que son las claves que se usan para autentificar tanto al servidor que vamos a crear con un cliente y viceversa, es decir, para hacer un [Handshake](https://es.wikipedia.org/wiki/Establecimiento_de_comunicaci%C3%B3n).

Para esto vamos a movernos a un directorio donde vamos a almacenar estas claves, por ejemplo podemos hacerlo en /etc/wireguard y para hacer todo esto vamos a ganar privilegios de administrador:
```bash
sudo su
cd /etc/wireguard
```
Vamos a cambiar los permisos de este directorio:
```bash
umask 077
```
Y ahora vamos a crear la claves:
```bash
wg genkey > server_private_key
wg pubkey > server_public_key < server_private_key

wg genkey > client1_private_key
wg pubkey > client1_public_key < client1_private_key
```
Si listamos los archivos del directorio actual con <code>ls</code> veremos que nos ha generado esos 4 archivos, uno con la clave privada del servidor, otro con su clave pública y los mismos pero para el cliente.

Usaremos el comando <code>cat</code> para ver el contenido de estos archivos, ya que lo usaremos para configurar el servidor y el cliente (en mi caso solo hay 1 cliente pero podemos tener los que queramos).
```bash
cat server_private_key
cat server_public_key
cat client_private_key
cat client_public_key
```
Supongamos que los ficheros contienen estas claves:

<code>server_private_key: AAABBBCCC</code>
<code>server_public_key:XXXYYYJJJ</code>
<code>client_private_key:RRRPPPKKK</code>
<code>client_public_key:TTTLLLWWW</code>


---
## Configurando el servidor (Raspberry)
---

Ahora vamos a configurar el servidor. Es necesario estar en el directorio **/etc/wireguard** ya que vamos a crear el archivo de configuración del servidor y editarlo, para eso ejecutamos:
```bash
nano wg0.conf
```
Se nos abrirá el editor de texto nano y le añadiremos lo siguiente:
```bash
[Interface]
Address = 123.123.123.1/24
ListenPort = 51840
PrivateKey = AAABBBCCC

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# Movil que voy a usar como cliente 1
PublicKey = TTTLLLWWW
AllowedIPs = 123.123.123.2/32
```
Una vez editado guardamos **(Ctrl+X)** y cerramos nano para volver a la consola. 

Voy a explicar un poco de qué se trata cada cosa de arriba hacia abajo:

+ **[Interface]**: Nos indica donde comienzan datos de nuestra interfaz de red de servidor.
+ **Address**: Esta es la **dirección IP virtual** que tendrá el servidor VPN,nos la podemos inventar, pero debemos tener clara cuál es y obviamente respetar las normas estructurales de una dirección IP, es decir, 555.777.999.889/98 no es una dirección IP.
+ **ListenPort**: Es el puerto que utilizará el servidor para escuchar, como es lógico debemos abrir este puero en nuestro firewall y router.
+ **PrivateKey**: es la clave privada del servidor que creamos antes.
+ **PostUp** y **PostDown**: son parámetros de iptables. Aquí cabe mencionar algo important: en ambos casos vemos que aparece **eth0** esto debe ser el nombre de la interfaz de red que estemos usando en la Raspberry, por ejemplo es usual que si usamos la Raspberry mediante Wi-Fi el nombre de esta interfaz sea **wlan0** De ser el caso debemos cambiar eth0 por wlan0. Para saber el nombre de la interfaz de red que estás usando puedes verlo con el comando <code>ifconfig</code>.

+ **[Peer]**: Indica donde comienzan los datos del primer cliente.
+ **#**: Indica un comentario.
+ **PublicKey**: Aquí va la clave pública del cliente que hemos generado antes.
+ **AllowedIPs**: Esta es la **dirección IP virtual** que tendrá el cliente, como dije arriba ha de respetar las normas de las direcciones IP e ir en concordancia con la dirección IP virtual del servidor.

Ahora toca habilitar el IP Forwarding,pero ¿para qué es útil esto? Veámoslo:

Si queremos acceder a nuestros recursos de la LAN (ya sea una cámara IP, otro equipo de la red, etc.) a través de esta VPN que estamos haciendo entonces debemos tener habilitado el IP Forwarding en el equipo host donde se encuentra el servidor VPN Wireguard, en este caso, en la Raspberry. Si no habilitamos el IP Forwarding no estaríamos aprovechando todo el potencial que nos da usar una VPN, dicho esto, omitir el IP Forwarding solo tendría sentido si el único dispositivo al que se quiere llegar desde fuera con la VPN es la máquina host WireGuard (la Raspberry en este caso).


Para habilitar el IP Forwarding abriremos el fichero de configuración **/etc/sysctl.conf** y lo editaremos, desmarcaremos la línea donde dice "net.ipv4.ip_forward=1", guardamos el archivo con su mismo nombre y cerramos nano:
```bash
nano /etc/sysctl.conf
```
Debe quedar algo así:
![cap2](https://i.ibb.co/7pk6Fkm/cap2.png)
Una vez hecho esto vamos a reinicar la máquina y nos logueamos con nuestro usuario normal, comprobamos que el IP Forwarding esté activo usando este comando:
```bash
sudo sysctl net.ipv4.ip_forward
```
Este comando nos debe **retornar** un valor igual a 1, es decir: **net.ipv4.ip_forward = 1**.

Ahora vamos a iniciar nuestra nueva interfaz de red del servidor con este comando:
```bash
sudo wg-quick up wg0
```
**nota**: Si queremos parar la interfaz en algún momento podemos ejecutar:   <code>sudo wg-quick down wg0</code>.

Para ver su estado ejecutamos lo siguiente:
```bash
sudo wg
```
Comprobamos que todo está bien y tenemos conexión a Internet, por ejemplo haciendo un PING a 8.8.8.8 

Si todo está bien y correcto y nos alegramos podemos hacer que se ejecute automáticamente al iniciar la Raspberry con este comando:
```bash
sudo systemctl enable wg-quick@wg0
```
Y procedemos a cambiar de dueño y permisos con estos comandos, siendo root ahora:
```bash
sudo su
chown -R root:root /etc/wireguard/
chmod -R og-rwx /etc/wireguard/*
```
---
Reiniciamos la máquina y nos logueamos con nuestro usuario normal.
## Configurando el cliente
---

Ahora toca configurar la parte del cliente, en mi caso es un smartphone con un sistema Android. Para estos dispositivos y para iPhone para instalar Wireguard simplemente debemos descargarnos la APP de su respectiva tienda de APP.

Para configurar la parte del cliente vamos a hacer esto:

En nuestra Raspberry Pi abrimos la terminal y nos situamos en el escritorio por ejemplo y vamos a crear una archivo de configuración para nuestro cliente y modificarlo:
```bash
nano cliente1.conf
```
Se nos abrirá el editor de texto nano y le incluiremos lo siguiente:
```bash
[Interface]
Address = 123.123.123.2/32
PrivateKey = RRRPPPKKK
DNS = 8.8.8.8
        
[Peer]
PublicKey = XXXYYYJJJ
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = AquíVaLaIpPúblicaDeTuRed:51840
```
+ **[Interface]**: Nos indica donde comienza la configuración de la interfaz del cliente.
+ **Address**: Aquí irá la dirección IP del cliente que permitimos en la sección ***AllowedIPs*** del archivo de configuración del servidor.
+ **PrivateKey**: Aquí debe ir la clave privada del cliente que se halla en el archivo (client_private_key).
+ **DNS**: Aquí ponemos la dirección del servidor DNS que prefiramos usar.
+ **[Peer]**: Se inicia la parte de configuración del cliente referenciando al Servidor Wireguard.
+ **PublicKey**: Aquí ponemos la clave pública del servidor que está en el archivo "server_public_key".
+ **AllowedIPs**: Podemos las direcciones IP que están ahí para permitir que todo tráfico pueda fluir por nuestro móvil.
+ **Endpoint**: Aquí debemos poner la IP pública de nuestro router ó la dirección DDNS que tengamos apuntando a ella.

Una vez explicado esto, guardamos este archivo (**Cntrl + X**) aceptamos y cerramos nano volviendo a la terminal y haremos lo siguiente:
```bash
sudo apt install qrencode
```
Y luego:
```bash
qrencode -t ANSIUTF8 < cliente1.conf
```
Nos habrá generado un código QR. En la APP de Wireguard que tenemos en nuestro móvil hay una opción de cargar la configuración mediante un código QR, apuntamos a la pantalla para escanear ese código, le ponemos un nombre y ya estaría disponible esa configuración en nuestro dispositivo.

Y bueno si todo ha salido bien ya tendríamos acceso a nuestra VPN desde cualquier parte del mundo con nuestro smartphone.