2011-05-17 14:23:58 +0000 2011-05-17 14:23:58 +0000
85
85

¿Cómo permitir el acceso a la LAN local mientras se está conectado a la VPN de Cisco?

¿Cómo puedo mantener el acceso a la LAN local mientras estoy conectado a Cisco VPN?

Cuando se conecta con Cisco VPN, el servidor tiene la capacidad de indicar al cliente que impida el acceso a la LAN local.

Suponiendo que esta opción del lado del servidor no se pueda desactivar, ¿cómo se puede permitir el acceso a la LAN local mientras se está conectado con un cliente Cisco VPN?

  • *

Solía pensar que era simplemente una cuestión de rutas que se añaden que capturan el tráfico de la LAN con una métrica más alta, por ejemplo:

Network 
Destination Netmask Gateway Interface Metric
   10.0.0.0 255.255.0.0 10.0.0.3 10.0.0.3 20 <--Local LAN
   10.0.0.0 255.255.0.0 192.168.199.1 192.168.199.12 1 <--VPN Link

Y tratar de eliminar la ruta 10.0.x.x -> 192.168.199.12 no tienen ningún efecto:

>route delete 10.0.0.0
>route delete 10.0.0.0 mask 255.255.0.0
>route delete 10.0.0.0 mask 255.255.0.0 192.168.199.1
>route delete 10.0.0.0 mask 255.255.0.0 192.168.199.1 if 192.168.199.12
>route delete 10.0.0.0 mask 255.255.0.0 192.168.199.1 if 0x3

Y aunque todavía podría ser simplemente un problema de enrutamiento, los intentos de añadir o eliminar rutas fallan.

¿A qué nivel hace el controlador del cliente Cisco VPN en la pila de red que anula la capacidad de un administrador local para administrar su máquina?

El cliente Cisco VPN no puede estar empleando magia. Sigue siendo un software que se ejecuta en mi ordenador. ¿Qué mecanismo está utilizando para interferir en la red de mi máquina? ¿Qué sucede cuando un paquete IP/ICMP llega a la red? ¿En qué parte de la pila de red se come el paquete?

Vea también

Edición: Cosas que aún no he probado:

>route delete 10.0.*
  • *

Actualización: Dado que Cisco ha abandonado su antiguo cliente, en favor de AnyConnect (VPN basada en HTTP SSL), esta cuestión, sin resolver, puede quedar como una reliquia de la historia.

De cara al futuro, podemos intentar resolver el mismo problema con su nuevo cliente .

Respuestas (10)

56
56
56
2013-02-05 00:07:44 +0000

El problema con Anyconnect es que primero modifica la tabla de enrutamiento, luego la cuida y la arregla si la modificas manualmente. He encontrado una solución para esto. Funciona con las versiones 3.1.00495, 3.1.05152, 3.1.05170, y probablemente con cualquier otra de la familia 3.1. Puede funcionar con otras versiones, al menos una idea similar debería funcionar asumiendo que el código no se reescriba. Afortunadamente para nosotros, Cisco ha puesto la llamada de la niñera “el bebé está despierto” en una biblioteca compartida. Así que la idea es que evitemos la acción de vpnagentd a través de LD_PRELOAD.

  1. Primero creamos un archivo hack.c:

Nota: Este código sólo funciona con Linux. Para aplicar esta solución a una máquina con macOS, véase la versión adaptada a macOS .

  1. Luego lo compilamos así:

  2. Instale libhack.so en la ruta de la biblioteca de Cisco:

  3. Bajar el agente:

  4. Asegúrese de que realmente está caído:

  5. Luego arregla /etc/init.d/vpnagentd añadiendo LD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.so donde se invoca a vpnagentd para que se vea así:

  6. Ahora inicie el agente:

  7. Arregla los iptables, porque AnyConnect se mete con ellos:

  8. Ahora arregla las rutas a tu gusto, por ejemplo:

  9. Comprueba si realmente están ahí:

