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

Comment autoriser l'accès au réseau local tout en étant connecté au VPN Cisco ?

Comment puis-je maintenir l'accès au réseau local tout en étant connecté au VPN Cisco ?

Lors d'une connexion à l'aide du VPN Cisco, le serveur doit pouvoir demander au client d'empêcher l'accès au réseau local.

En supposant que cette option côté serveur ne puisse pas être désactivée, comment peut-on autoriser l'accès au réseau local tout en étant connecté à un client VPN Cisco ?


J'ai toujours pensé qu'il suffisait d'ajouter des routes qui captent le trafic du LAN avec une métrique plus élevée, par exemple :

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

Et essayer de supprimer la route 10.0.x.x -> 192.168.199.12 n'a aucun effet :

>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

Et alors qu'il pourrait encore s'agir simplement d'un problème de routage, les tentatives d'ajout ou de suppression de routes échouent.

A quel niveau le pilote client VPN Cisco fait-il quoi dans la pile réseau qui prend le pas sur la capacité d'un administrateur local à administrer sa machine ?

Le client VPN Cisco ne peut pas utiliser la magie. C'est toujours un logiciel qui tourne sur mon ordinateur. Quel mécanisme utilise-t-il pour interférer avec le réseau de ma machine ? Que se passe-t-il lorsqu'un paquet IP/ICMP arrive sur le réseau ? Où, dans la pile réseau, le paquet est-il mangé ?

Voir aussi


Edit: Ce que je n'ai pas encore essayé :

>route delete 10.0.*
  • *

Mise à jour: Puisque Cisco a abandonné son ancien client, au profit de AnyConnect (VPN basé sur HTTP SSL), cette question, non résolue, peut être laissée comme une relique de l'histoire.

A l'avenir, nous pouvons essayer de résoudre le même problème avec leur nouveau client .

Réponses (9)

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

Le problème avec Anyconnect est qu'il modifie d'abord la table de routage, puis la garde et la répare si vous la modifiez manuellement. J'ai trouvé un moyen de contourner ce problème. Il fonctionne avec les versions 3.1.00495, 3.1.05152, 3.1.05170, et probablement avec tout ce qui fait partie de la famille 3.1. Peut fonctionner avec d'autres versions, au moins une idée similaire devrait fonctionner en supposant que le code ne soit pas réécrit. Heureusement pour nous, Cisco a mis l'appel “baby is awake” de la baby-sitter dans une bibliothèque partagée. L'idée est donc que nous empêchons toute action de vpnagentd via LD_PRELOAD.

  1. D'abord nous créons un fichier hack.c :

Note : Ce code ne fonctionne qu'avec Linux. Pour appliquer cette solution à une machine macOS, voir la version adaptée à macOS .

  1. Ensuite, on le compile comme ceci :

  2. Installez libhack.so dans le chemin de la bibliothèque Cisco :

  3. Faites descendre l'agent :

  4. Assurez-vous qu'il est vraiment en panne

  5. Ensuite, corrigez /etc/init.d/vpnagentd en ajoutant LD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.soà l'endroit où le vpnagentd est invoqué pour qu'il ressemble à ceci :

  6. Maintenant, lancez l'agent :

  7. Réparez iptables, parce que AnyConnect s'en prend à eux :

  8. Maintenant, réparez les routes comme vous le souhaitez, par exemple :

  9. Vérifiez s'ils sont vraiment là :

Une version précédente, plus simple, de ce hack donnait une fonction qui ne faisait que “retourner 0” ; - ce poster indiquait que “Le seul effet secondaire que j'ai observé jusqu'à présent est que vpnagentd utilise 100% du CPU comme indiqué par le top, mais le CPU global n'est que de 3% d'utilisateur et 20% de système, et le système est parfaitement réactif. Je l'ai tracé, il semble faire deux sélections en boucle lorsqu'il revient rapidement des deux au repos, mais il ne lit ou n'écrit jamais - je suppose que l'appel que j'ai coupé avec LD_PRELOAD était censé lire. Il y a peut-être un moyen plus propre de le faire, mais il me suffit pour l'instant. Si quelqu'un a une meilleure solution, veuillez partager”.

