Question Comment permettre l'accès au réseau local local lorsque vous êtes connecté à Cisco VPN?


Comment puis-je conserver un accès local au réseau local lorsque vous êtes connecté à Cisco VPN?

Lors de la connexion à l'aide de Cisco VPN, le serveur doit être en mesure de demander au client d'empêcher l'accès au réseau local.

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


J'avais l'habitude de penser qu'il s'agissait simplement d'ajouter des routes qui capturent le trafic 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 en essayant de supprimer le 10.0.x.x -> 192.168.199.12 route 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 bien qu'il puisse 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 Cisco VPN effectue-t-il dans la pile réseau une prise en charge de la capacité d'un administrateur local à administrer son ordinateur?

Le client Cisco VPN ne peut pas utiliser la magie. C'est toujours un logiciel qui fonctionne 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ù le paquet est-il mangé dans la pile de réseau?

Voir également


Modifier: Les choses que je n'ai pas encore essayées:

>route delete 10.0.*

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

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


73
2018-05-17 14:23


origine


Le lien VPN a une métrique inférieure et est donc essayé avant votre itinéraire local. Augmenter la métrique de votre réseau local local va probablement désactiver votre réseau local. Si le VPN n'est pas configuré pour acheminer tout le trafic, la commutation de votre sous-réseau domestique pourrait être une solution. Quelles sont les adresses IP auxquelles vous devez accéder via ce VPN? Est-ce la totalité du 10.0.0.0 côté VPN? - pberlijn
Cela semble très bien être le problème; je pensais métrique de plus élevé = mieux. - Ian Boyd
Effectivement, Métrique inférieure = préféré. - Jonathon Reinhart
Cisco AnyConnect peut être remplacé par le client alternatif OpenConnect principalement compatible décrit à serverfault.com/a/664097/104573 - Vadzim


Réponses:


Le problème avec Anyconnect est qu'il modifie d'abord la table de routage, puis le garde et le corrige si vous le modifiez manuellement. J'ai trouvé une solution pour cela. Fonctionne avec la version 3.1.00495, 3.1.05152, 3.1.05170 et probablement tout autre élément 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 de baby-sitter "bébé est réveillé" dans une bibliothèque partagée. L'idée est donc d'empêcher l'action de vpnagentd via LD_PRELOAD.

  1. Nous créons d'abord un fichier hack.c:

    #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;
    }
    
  2. Ensuite, compilez-le comme ceci:

    gcc -o libhack.so -shared -fPIC hack.c
    
  3. Installer libhack.so dans le chemin de la bibliothèque Cisco:

    sudo cp libhack.so  /opt/cisco/anyconnect/lib/
    
  4. Amenez l'agent:

    /etc/init.d/vpnagentd stop
    
  5. Assurez-vous qu'il est vraiment bas

    ps auxw | grep vpnagentd
    

    Si non, kill -9 juste pour être sûr.

  6. Ensuite, corrigez /etc/init.d/vpnagentd en ajoutant LD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.so où le vpnagentd est appelé, il ressemble à ceci:

    LD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.so /opt/cisco/anyconnect/bin/vpnagentd
    
  7. Maintenant, lancez l'agent:

    /etc/init.d/vpnagentd start
    
  8. Réparez iptables, car AnyConnect les perturbe:

    iptables-save | grep -v DROP | iptables-restore
    

    Vous voudrez peut-être faire quelque chose de plus avancé ici pour autoriser l'accès uniquement à certains hôtes LAN.

  9. Maintenant, réparez les routes comme bon vous semble, par exemple:

    route add -net 192.168.1.0 netmask 255.255.255.0 dev wlan0
    
  10. Vérifiez si elles sont vraiment là:

    route -n
    

Une version précédente plus simple de ce hack donnait une fonction qui ne faisait que "retourner 0;" - cette affiche a noté que "le seul effet secondaire que j'ai observé jusqu'à présent est que vpnagentd utilise 100% du processeur comme indiqué par top, mais que le processeur global ne contient que 3% d'utilisateurs et 20% de systèmes, et que le système est parfaitement réactif Je l'ai étalé, il semble faire deux sélections dans une boucle lorsque je reviens rapidement des deux, mais il ne lit ni n'écrit jamais - je suppose que l'appel que j'ai découpé avec LD_PRELOAD était supposé lire. pour le faire, mais c'est assez bon pour moi jusqu'à présent. Si quelqu'un a une meilleure solution, s'il vous plaît partagez. "