Una versión anterior, más simple, de este hack daba una función que sólo hacía “return 0;” - ese póster señaló que “El único efecto secundario que he observado hasta ahora es que vpnagentd está usando el 100% de la CPU según lo informado por top, pero la CPU general es sólo el 3% del usuario y el 20% del sistema, y el sistema responde perfectamente. Lo he estratificado, parece que está haciendo dos selects en un bucle cuando está inactivo volviendo de ambos rápidamente, pero nunca lee ni escribe - supongo que la llamada que corté con LD_PRELOAD se suponía que debía leer. Puede que haya una forma más limpia de hacerlo, pero de momento me vale. Si alguien tiene una solución mejor, por favor, compártala”.

El problema con el hack trivial es que causaba que un solo núcleo de la cpu estuviera al 100% todo el tiempo, reduciendo efectivamente su conteo de hilos de la cpu por hardware en uno - ya sea que su conexión vpn estuviera activa o no. Me di cuenta de que las selecciones que el código estaba haciendo estaban en un socket netlink, que envía datos a vpnagentd cuando la tabla de enrutamiento cambia. vpnagentd sigue notando que hay un nuevo mensaje en el socket netlink y llama al routeCallBackHandler para lidiar con él, pero desde que el hack trivial no borra el nuevo mensaje sigue siendo llamado una y otra vez. el nuevo código proporcionado arriba limpia los datos del netlink para que el bucle sin fin que causó el 100% de la cpu no suceda.

Si algo no funciona, haz gdb -p $(pidof vpnagentd), una vez que se adjunta:

b socket
c
bt

y mira en qué llamada estás. Entonces adivina cual quieres cortar, añádelo a hack.c y recompila.

11
11
11
2011-12-24 14:43:04 +0000

Esto es MUY complicado, pero si creas una VM mínima usando VMWare Player o similar, y ejecutas el cliente Cisco AnyConnect VPN en ella, podría ser posible configurar el enrutamiento como quieras usando los adaptadores de red virtuales de VMWare, o simplemente usar la VM para acceder a cualquier recurso que se requiera a través de Cisco SSL VPN y “arrastrar/soltar” archivos a/desde tu máquina real.

7
7
7
2013-03-05 13:17:21 +0000