Le problème avec ce hack trivial est qu'il a fait en sorte qu'un seul noyau de cpu soit à 100% tout le temps, réduisant effectivement le nombre de threads de votre cpu matériel d'une unité - que votre connexion vpn soit active ou non. J'ai remarqué que les sélections effectuées par le code se trouvaient sur une socket netlink, qui envoie des données à vpnagentd lorsque la table de routage change. vpnagentd ne cesse de remarquer qu'il y a un nouveau message sur la socket netlink et appelle le routeCallBackHandler pour qu'il s'en occupe, mais comme le hack trivial n'efface pas le nouveau message, il continue d'être appelé encore et encore. le nouveau code fourni ci-dessus efface les données netlink pour que la boucle sans fin qui a causé le processeur à 100% ne se produise pas.

Si quelque chose ne fonctionne pas, faites gdb -p $(pidof vpnagentd), une fois attaché :

b socket
c
bt

et voyez dans quel appel vous êtes. Ensuite, devinez lequel vous voulez couper, ajoutez-le à hack.c et recompilez.

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

C'est TRES compliqué, mais si vous créez une VM minimale en utilisant VMWare Player ou un logiciel similaire, et que vous utilisez le client VPN AnyConnect de Cisco, il est possible de configurer le routage comme vous le souhaitez en utilisant les adaptateurs de réseau virtuel VMWare, ou simplement d'utiliser la VM pour accéder à toutes les ressources nécessaires via le VPN SSL de Cisco et les fichiers “glisser/déposer” vers/depuis votre machine actuelle.

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