Le problème avec le piratage trivial est qu’un seul cœur cpu est tout le temps à 100%, ce qui réduit effectivement le nombre de threads de votre processeur cpu, que votre connexion vpn soit active ou non. J'ai remarqué que les sélections effectuées par le code étaient sur un 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 le socket netlink et appelle la routeCallBackHandler pour y faire face, mais comme le piratage trivial n'efface pas le nouveau message, il continue à être appelé à plusieurs reprises. le nouveau code fourni ci-dessus vide les données netlink afin que la boucle sans fin qui a provoqué le processeur 100% ne se produise pas.

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

b socket
c
bt

et voir quel appel vous êtes. Puis devinez lequel vous voulez couper, ajoutez-le à hack.c et recompilez.


51
2018-02-05 00:07



C'est du génie. J'essaie de le faire fonctionner sur OSX et j'ai une question: comment avez-vous su que la méthode à remplacer était nommée _ZN27CInterfaceRouteMonitorLinux20routeCallbackHandlerEv? - donturner
@donturner essayer nm /opt/cisco/anyconnect/lib/libvpnagentutilities.dylib | grep routeCallbackHandlerEv et puis vous trouverez __ZN25CInterfaceRouteMonitorMac20routeCallbackHandlerEv - McKelvin
Je l'ai compris en attachant à vpnagentd avec gdb et en définissant divers points d'arrêt. - Sasha Pachev
@McKelvin nm /opt/cisco/anyconnect/lib/libvpnagentutilities.so résultats nm: /opt/cisco/anyconnect/lib/libvpnagentutilities.so: no symbols sur mon AnyConnect sous Ubuntu, il a donc été généré sans informations de table de symboles. Comment as-tu pu obtenir ça? - nephewtom
@SashaPachev Comment pourriez-vous déboguer vpnagentd sans information de symbole? - nephewtom


Ceci est très compliqué, mais si vous créez une VM minimale en utilisant VMWare Player ou similaire et exécutez le client Cisco AnyConnect VPN dans ce cas, il est possible de configurer le routage comme vous le souhaitez en utilisant les cartes réseau virtuelles VMWare. VM pour accéder à toutes les ressources requises via le Cisco SSL VPN et les fichiers "glisser / déposer" vers / depuis votre machine actuelle.


11
2017-12-24 14:43





Musaraigne Logiciel Soft VPN a fait le tour pour moi, aussi, comme Ian Boyd suggéré.

Il peut importer des profils client Cisco VPN. 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 connexion VPN Shrew (ou Logiciel).


5
2018-03-05 13:17



Ce serait incroyable si cela était disponible pour Android. - Gabriel Fair


Grâce à Sasha Pachev pour le joli hack ci-dessus.

vpnagentd perturbe é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:

#!/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 chattr -i /etc/resolv.conf lors de la déconnexion.

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

Mise à jour 1/2: A strace a dévoilé que vpnagentdutilise le inotify API pour surveiller les modifications du fichier de résolution. À partir de là, c'était en descente. Voici le hack supplémentaire:

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

C'est un peu exagéré, car cela désactive tout fichier regarder pour l'agent. Mais semble fonctionner correctement.

Le script d'encapsulation 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 vpn.conf fichier avec le format décrit ci-dessous (et les autorisations 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+\1LD_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

5
2018-01-28 18:51



Votre service de notification a résolu mon nouveau problème (2017-02-25) avec mon installation AnyConnect 3.1.14018: il déconnecte chaque fois que j'ouvre une nouvelle fenêtre de terminal ou un écran GNU. Il regarde / var / run / utmp pour une raison quelconque. Eh bien, plus maintenant, merci! - Martin Dorey
Agréable. Parfois, "overkill" peut être votre ami. :-) - Mauro Lacy


Mon entreprise utilise toujours ce VPN. Le client vpnc modifie simplement vos paramètres iptables de la manière suivante:

