VPN de acceso remoto con WireGuard (Windows, Linux, Android)
Introducción
En este post vamos a configurar un servidor VPN con WireGuard. WireGuard es un protocolo de túnel de código abierto que se ha convertido en una alternativa a OpenVPN. WireGuard es más rápido, más ligero y más fácil de configurar que OpenVPN.
Preparando el escenario
Máquina Interno
Vamos a crear una máquina virtual con la ayuda de vagrant que servirá de cliente interno. Esta máquina tendrá una IP privada y no podrá acceder a internet.
Vagrant.configure("2") do |config|
config.vm.provider :libvirt do |libvirt|
libvirt.memory = 1024
end
config.vm.define :nodo1 do |nodo1|
nodo1.vm.box = "debian/bullseye64"
nodo1.vm.hostname = "Interno"
nodo1.vm.synced_folder ".", "/vagrant", disabled: true
nodo1.vm.network :private_network,
:libvirt__network_name => "Privada",
:libvirt__dhcp_enabled => false,
:ip => "192.168.20.10",
:libvirt__netmask => '255.255.255.0',
:mode => "veryisolated"
end
end
Y le configuraremos la ruta por defecto para que vaya por la ip ‘192.168.20.1’ que es la ip del servidor VPN.
ip r del default
ip r add default via 192.168.20.1
Maquina Servidor
Vamos a crear una máquina virtual con la ayuda de vagrant que servirá de servidor VPN. Esta máquina tendrá una IP pública y podrá acceder a internet.
Vagrant.configure("2") do |config|
config.vm.provider :libvirt do |v|
v.memory = 1024
end
config.vm.define :nodo1 do |nodo1|
nodo1.vm.box = "debian/bullseye64"
nodo1.vm.hostname = "Servidor"
nodo1.vm.synced_folder ".", "/vagrant", disabled: true
nodo1.vm.network :private_network,
:libvirt__network_name => "VPN3",
:libvirt__dhcp_enabled => false,
:ip => "192.168.99.10",
:libvirt__netmask => '255.255.255.0',
:libvirt__forward_mode => "veryisolated"
nodo1.vm.network :private_network,
:libvirt__network_name => "Privada",
:libvirt__dhcp_enabled => false,
:ip => "192.168.20.1",
:libvirt__netmask => '255.255.255.0',
:mode => "veryisolated"
end
end
En esta máquina vamos a instalar WireGuard.
apt install wireguard
Activamos el bit de forwarding en el kernel.
echo 1 > /proc/sys/net/ipv4/ip_forward
Nos dirigimos al directorio de configuración de WireGuard, creamos las claves del servidor que nos servirán para configurar los clientes y el fichero de configuración del servidor.
wg genkey | tee serverprivatekey | wg pubkey > serverpublickey
[Interface]
#IP del servidor
Address = 10.99.99.1
#Clave privada del servidor
PrivateKey = gFfh8vumUY89MkV269eYEiDdT9IWdfKDvV1T0DcSsEA=
#Puerto de escucha
ListenPort = 51820
Activamos la interfaz de WireGuard.
wg-quick up wg0
Y comprobamos que funciona correctamente.
wg
Cliente Linux
Vamos a crear una máquina virtual con la ayuda de vagrant que servirá de cliente para la VPN.
Vagrant.configure("2") do |config|
config.vm.provider :libvirt do |v|
v.memory = 1024
end
config.vm.define :nodo1 do |nodo1|
nodo1.vm.box = "debian/bullseye64"
nodo1.vm.hostname = "Linux"
nodo1.vm.synced_folder ".", "/vagrant", disabled: true
nodo1.vm.network :private_network,
:libvirt__network_name => "VPN3",
:libvirt__dhcp_enabled => false,
:ip => "192.168.99.11",
:libvirt__netmask => '255.255.255.0',
:libvirt__forward_mode => "veryisolated"
end
end
Y le configuraremos la ruta por defecto para que vaya por la ip ‘192.168.20.1’ que es la ip del servidor VPN.
ip r del default
ip r add default via 192.168.99.10
En esta máquina realizaremos la configuración de wireguard como hemos realizado en la máquina anterior.
- Instalamos wireguard
apt install wireguard
- Nos dirigimosal directorio
/etc/wireguard/y creamos el par de claves:
wg genkey | tee clientprivatekey | wg pubkey > clientpublickey
- Creamos el fichero de configuración del cliente:
[Interface]
Address = 10.99.99.2/24
#Clave privada del cliente
PrivateKey = 8J4d+gUAoZMNPZ1unrMtPJ4p7a2aXAB24MXnlmx+CEU=
#Puerto de escucha del servidor
ListenPort = 51820
[Peer]
#Clave pública del servidor
PublicKey = KGD20wvABWB20aj02aCsUfKxphiubQUa0iGOMSVqNHc=
AllowedIPs = 0.0.0.0/0
#Punto de acceso del servidor
Endpoint = 192.168.99.10:51820
#Tiempo de espera de la conexión
PersistentKeepalive = 25
- Activamos la interfaz de WireGuard.
wg-quick up wg0
Configurado el cliente, deberemos configurar en el fichero wg0.congde servidor donde incluiremos el cliente que recientemente hemos configurado y el fichero quedaría de la siguiente manera:
[Interface]
Address = 10.99.99.1
#Clave privada del servidor
PrivateKey = gFfh8vumUY89MkV269eYEiDdT9IWdfKDvV1T0DcSsEA=
#Puerto de escucha
ListenPort = 51820
#Bit de forwarding
PreUp = sysctl -w net.ipv4.ip_forward=1
# Cliente Debian 11
[Peer]
#Clave pública del cliente
Publickey = pQLF6BndUY/V15vvCymgo+84qWp5YzLLjXpybSmMBDo=
#IP del cliente
AllowedIPs = 10.99.99.2/32
#Tiempo de espera de respuesta
PersistentKeepAlive = 25
Reiniciaos el servicio y comprobamos que el cliente se ha conectado correctamente.
wg-quick down wg0
wg
Comprobaciones de funcionamiento
Desde el propio cliente podemos comprobar el funcionamiento de la VPN.
Desde el servidor podemos comprobar que el cliente Android se ha conectado correctamente.
Configuración del cliente windows
Lo primero que deberemos realizar es el cambio de ip de la interfaz de red de la máquina virtual para que no haya conflictos con la ip de la VPN. Para ello, ejecutamos el administrador de sistema en modo administrador y escribimos en la consola:
netsh
interface ip set address name="Ethernet" static 192.168.99.12 255.255.255.0 192.168.99.10
Descargamos wildguard desde su página oficial, y una vez instalado, abrimos el programa y en la parte inferior izquierda, tenemos un menú desplegable donde seleccionamos Añadir tunel vacío.
En la subventana que se abre, ya nos aparecen creadas ambas claves, la pública y la privada del servidor, por lo que solo tendremos que añadir la clave pública del servidor y la IP.
Nos dirigimos al servidor, y añadimos la clave pública del cliente y la IP, quedando el fichero de la siguiente manera:
[Interface]
Address = 10.99.99.1
PrivateKey = gFfh8vumUY89MkV269eYEiDdT9IWdfKDvV1T0DcSsEA=
ListenPort = 51820
PreUp = sysctl -w net.ipv4.ip_forward=1
# Cliente Debian 11
[Peer]
Publickey = pQLF6BndUY/V15vvCymgo+84qWp5YzLLjXpybSmMBDo=
AllowedIPs = 10.99.99.2/32
PersistentKeepAlive = 25
# Cliente Windows
[Peer]
Publickey = SqFFutq1xAbGzj3POiHSRbbPpQAH1clUkyWikKjhojg=
AllowedIPs = 10.99.99.2/32
PersistentKeepAlive = 25
Reiniciamos el servicio y comprobamos que el cliente se ha conectado correctamente.
Comprobaciones de funcionamiento
En las siguientes imágenes, podemos ver que el cliente windows puede acceder a la red interna y también con el cliente linux.
Configuración del cliente Android
Para este punto del escenario, voy a usar mi máquina host como servidor VPN y mi móvil físico como cliente. Para ello, hemos instalado la aplicación WireGuard en el móvil y hemos configurado el servidor con la IP de mi móvil.
Para hacerlo posible, vamos a realizar la configuración del cliente en la propia máquina servidor y luego pasaremos dicha configuración al móvil a través de un código QR que generaremos en nuestra consola.
- Creamos las claves pública y privada del cliente.
wg genkey | tee androidprivate | wg pubkey > androidpublic
- Creamos el fichero de configuración del cliente.
[Interface]
Address = 10.99.99.4
PrivateKey = wHf9pBV923/XKWPzFVPp39w3eUZ7wU7DsE6cvu36F2s=
ListenPort = 51820
[Peer]
Publickey =n9IjUHqVAQ9WEW80syWFYmgY5IG80kd5J9j2godvgm8=
AllowedIPs = 0.0.0.0/0
Endpoint = 192.168.15.32:51820
- Ahora generaremos el código QR con el que pasaremos la configuración al móvil.
qrencode -t ansiutf8 < android.conf
- Modificamos el fichero de configuración del servidor para añadir la clave pública del cliente y la IP.
[Interface]
#IP del servidor
Address = 10.99.99.1
#Clave privada del servidor
PrivateKey = gFfh8vumUY89MkV269eYEiDdT9IWdfKDvV1T0DcSsEA=
#Puerto de escucha
ListenPort = 51820
[Peer]
Publickey = Iq47qp/TP8bx6v4qDJwTiHwWYSO7/y23FvK1SpIdzi0=
AllowedIPs = 10.99.99.4/32
PersistentKeepAlive = 25
- Tras ello, reiniciamos el servicio y comprobamos que el cliente se ha conectado correctamente.
Comprobaciones de funcionamiento
Para verificar que funciona correctamente, haremos ping desde el cliente interno al cliente android y desde el cliente android al servidor.
Conclusiones
Comparando OpenVPN y WireGuard, podemos ver que WireGuard es mucho más sencillo de configurar y que tiene un rendimiento mucho mejor. Con Wireguard no es necesario que creamos un certificado para cada cliente, ya que solo necesitamos la clave pública del cliente y la clave privada del servidor.
Otro de los puntos a favor de WireGuard es que no es necesario que el servidor tenga una IP pública, ya que podemos usar un servidor con una IP privada y usar un servicio de tunelado.