Table of Contents

Crear conexiones VPN con SSH / Configurar el uso de VPN en aplicaciones

Crear VPNs utilizando simplemente SSH es fácil de implementar y muy práctico en muchas tesituras debido a su flexibilidad. Además si se combina con las nuevas funcionalidades del kernel Linux, como los espacios de nombres de Linux, elevan su funcionalidad casi a la de VPNs profesionales.

Dichos espacios de nombres son una característica del muy usada en tecnologías de contenedores. Un espacio de nombres envuelve un recurso global del sistema en una abstracción que estará vinculada solo a los procesos dentro del espacio de nombres, proporcionando aislamiento de recursos. En nuestro caso se usará el espacio de nombres de red, que viene a ser una cópia de la pila TCP/IP del kernel pero aislada para ser entregada a determinados procesos. Permitiendo por tanto la posibilidad de utilizar cualquier aplicación o grupo de aplicaciones del sistema sobre una determinada conexión SSH. Además el uso de llaves permite no depender de contraseñas y poder automatizar procesos en scripts. Realmente la creación de este tipo de VPN se basan en combinar el típico redireccionamiento IP(IP forwarding), NAT y capacidades de enrutamiento del núcleo de Linux junto a la implementación de interfaces túnel que SSH ofrece.

Para el supuesto que servirá de ejemplo se dispone de dos equipos, un sobremesa o portátil en casa y un servidor VPS localizado en cualquier parte de Internet. El ordenador de casa que hará de cliente tiene la típica red 192.168.178.0/24 y una dirección pública con la que sale a internet. El VPS tiene una dirección pública por la cual es accesible mediante ssh y además una red interna 172.16.0.0/12 que utiliza para comunicarse con otros servidores virtuales y queremos tenerla accesible desde casa.

Estas son algunas de las cosa que vamos a poder hacer con la VPN.

Requerimientos.

El servidor remoto necesita soportar túneles ssh, para ello comprobar la opción “PermitTunnel yes” en el fichero “/etc/ssh/sshd_config”. En un primer momento tanto el PC de casa como el servidor VPS remoto necesitan acceso directo a root ya que deben crearse interfaces para el túnel.

Como los pasos son siempre los mismos y cada VPN creada es independiente de las otras, se va a explicar el proceso con una sola VPN. A grandes rasgos esto funciona de la siguiente manera. La conexión ssh saliente crea en el PC de casa y el servidor destino un túnel ssh, este se apoya en la creación de interfaces virtual identificadas como “tun0” en cada uno de los sistemas. Una vez se tiene el túnel solo falta configurar el direccionamiento IP para que SSH empiece a encapsular el tráfico de red que enviemos por ese canal y las rutas.

Para comunicar los dos extremos del túnel se creará una red aparte, por ejemplo 10.0.0.0/30.

       [ CASA ]                                             [ VPS ]                                                        
eth0 192.168.178.0/24                              venet0 172.16.0.0/12 < ---- NAT ---- > Internet / LAN
tun0 10.0.0.1/30 < ------------ SSH ------------ > tun0   10.0.0.2/30 

Configuración de la parte cliente de la VPN

La opción “-w” crea en local y remoto un túnel ssh accesible mediante interfaces virtuales tun0.

# Desde el PC de casa.
ssh -w any:any root@VPS   # Crea el túnel ssh. (Versiones muy actuales del cliente ssh pueden no funcionar con versiones antiguas del servicio.)
ip addr                  # Debe mostrar una interfaz tun0 en casa y el servidor VPS.

Configurar / Gestionar la VPN mediante rutas (Opción 1).

ip address add 10.0.0.1/30 dev tun0                # Asignar una IP al extremo del túnel del cliente.
ip link set up tun0
ip route add 172.16.0.0/12 via 10.0.0.2 dev tun0  # Configura una ruta para que la red  del VPS 172.16.0.0/12 esté accesible a través del túnel

NOTA: Para que la red 172.16.0.0/12 esté accesible desde el cliente, es decir desde la casa, el servidor VPS remoto debe hacer NAT y enrutar los paquetes. En caso contrario solo estará accesible la dirección IP LAN del servidor VPS.

Usar la VPN mediante la configuración de aplicaciones (Opción 2).

En vez de usar rutas como en el caso anterior, se puede simplemente ejecutar aplicaciones obligándolas a que usen una interfaz determinada, para nuestro caso tun0. En este caso no hace falta crear rutas porque las aplicaciones usaran únicamente la interfaz del túnel. Para ello se creara un nuevo espacio de red mediante la opción de administrador de nombres de red del comando ip “netns”.

Un espacio de nombres de red es otra copia de la pila de red del kernel, con sus propias rutas, reglas de firewall y dispositivos de red.

Netns: http://man7.org/linux/man-pages/man8/ip-netns.8.html
TUN/TAP: https://www.kernel.org/doc/Documentation/networking/tuntap.txt
ip netns: forzar_a_los_procesos_a_utilizar_una_determinada_interfaz_de_red_ip

Para el ejemplo se creará un espacio de direcciones que identificaremos como “Busi_VPN”. Ese espacio tendrá como gateway por defecto la dirección del túnel perteneciente al VPS.

ip netns add Busi_VPN
ip link set tun0 netns Busi_VPN
ip netns exec Busi_VPN ip address add 127.0.0.1/8 dev lo
ip netns exec Busi_VPN ip link set tun0 up
ip netns exec Busi_VPN ip address add 10.0.0.1/30 dev tun0
ip netns exec Busi_VPN ip route add default via 10.0.0.2
 