(http://www.shrew.net “Free as of March 2013”) Le logiciel Soft VPN a fait l'affaire pour moi aussi, comme l'a suggéré Ian Boyd**.

Il peut importer les profils des clients VPN Cisco. J'ai utilisé le client VPN Cisco version 5.0.05.0290, et après avoir installé le VPN Shrew (version 2.1.7) et importé le profil Cisco, j'ai pu accéder au réseau local tout en étant connecté au VPN d'entreprise sans aucune configuration supplémentaire de la connexion (ou du logiciel) VPN Shrew.

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

Merci à Sasha Pachev pour le joli hack ci-dessus.

vpnagentd s'embrouille également avec le résolveur en écrasant les modifications apportées à /etc/resolv.conf. Je l'ai résolu en gagnant finalement la course contre lui :

#!/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

N'oubliez pas de faire chattr -i /etc/resolv.conf lors de la déconnexion.

J'essaie de le résoudre en interceptant le callback, comme pour la méthode des routes ci-dessus, mais je ne trouve pas encore le callback ou la méthode correspondante.

Update1/2 : Un strace a révélé que vpnagentd utilise l'API inotify pour surveiller les modifications du fichier de résolution. A partir de là, c'était la descente. Voici le hack supplémentaire :

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

C'est un peu exagéré, c'est vrai, car cela désactive la surveillance de tous les fichiers pour l'agent. Mais ça semble bien fonctionner.

Le script wrapper du client vpn ci-dessous intègre toutes les fonctionnalités (mises à jour pour inclure ce hack supplémentaire). chattr n'est plus utilisé/nécessaire.

Mise à jour 3 : correction des paramètres de nom d'utilisateur/mot de passe dans le script. Il utilise maintenant un fichier vpn.conf avec le format décrit ci-dessous(et les permissions de root uniquement).

#!/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
2019-02-05 01:45:11 +0000

Pour ceux qui cherchent à garder le contrôle de leur table de routage lorsqu'ils utilisent un VPN SSL Cisco AnyConnect, consultez OpenConnect . Il prend en charge le VPN SSL AnyConnect de Cisco et ne tente pas de perturber ou de “sécuriser” les entrées de la table de routage. @Vadzim y fait allusion dans un commentaire ci-dessus .

Après avoir tout essayé, à l'exception de la correction du client de mobilité sécurisée AnyConnect, j'ai réussi à le remplacer sous Windows par OpenConnect GUI . Cela m'a permis de maintenir la connectivité avec les ressources locales (et de mettre à jour la table de routage).

J'utilise OpenConnect sur Windows mais il supporte également Linux, BSD, et macOS (entre autres plateformes) selon la page du projet .

4
4
4
2012-06-17 13:37:24 +0000

Ma société utilise toujours ce vpn. Le client vpnc modifie simplement les paramètres d'iptables de cette façon :

# 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

Il filtre tout sauf le trafic vpn.

Il suffit de placer le filtre dans un fichier avec iptables-save, d'ajouter les lignes d'accès INPUT et OUTPOUT qui correspondent à vos besoins et de réappliquer le fichier avec iptables-restore.

par exemple pour accéder à un réseau local sur 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
3
3
3
2014-02-28 10:12:50 +0000

Comme je ne peux pas ajouter de commentaires, je vais poster ici. Je suis sous Windows.

La solution utilisant une machine virtuelle et faisant tourner AnyConnect à l'intérieur de la VM, puis utilisant la VM comme médiateur entre votre environnement de travail et le réseau de votre entreprise ne fonctionnera pas si votre “cher” département informatique fait passer la version 0.0.0.0 par le VPN ; ainsi même votre réseau local (y compris celui-ci entre votre PC local et la VM) est acheminé par le VPN(sic !).

J'ai essayé d'appliquer la solution publiée par @Sasha Pachev mais j'ai fini par patcher le .dll pour qu'il renvoie 0 au début de la fonction. Finalement, après quelques combats avec la bibliothèque dynamique, j'ai pu modifier les tables de routage en fonction de mes besoins mais apparemment ce n'est pas suffisant !

Même si mes règles semblent être correctes pour réaliser le split tunneling, j'obtiens toujours General Failure._Avez-vous rencontré un problème similaire à celui que vous avez pu résoudre ?

  • Ma passerelle vers Internet est 192.168.163.2
  • Ma passerelle vers le réseau de l'entreprise est 10.64.202.1 (donc 10.. entier. * sous-réseau que je traite comme “comapny’s”)

Voici à quoi ressemble ma table de routage maintenant (après des modifications manuelles alors que le VPN est activé)

pourtant les résultats du ping suivent

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.

Juste pour la référence, Voici à quoi ressemble le tableau des routes lorsque le VPN est déconnecté (sans modification)

et voici à quoi ressemble le tableau lorsque le VPN est connecté (sans modification) dans ce cas, lorsque j'essaie de faire un ping 8.8.8.8 j'obtiens simplement un timeout (puisque le pare-feu de la société ne permet pas au trafic de sortir de l'intranet)

.

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

Je ne sais pas si je l'ai bien compris, mais je clarifie d'abord ma compréhension :

Vous avez un LAN local (par exemple, disons 10.0.0.0/16, et un serveur VPN Cisco distant (par exemple, 64.0.0.0/16). Vous voulez vous connecter au serveur VPN par le biais du client VPN Cisco et pourtant vous devez avoir l'accès au réseau local. Dans ce cas, vous voulez séparer l'ensemble 10.0.x.x/16 de la connexion VPN). La route suivante doit être ajoutée dans un client Mac :

/sbin/route add -net 10.0 -interface en1

où en1 est l'interface par laquelle vous êtes connecté à votre LAN. Je sais que vous pouvez ajouter la même chose sous Windows et Linux.

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

Des nouvelles à ce sujet ?

A quel niveau le pilote client VPN Cisco fait-il quoi dans la pile réseau qui prend le pas sur la capacité d'un administrateur local à administrer sa machine ?

Je suis tout à fait d'accord et je me demandais la même chose.

Quoi qu'il en soit, c'est une application qui nécessite des privilèges d'administrateur pour s'installer et pendant qu'elle tourne, elle peut très bien filtrer ce que vous faites…

Mes tentatives sur Windows échouent aussi :

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

Haha. Il semble qu'il n'y ait pas de métrique en dessous de 20.