(http://www.shrew.net “Free as of March 2013”) El software Soft VPN también me sirvió, como sugirió Ian Boyd.

Puede importar perfiles de clientes Cisco VPN. He utilizado la versión 5.0.05.0290 del cliente VPN de Cisco, y después de instalar la VPN de Shrew (versión 2.1.7) e importar el perfil de Cisco, pude acceder a la LAN local mientras estaba conectado a la VPN corporativa sin ninguna configuración adicional de la conexión VPN de Shrew (o del software).

5
5
5
2015-01-28 18:51:15 +0000

Gracias a Sasha Pachev por el bonito hack de arriba.

vpnagentd también se mete con el resolver sobrescribiendo los cambios hechos en /etc/resolv.conf. Lo resolví ganando eventualmente la carrera contra él:

#!/bin/bash

dnsfix() {
    [-f /etc/resolv.conf.vpnbackup] || echo "Not connected?" >&2 || return 0 # do nothing in case of failure
    while ! diff -q /etc/resolv.conf /etc/resolv.conf.vpnbackup #>/dev/null
    do
         cat /etc/resolv.conf.vpnbackup >/etc/resolv.conf
    done
    chattr +i /etc/resolv.conf
    diff -q /etc/resolv.conf /etc/resolv.conf.vpnbackup >/dev/null 
}

while ! dnsfix
do
    echo "Retrying..."
    chattr -i /etc/resolv.conf
done

No te olvides de chattr -i /etc/resolv.conf al desconectar.

Estoy tratando de resolverlo interceptando el callback, como para el método de las rutas de arriba, pero todavía no puedo encontrar el callback o método correspondiente.

Actualización1/2: Un strace reveló que vpnagentdestá usando la API de inotify para monitorear los cambios en el archivo del resolver. A partir de ahí todo fue cuesta abajo. Aquí está el hack adicional:

int _ZN18CFileSystemWatcher11AddNewWatchESsj(void *string, unsigned int integer)
{
  return 0;
}

Esto es un poco exagerado, ya que desactiva todos los archivos del agente. Pero parece que funciona bien.

El script envolvente del cliente vpn de abajo integra toda la funcionalidad (actualizado para incluir este hack adicional). chattr ya no se usa/necesita.

Actualización 3: Se ha corregido la configuración del nombre de usuario/contraseña en el script. Ahora utiliza un archivo vpn.conf con el formato descrito a continuación(y permisos sólo para root).

#!/bin/bash

# Change this as needed
CONF="/etc/vpnc/vpn.conf"
# vpn.conf format
#gateway <IP>
#username <username>
#password <password>
#delete_routes <"route spec"...> eg. "default gw 0.0.0.0 dev cscotun0"
#add_routes <"route spec"...> eg. "-net 192.168.10.0 netmask 255.255.255.0 dev cscotun0" "-host 10.10.10.1 dev cscotun0"

ANYCONNECT="/opt/cisco/anyconnect"

usage() {
    echo "Usage: $0 {connect|disconnect|state|stats|hack}"
    exit 1
}

CMD="$1"
[-z "$CMD"] && usage

ID=`id -u`

VPNC="$ANYCONNECT/bin/vpn"

dnsfix() {
    [-f /etc/resolv.conf.vpnbackup] || echo "Not connected?" >&2 || return 0 # do nothing in case of failure
    while ! diff -q /etc/resolv.conf /etc/resolv.conf.vpnbackup >/dev/null
    do
         cat /etc/resolv.conf.vpnbackup >/etc/resolv.conf
    done
# chattr +i /etc/resolv.conf
    diff -q /etc/resolv.conf /etc/resolv.conf.vpnbackup >/dev/null 
}

case "$CMD" in
    "connect")
        [$ID -ne 0] && echo "Needs root." && exit 1
        HOST=`grep ^gateway $CONF | awk '{print $2}'`
        USER=`grep ^user $CONF | awk '{print $2}'`
        PASS=`grep ^password $CONF | awk '{print $2}'`
        OLDIFS=$IFS
        IFS='"'
        DEL_ROUTES=(`sed -n '/^delete_routes/{s/delete_routes[\t\"]*//;s/\"[\t]*\"/\"/g;p}' $CONF`)
        ADD_ROUTES=(`sed -n '/^add_routes/{s/add_routes[\t\"]*//;s/\"[\t]*\"/\"/g;p}' $CONF`)
        IFS=$OLDIFS

        /usr/bin/expect <<EOF
set vpn_client "$VPNC";
set ip "$HOST";
set user "$USER";
set pass "$PASS";
set timeout 5
spawn \$vpn_client connect \$ip
match_max 100000
expect { 
    timeout {
        puts "timeout error\n"
        spawn killall \$vpn_client
        exit 1
    }
    ">> The VPN client is not connected." { exit 0};
    ">> state: Disconnecting" { exit 0};
    "Connect Anyway?"
}
sleep .1
send -- "y\r"
expect { 
    timeout {
        puts "timeout error\n"
        spawn killall \$vpn_client
        exit 1
    }
    "Username:"
}
sleep .1
send -- "\$user\r"
expect { 
    timeout {
        puts "timeout error\n"
        spawn killall \$vpn_client
        exit 1
    }
    "Password: "
}
send -- "\$pass\r";
expect eof
EOF
        sleep 2
        # iptables
        iptables-save | grep -v DROP | iptables-restore

        # routes
        for ROUTE in "${DEL_ROUTES[@]}"
        do
# echo route del $ROUTE
            route del $ROUTE
        done
        for ROUTE in "${ADD_ROUTES[@]}"
        do
# echo route add $ROUTE
            route add $ROUTE
        done

        # dns
        while ! dnsfix
        do
            echo "Try again..."
# chattr -i /etc/resolv.conf
        done

        echo "done."
        ;;
    "disconnect")
# [$ID -ne 0] && echo "Needs root." && exit 1
        # dns
# chattr -i /etc/resolv.conf

        $VPNC disconnect
        ;;
    "state"|"stats")
        $VPNC $CMD
        ;;
    "hack")
        [$ID -ne 0] && echo "Needs root." && exit 1
        /etc/init.d/vpnagentd stop
        sleep 1
        killall -9 vpnagentd 2>/dev/null
        cat - >/tmp/hack.c <<EOF
#include <sys/socket.h>
#include <linux/netlink.h>

