Al conectarnos por VPN a la red de nuestra empresa, de algún cliente, o para consumir algún contenido específico, a veces podemos tener problemas con las configuraciones de ruteo que la conexión genera al establecerse.

Al configurar una VPN en un firewall o algún dispositivo que soporte la terminación de túneles, uno debe establecer la configuración de ruteo que los clientes obtendrán al conectarse, o más especificamente, que redes le diremos que puede conocer por el túnel que estableció, que puede ser una, muchas o todas.

Si las redes se especifican una por una, es lo que se conoce como split tunneling, ya que el cliente enviará el tráfico hacia esas por el túnel, y el resto del tráfico, lo enviará hacia internet sin tunelizar.

Una opción más segura es forzar al cliente a que envie todo el tráfico por el túnel y que utilice la salida de internet propia de la red de la VPN, esto evita que el usuario, por ejemplo, navegue sin control por internet a la vez que está conectado a recursos corporativos, para hacer esto se fuerza una ruta "default" con destino al tunel. (Se setea el default gateway como el next hope del tunel).

Ahora bien, esta configuración es la que la VPN "propone" al cliente que se conecta y este configura automáticamente mediante los softwares de conexión; pero es posible tocar manualmente la tabla de ruteo para rearmar el flujo del tráfico a nuestro gusto.

Esto podría hacerse manualmente, luego de iniciado el tunel, utilizando comandos para interactuar con la configuración de ruteo.

Pero si quién establece la conexión es un equipo o servidor al que accedemos remotamente desde internet, podríamos perder conectividad con el mismo por el ruteo que trae dicha conexión.

Desde linux, para conectarse con equipos Cisco (en reemplazo de los clientes AnyConnect) se puede utilizar vpnc o openconnect, siendo este segundo más performante y completo en cuanto a funcionalidades, pero que utiliza alguna funcionalidad del primero.

Por lo tanto, veremos como manejar nuestro propio split tunneling con openconnect, pero es posible adaptarlo a vpnc si fuese necesario.

Para configurar el ruteo, por default openconnect utiliza un script en /etc/vpnc/vpnc-script luego de conectarse que se encarga de reconfigurar nuestro ruteo, dns, etc. Podemos especificarle a la conexión que utilice otro para tener el control de dicha configuración. Por lo que vamos a hacer es crear un nuevo script llamado "new-script" en esa ubicación con el siguiente código que adapté del siguiente gist: https://gist.github.com/jagtesh/5531300

add_network ()
{
    export CISCO_SPLIT_INC_${CISCO_SPLIT_INC}_ADDR=$1
    export CISCO_SPLIT_INC_${CISCO_SPLIT_INC}_MASK=$2
    export CISCO_SPLIT_INC_${CISCO_SPLIT_INC}_MASKLEN=$3
    export CISCO_SPLIT_INC=$(($CISCO_SPLIT_INC + 1))
}

# Inicializar variable
export CISCO_SPLIT_INC=0

# Utilizar nuestros DNS
# Comentando esta linea utilizamos los DNS de la VPN.
unset INTERNAL_IP4_DNS

# List of IPs beyond VPN tunnel
add_network 10.0.0.0 255.255.255.0 24
add_network 10.0.1.0 255.255.255.0 24

# Continuar con el script default
. /etc/vpnc/vpnc-script	

Se pueden agregar las redes que se necesite tunelizar según la necesidad, sin depender de la configuración que el admin de la VPN haya decidido fijar, entonces por ejemplo podremos utilizar nuestra salida para navegar y la VPN únicamente para acceder a los recursos de las redes 10.0.0.0/24 y 10.0.1.0/24. (se debe ingresar la red y la máscara en formato numérico y CIDR). Para agregar un host setear la máscara en 255.255.255.255 y 32, Ej:

add_network 10.0.0.1 255.255.255.255 32

Mediante el comando unset INTERNAL_IP4_DNS especificamos que no se utilicen los DNS que trae la VPN, sino seguir usando los nuestros. En caso de no requerirlo, se puede comentar esa línea.

Para utilizar este script, se debe ejecutar openconnect pasándolo como parámetro así:

openconnect -s /etc/vpnc/new-script

Saludos