# iptables-save
# Généré par iptables-save v1.4.10 sur Sun Jun 17 14:12:20 2012
*filtre
: INPUT DROP [0: 0]
: AVANT ACCEPTER [0: 0]
: OUTPUT DROP [0: 0]
-A INPUT -s 123.244.255.254/32 -d 192.168.0.14/32 -j ACCEPTER
-A INPUT -i tun0 -j ACCEPTER
-A INPUT -i lo0 -j ACCEPTER
-A INPUT -j DROP
-A OUTPUT -s 192.168.0.14/32 -d 123.244.255.254/32 -j ACCEPTER
-A OUTPUT -o tun0 -j ACCEPTER
-A SORTIE -o lo0 -j ACCEPTER
-A SORTIE -j DROP
COMMETTRE

Il filtre tout sauf le trafic VPN.

Obtenez simplement le filtre dans un fichier avec iptables-save, ajoutez les lignes d'accès INPUT et OUTPOUT correspondant à vos besoins et réappliquez le fichier avec iptables-restore.

par exemple pour accéder à un réseau local sur 192.168.0

# Généré par iptables-save v1.4.10 sur Sun Jun 17 14:12:20 2012
*filtre
: INPUT DROP [0: 0]
: AVANT ACCEPTER [0: 0]
: OUTPUT DROP [0: 0]
-A INPUT -s 123.244.255.254/32 -d 192.168.0.14/32 -j ACCEPTER
-A INPUT -s 192.168.0.0/24 -d 192.168.0.14/32 -j ACCEPT #local in
-A INPUT -i tun0 -j ACCEPTER
-A INPUT -i lo0 -j ACCEPTER
-A INPUT -j DROP
-A OUTPUT -s 192.168.0.14/32 -d 123.244.255.254/32 -j ACCEPTER
-A OUTPUT -s 192.168.0.14/32 -d 192.168.0.0/24 -j ACCEPT #local out
-A OUTPUT -o tun0 -j ACCEPTER
-A SORTIE -o lo0 -j ACCEPTER
-A SORTIE -j DROP
COMMETTRE

4
2018-06-17 13:37



C'est faux, ce n'est pas si facile d'ajouter simplement votre itinéraire .. J'ai essayé et ça n'a pas fonctionné .. Client VPN prenant le contrôle de la table de routage du noyau qui ne vous laisse pas modifier - Satish


des nouvelles à ce sujet?

À quel niveau le pilote client Cisco VPN fait-il quoi dans la mise en réseau?   pile qui prend en charge la capacité d'un administrateur local à   administrer leur machine?

Je suis entièrement d'accord et 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 fonctionne, 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. Aucune métrique en dessous de 20 ici, il semble.


3
2017-07-23 19:49



En ce qui concerne Linux, ceci (petefreitag.com/item/753.cfm) semble indiquer que le pare-feu est également impliqué. - Marki
J'ai trouvé ShrewSoft VPN. Il peut se connecter à un serveur VPN Cisco IPSec et ignore la demande de l'administrateur du serveur VPN que je sois déconnecté de mon propre réseau. (Voir superuser.com/questions/312947/... pour des instructions détaillées) Même s'il ne répond pas à cette question, il s'agit d'une solution de contournement. Remarque: ShrewSoft VPN ne fonctionne que pour IPSec; il ne fonctionne pas avec SSL VPN (c.-à-d. client VPN Cisco AnyConnect plus récent) - Ian Boyd


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

Vous avez un réseau local (par exemple, 10.0.0.0/16 et un serveur VPN Cisco distant (par exemple, 64.0.0.0/16). Vous souhaitez vous connecter au serveur VPN via le client VPN Cisco et pourtant vous avez besoin de pour avoir l’accès LAN, dans ce cas vous voulez séparer l’ensemble 10.0.xx / 16 de la connexion VPN). La route suivante doit être ajoutée sur un client Mac:

/sbin/route add -net 10.0 -interface en1

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


3
2017-11-06 11:44



+1 pour le client Mac; ce qui ne s'applique pas à moi Et pendant que cette commande pourrait fonctionner, le client Cisco pourrait le supprimer peu après sa création (le client Cisco semble empêcher quiconque de changer de route). - Ian Boyd