int _ZN27CInterfaceRouteMonitorLinux20routeCallbackHandlerEv()
{
  int fd=50; // max fd to try
  char buf[8192];
  struct sockaddr_nl sa;
  socklen_t len = sizeof(sa);

  while (fd) {
     if (!getsockname(fd, (struct sockaddr *)&sa, &len)) {
        if (sa.nl_family == AF_NETLINK) {
           ssize_t n = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
        }
     }
     fd--;
  }
  return 0;
}

int _ZN18CFileSystemWatcher11AddNewWatchESsj(void *string, unsigned int integer)
{
  return 0;
}
EOF
        gcc -o /tmp/libhack.so -shared -fPIC /tmp/hack.c
        mv /tmp/libhack.so $ANYCONNECT
        sed -i "s+^\([\t]*\)$ANYCONNECT/bin/vpnagentd+LD_PRELOAD=$ANYCONNECT/lib/libhack.so $ANYCONNECT/bin/vpnagentd+" /etc/init.d/vpnagentd
        rm -f /tmp/hack.c
        /etc/init.d/vpnagentd start
        echo "done."
        ;;
    *)
        usage
        ;;
esac
4
4
4
2012-06-17 13:37:24 +0000

Mi empresa sigue usando esa vpn. El cliente vpnc simplemente cambia la configuración de iptables de esa manera :

# iptables-save # Generated by iptables-save v1.4.10 on Sun Jun 17 14:12:20 2012 \*filter :INPUT DROP [0:0] :FORWARD ACCEPT [0:0] :OUTPUT DROP [0:0] -A INPUT -s 123.244.255.254/32 -d 192.168.0.14/32 -j ACCEPT -A INPUT -i tun0 -j ACCEPT -A INPUT -i lo0 -j ACCEPT -A INPUT -j DROP -A OUTPUT -s 192.168.0.14/32 -d 123.244.255.254/32 -j ACCEPT -A OUTPUT -o tun0 -j ACCEPT -A OUTPUT -o lo0 -j ACCEPT -A OUTPUT -j DROP COMMIT

Filtra todo excepto el tráfico de la vpn.

Simplemente obtenga el filtro en un archivo con iptables-save, añada líneas de acceso INPUT y OUTPOUT que se ajusten a sus necesidades y vuelva a aplicar el archivo con iptables-restore.

por ejemplo para acceder a una red local en 192.168.0

# Generated by iptables-save v1.4.10 on Sun Jun 17 14:12:20 2012 \*filter :INPUT DROP [0:0] :FORWARD ACCEPT [0:0] :OUTPUT DROP [0:0] -A INPUT -s 123.244.255.254/32 -d 192.168.0.14/32 -j ACCEPT -A INPUT -s 192.168.0.0/24 -d 192.168.0.14/32 -j ACCEPT #local in -A INPUT -i tun0 -j ACCEPT -A INPUT -i lo0 -j ACCEPT -A INPUT -j DROP -A OUTPUT -s 192.168.0.14/32 -d 123.244.255.254/32 -j ACCEPT -A OUTPUT -s 192.168.0.14/32 -d 192.168.0.0/24 -j ACCEPT #local out -A OUTPUT -o tun0 -j ACCEPT -A OUTPUT -o lo0 -j ACCEPT -A OUTPUT -j DROP COMMIT
4
4
4
2019-02-05 01:45:11 +0000

Para aquellos que buscan mantener el control de su tabla de enrutamiento cuando se utiliza un Cisco AnyConnect SSL VPN, echa un vistazo a OpenConnect . Es compatible con Cisco AnyConnect SSL VPN y no intenta interrumpir o “asegurar” las entradas de la tabla de enrutamiento. @Vadzim alude a esto en un comentario anterior .

Después de intentar todo, excepto parchear el AnyConnect Secure Mobility Client, pude reemplazarlo con éxito en Windows con OpenConnect GUI . Esto me permitió mantener la conectividad con los recursos locales (y actualizar la tabla de enrutamiento).

Utilizo OpenConnect en Windows pero también es compatible con Linux, BSD y macOS (entre otras plataformas) según la página del proyecto .

3
3
3
2011-07-23 19:49:44 +0000