ip netns exec Busi_VPN bash   # Todo lo ejecutado en la terminal usará dicho espacio de nombres de red.

Crear la conexión VPN-SSH sin necesitar de privilegios root en cliente.

Crear interfaz de túnel tun0 con el comando ip.

ip tuntap add mode tun tun0
# Asignarle a la interfaz una dirección IP de cualquiera de las formas anteriormente vistas.

Crear interfaz túnel tun0 de manera persistente: systemd.netdev

Crear el fichero /etc/systemd/network/tun0.netdev

[NetDev]
Name=tun0
Kind=tun
systemctl restart systemd-networkd

Ahora simplemente se le asigna la dirección IP estática como otra interfaz más del sistema, en nuestro supuesto sería la dirección 10.0.0.1/30 (broadcast 10.0.0.3). Al ya estar creada la interfaz túnel, el cliente ssh simplemente puede utilizarla y establecer la comunicación con el destino. El uso de root en el destino es obligatorio para poder hacer el enrutamiento, traducción de direcciones, etc. del tráfico proveniente de cliente.

Configuración del servidor de VPN (SSH)

Asignar la IP para la parte del túnel y controlar mediante rutas el uso de la VPN.

ip address add 10.0.0.2/30 dev tun0
ip link set up tun0

Si se requiere tener disponible desde casa la red donde se encuentra el VPS e incluso usar su conexión a internet, simplemente se debe configurar el “postrouting” / “masquerade” para hacer NAT.

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o venet0 -j MASQUERADE

NOTA: En el ejemplo, el servidor VPS tiene la IP publica y la red privada en la misma interfaz. De tener interfaces diferentes, una para la salida a internet y otra para la red LAN, se tendrá que crear una regla para cada interfaz. Dependiendo de lo que se quiera tener accesible, internet y/o red LAN.

Si se requiere que desde el servidor remoto VPS se pueda acceder también a la red de casa o únicamente al PC que está al otro extremo del túnel, hay que configurar una ruta acorde en el servidor VPS. En el PC de casa se debe configurar también el NAT si se quiere tener disponible el resto de la red.

Los espacios de nombres como ya se comentó son independientes y además son de ámbito local.

Servidor VPS remoto.

ip route add 192.168.178.0/24 via 10.0.0.1 dev tun0    # Configura una ruta para 192.168.178.0/24

PC Cliente (casa).

echo 1 > /proc/sys/net/ipv4/ip_forward                  # Activa el reenvío de IPs.
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE    # Deja accesible toda la red del PC de casa por medio de NAT.

Este acceso por parte del servidor de VPN a la red cliente no está disponible si se usa otro espacio de nombres de red en el cliente para configurar el túnel (Opción 2). Por lo tanto si se quiere compartir puertos, el extremo por el cual se sale a internet debe de redireccionar los puertos. Para eso se puede usar en el host remoto socat o iptables.

socat TCP-LISTEN:8080,fork TCP:10.0.0.1:80 # Copartiendo el puerto 80 del pc de casa en la red e internet si tiene el puerto abierto del PC remoto.
socat TCP-LISTEN:2222,fork TCP:10.0.0.1:22 # SSH en el puerto 2222.

Reforzar la estabilidad de las conexiones

Se pueden configurar los clientes y/o los servidores ssh para mantener las conexiones activas frente a condiciones de mala conectividad.

Cliente de SSH.

Editar el fichero /etc/ssh/ssh_config: Indica al cliente de ssh que envíe un paquete cada 120 segundos al servidor para mantener activa la comunicación.

Host *
ServerAliveInterval 120

Servidor SSH.

Editar el fichero /etc/ssh/sshd_config.

# Envía un paquete cada 120 segundos al cliente para mantener activa la comunicación.
ClientAliveInterval 120
 
# Se da por inactiva la conexión cuando no se ha recibido respuesta después de 360 intentos. 360*120=43200=12h
ClientAliveCountMax 360   

Redirigir todo el tráfico al túnel SSH (VPN)

Para redirigir todo el tráfico que generen las aplicaciones del sistema, ya sea el generado por el propio escritorio mediante gadgets medioambientales, actualizaciones del sistema, clientes p2p torrent, comandos como curl, wget, etc. Lo mejor es realizar la VPN ssh usando un espacio de nombres de red alternativo para la interfaz tun0, como se vio anteriormente en la opción 2. Una vez se tenga ese nuevo espacio de red funcionando, se cierra el escritorio y el display manager y/o servidor gráfico. Esto no es obligatorio si se quiere disponer de dos escritorios diferentes simultáneamente, uno con la conexión normal y otro con la VPN.

Una vez nos encontremos en una tty, arrancamos una shell bash en ese nuevo espacio de red creado anteriormente y ejecutamos en dicha shell de nuevo el display manager o directamente el escritorio, por ejemplo de ser xfce4, con ejecutar startxfce4 sería suficiente.

El escritorio y todas las aplicaciones que sobre el mismo corren usarán únicamente la interfaz “tun0” de SSH, es más, la interfaz que normalmente se usa para Internet / LAN no estará accesible. De esta manera todas las aplicaciones saldrán por la conexión SSH de manera transparente. Esto ahorra tiempo y esfuerzo ya que las aplicaciones que se usan para redireccionar tráfico muchas veces no soportan todos los protocolos (ej. torify y Proxychains-ng por citar dos no puede redirigir tráfico UDP). Si el túnel SSH queda desactivado ninguna aplicación tendrá acceso a la red.