¿Alguna noticia sobre esto?

¿A qué nivel hace el controlador del cliente VPN de Cisco en la pila de red que anula la capacidad de un administrador local para administrar su máquina?

Estoy totalmente de acuerdo y me preguntaba lo mismo.

De todas formas, es una aplicación que requiere privilegios de administrador para instalarse y mientras se ejecuta puede muy bien filtrar lo que haces…

Mis intentos en Windows también fallan:

route change 0.0.0.0 mask 0.0.0.0 192.168.1.1 metric 1
 OK!

IPv4 Route Table
===========================================================================
Active Routes:
Network Destination Netmask Gateway Interface Metric
          0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.230 21 <-- LAN
          0.0.0.0 0.0.0.0 192.168.120.1 192.168.120.3 2 <-- VPN

Jaja. No hay métrica por debajo de 20 aquí parece.

3
3
3
2014-02-28 10:12:50 +0000

Como no puedo añadir comentarios, lo publicaré aquí. Estoy corriendo en Windows.

La solución de utilizar la máquina virtual y ejecutar AnyConnect dentro de la VM y luego utilizar la VM como un mediador entre su entorno de trabajo y la red de la empresa no funcionará si su “amado” departamento de TI rutas 0.0.0.0 a través de VPN por lo tanto, incluso su red local (incluyendo esto entre su PC local y la VM) se encamina a través de la VPN (sic!).

Intenté aplicar la solución publicada por @Sasha Pachev pero finalmente acabé parcheando la .dll para que devuelva 0 al principio de la función. Finalmente, después de pelearme con la librería dinámica, pude modificar las tablas de enrutamiento de acuerdo a mis necesidades, pero aparentemente eso no es suficiente.

A pesar de que mis reglas parecen ser correctas para lograr un túnel dividido, sigo obteniendo un Fallo General.¿Te has encontrado con un problema similar y has podido resolverlo?

  • Mi puerta de entrada a Internet es 192.168.163.2
  • Mi puerta de entrada a la red de la empresa es 10.64.202.1 (por lo tanto toda la subred 10... \ * subred que trato como “de la empresa”)

Así es como mi tabla de enrutamiento se ve ahora (después de las modificaciones manuales, mientras que la VPN está en)

Sin embargo, el resultado de ping son los siguientes

C:\Users\Mike>ping -n 1 10.64.10.11
Reply from 10.64.10.11: bytes=32 time=162ms TTL=127

C:\Users\Mike>ping -n 1 8.8.8.8
PING: transmit failed. General failure.

C:\Users\Mike>ping -n 1 192.168.163.2
General failure.

Sólo para la referencia, a continuación se muestra cómo se ve la tabla de rutas cuando la VPN está desconectada (sin modificar)

y así es como se ve la tabla cuando la VPN está conectada (sin modificar) en ese caso cuando estoy tratando de hacer ping a 8.8.8.8 simplemente obtengo tiempo de espera (ya que el firewall de la empresa no permite que el tráfico salga de la intranet)

3
3
3
2011-11-06 11:44:34 +0000

No sé si lo he entendido bien, pero primero aclaro lo que he entendido:

Tienes una LAN local (por ejemplo, digamos 10.0.0/16, y un servidor VPN Cisco remoto (por ejemplo, 64.0.0/16). Usted quiere conectarse al servidor VPN a través del cliente Cisco VPN y, sin embargo, necesita tener el acceso a la LAN. En este caso se quiere separar toda la 10.0.x.x/16 de la conexión VPN). Hay que añadir la siguiente ruta en el cliente Mac:

/sbin/route add -net 10.0 -interface en1

donde en1 es la interfaz a través de la cual estás conectado a tu LAN. Sé que se puede añadir lo mismo en Windows y Linux también.

1
1
1
2014-05-01 03:42:23 +0000

Intenta eliminar esas entradas con gateway 10.64.202.13 mira si el ping 8.8.8.8 funciona y luego vuelve a añadirlas una a una e identifica cuál es la que causa el problema.

¿Cómo has parcheado la DLL? Ni siquiera puedo modificar la tabla de enrutamiento porque sigue añadiendo el 0.0.0.0 con la puerta de enlace VPN de nuevo.