it-swarm.com.de

Wie kann ich lokalen LAN-Zugriff zulassen, während ich mit Cisco VPN verbunden bin?

Wie kann ich den lokalen LAN-Zugang aufrechterhalten, während eine Verbindung zu Cisco VPN besteht?

Bei der Verbindung über Cisco VPN muss der Server den Client anweisen können, den lokalen LAN-Zugriff zu verhindern.

Angenommen, diese serverseitige Option kann nicht deaktiviert werden. Wie kann der lokale LAN-Zugriff zugelassen werden, während eine Verbindung mit einem Cisco VPN-Client besteht?


Früher dachte ich, dass es nur darum ging, Routen hinzuzufügen, die den LAN-Verkehr mit einer höheren Metrik erfassen, zum Beispiel:

  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

Der Versuch, die 10.0.x.x -> 192.168.199.12-Route zu löschen, hat keine Auswirkungen:

>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

Auch wenn es sich möglicherweise immer noch um ein Routingproblem handelt, schlagen Versuche fehl, Routen hinzuzufügen oder zu löschen.

Auf welcher Ebene erledigt der Cisco VPN-Client-Treiber, was im Netzwerkstapel die Fähigkeit eines lokalen Administrators zur Verwaltung seines Computers überschreibt?

Der Cisco VPN-Client kann keine Magie einsetzen. Es ist immer noch Software, die auf meinem Computer läuft. Welchen Mechanismus verwendet es, um das Netzwerk meines Computers zu stören? Was passiert, wenn ein IP/ICMP-Paket im Netzwerk eintrifft? Wo im Netzwerkstapel wird das Paket gefressen?

Siehe auch


Edit: Dinge, die ich noch nicht ausprobiert habe:

>route delete 10.0.*

Update: Da Cisco seinen alten Client zugunsten von AnyConnect (HTTP SSL-basiertes VPN) aufgegeben hat, kann diese ungelöste Frage als Relikt der Geschichte zurückgelassen werden.

In Zukunft können wir versuchen, dasselbe Problem mit ihrem neuen Client zu lösen.

79
Ian Boyd

Das Problem mit Anyconnect ist, dass es zuerst die Routing-Tabelle ändert, sie dann babysittet und repariert, falls Sie sie manuell ändern. Ich habe einen Workaround dafür gefunden. Kompatibel mit Version 3.1.00495, 3.1.05152, 3.1.05170 und wahrscheinlich auch allen anderen Versionen der 3.1-Familie. Funktioniert möglicherweise mit anderen Versionen, sollte zumindest eine ähnliche Idee funktionieren, vorausgesetzt, der Code wird nicht neu geschrieben. Zum Glück für uns hat Cisco den Babysitter "Baby ist wach" in eine gemeinsame Bibliothek gerufen. Die Idee ist also, dass wir die Aktion von vpnagentd über LD_PRELOAD verhindern.

  1. Zuerst erstellen wir eine Datei 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. Dann kompiliere es so:

    gcc -o libhack.so -shared -fPIC hack.c
    
  3. Installieren Sie libhack.so im Cisco-Bibliothekspfad:

    Sudo cp libhack.so  /opt/Cisco/anyconnect/lib/
    
  4. Runter den Agenten:

    /etc/init.d/vpnagentd stop
    
  5. Stellen Sie sicher, dass es wirklich nicht funktioniert

    ps auxw | grep vpnagentd
    

    Wenn nicht, kill -9 nur um sicherzugehen.

  6. Repariere dann /etc/init.d/vpnagentd, indem du LD_PRELOAD=/opt/Cisco/anyconnect/lib/libhack.so hinzufügst, wo der vpnagentd aufgerufen wird, so dass er so aussieht:

    LD_PRELOAD=/opt/Cisco/anyconnect/lib/libhack.so /opt/Cisco/anyconnect/bin/vpnagentd
    
  7. Starten Sie nun den Agenten:

    /etc/init.d/vpnagentd start
    
  8. Repariere iptables, weil AnyConnect mit ihnen herumwirbelt:

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

    Möglicherweise möchten Sie hier etwas Fortgeschritteneres tun, um den Zugriff nur auf bestimmte LAN-Hosts zuzulassen.

  9. Korrigieren Sie nun die Routen nach Ihren Wünschen, zum Beispiel:

    route add -net 192.168.1.0 netmask 255.255.255.0 dev wlan0
    
  10. Überprüfen Sie, ob sie wirklich da sind:

    route -n
    

Eine frühere, einfachere Version dieses Hacks enthielt eine Funktion, die nur "return 0" ergab. - Auf dem Poster stand: "Der einzige Nebeneffekt, den ich bisher beobachtet habe, ist, dass vpnagentd 100% der CPU verwendet, wie von top gemeldet, aber insgesamt nur 3% Benutzer und 20% System, und das System ist perfekt ansprechbar Ich habe es eingeengt, es scheint zwei Auswahlen in einer Schleife zu machen, wenn im Leerlauf schnell von beiden zurückgekehrt wird, aber es liest oder schreibt nie - ich nehme an, der Aufruf, den ich mit LD_PRELOAD ausgeschnitten habe, sollte lauten dazu, aber es ist gut genug für mich bisher. Wenn jemand eine bessere Lösung hat, teilen Sie es bitte. "

Das Problem mit dem trivialen Hack ist, dass ein einzelner CPU-Kern die ganze Zeit zu 100% ausfällt, wodurch die Anzahl der Hardware-CPU-Threads effektiv um eins verringert wird - unabhängig davon, ob Ihre VPN-Verbindung aktiv war oder nicht. Mir ist aufgefallen, dass sich die ausgewählten Elemente, die der Code ausführt, auf einem Netlink-Socket befinden, der vpnagentd-Daten sendet, wenn sich die Routingtabelle ändert. vpnagentd bemerkt immer wieder, dass eine neue Nachricht auf dem Netlink-Socket ist und ruft den routeCallBackHandler auf, um damit umzugehen, aber da der triviale Hack die neue Nachricht nicht löscht, wird sie immer wieder aufgerufen. Der oben angegebene neue Code löscht die Netlink-Daten, sodass die Endlosschleife, die die 100% -CPU verursacht hat, nicht auftritt.

Wenn etwas nicht funktioniert, führen Sie gdb -p $(pidof vpnagentd) aus, sobald Folgendes angehängt ist:

b socket
c
bt

und sehen Sie, in welchem ​​Anruf Sie sich befinden. Dann raten Sie einfach, welchen Sie ausschneiden möchten, fügen Sie ihn zu hack.c hinzu und kompilieren Sie ihn erneut.

53
Sasha Pachev

Dies ist SEHR kompliziert. Wenn Sie jedoch mit VMWare Player oder einem ähnlichen Programm ein minimales VM erstellen und den Cisco AnyConnect VPN-Client in diesem Programm ausführen, können Sie das Routing unter Verwendung des virtuellen VMWare-Netzwerks möglicherweise nach Ihren Wünschen einrichten Adapter, oder verwenden Sie einfach VM, um über das Cisco SSL-VPN und "Drag/Drop" -Dateien auf/von Ihrem Computer auf die erforderlichen Ressourcen zuzugreifen.

11
LawrenceC

Shrew Soft VPN-Software hat den Trick für mich auch getan, als Ian Boyd vorgeschlagen.

Es kann Cisco VPN-Client-Profile importieren. Ich habe Cisco VPN Client Version 5.0.05.0290 verwendet und nach der Installation von Shrew VPN (Version 2.1.7) und dem Importieren des Cisco-Profils konnte ich ohne zusätzliche Konfiguration der Shrew VPN-Verbindung (oder auf das lokale LAN zugreifen, während ich mit dem Unternehmens-VPN verbunden war Software).

6
vstrale

Vielen Dank an Sasha Pachev für den oben genannten netten Hack.

vpnagentd greift auch in den Resolver ein, indem die an /etc/resolv.conf vorgenommenen Änderungen überschrieben werden. Ich habe es gelöst, indem ich irgendwann das Rennen gewonnen habe:

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

Vergessen Sie nicht, beim Trennen der Verbindung chattr -i /etc/resolv.conf einzugeben.

Ich versuche es zu lösen, indem ich den Rückruf abfange, wie bei der oben beschriebenen Routing-Methode, aber ich kann den entsprechenden Rückruf oder die entsprechende Methode noch nicht finden.

Update1/2: Eine strace hat ergeben, dass vpnagentd die API inotify verwendet, um die Änderungen der Resolver-Datei zu überwachen. Von da an ging es bergab. Hier ist der zusätzliche Hack:

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

Das ist ein bisschen übertrieben, da es die all Dateiüberwachung für den Agenten deaktiviert. Scheint aber OK zu funktionieren.

Das unten stehende VPN-Client-Wrapper-Skript integriert alle Funktionen (aktualisiert, um diesen zusätzlichen Hack einzuschließen). chattr wird nicht mehr verwendet/benötigt.

Update 3: Benutzer-/Passworteinstellungen im Skript korrigiert. Es wird jetzt eine vpn.conf-Datei mit dem unten beschriebenen Format (und Root-Berechtigungen) verwendet.

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

Mein Unternehmen verwendet diesen VPN immer noch. Der vpnc-client ändert einfach die iptables-einstellungen auf diese weise:

 # iptables-save 
 # Erstellt von iptables-save v1.4.10 am 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 

Es filtert alle bis auf den VPN-Verkehr.

Holen Sie sich einfach den Filter in eine Datei mit iptables-save, fügen Sie INPUT- und OUTPOUT-Zugriffszeilen hinzu, die Ihren Anforderungen entsprechen, und wenden Sie die Datei mit iptables-restore erneut an.

zum Beispiel, um auf ein lokales Netzwerk unter 192.168.0 zuzugreifen

 # Erstellt von iptables-save v1.4.10 am 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
banjo

Gibt es Neuigkeiten zu diesem Thema?

Auf welcher Ebene erledigt der Cisco VPN-Client-Treiber, was im Netzwerkstapel die Fähigkeit eines lokalen Administrators zur Verwaltung seines Computers überschreibt?

Ich stimme voll und ganz zu und wundere mich über das Gleiche.

Wie auch immer, es ist eine App, für deren Installation Administratorrechte erforderlich sind. Während sie ausgeführt wird, filtert sie möglicherweise sehr gut, was Sie tun ...

Meine Versuche unter Windows schlagen ebenfalls fehl:

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. Hier scheint es keine Metrik unter 20 zu geben.

3
Marki

Ich weiß nicht, ob ich es richtig verstanden habe, aber ich kläre zuerst mein Verständnis:

Sie haben ein lokales LAN (z. B. 10.0.0.0/16) und einen Remote-Cisco-VPN-Server (z. B. 64.0.0.0/16). Sie möchten über den Cisco-VPN-Client eine Verbindung zum VPN-Server herstellen und benötigen dies dennoch In diesem Fall möchten Sie die gesamte 10.0.xx/16 von der VPN-Verbindung trennen. Die folgende Route muss in einem Mac-Client hinzugefügt werden:

/sbin/route add -net 10.0 -interface en1

dabei ist en1 die Schnittstelle, über die Sie mit Ihrem LAN verbunden sind. Ich weiß, dass Sie das Gleiche auch in Windows und Linux hinzufügen können.

3
Yasser Sobhdel

Da ich keine Kommentare hinzufügen kann, werde ich hier posten. Ich arbeite unter Windows.

Die Lösung, die Virtual Machine verwendet und AnyConnect innerhalb von VM ausführt und dann VM als Mittler zwischen Ihrer Arbeitsumgebung und dem Unternehmensnetzwerk verwendet, funktioniert nicht, wenn Ihre "geliebte" IT-Abteilung 0.0 weiterleitet .0.0 über VPN wird somit auch Ihr lokales Netzwerk (einschließlich dieses zwischen Ihrem lokalen PC und VM) über das VPN geroutet (sic!).

Ich habe versucht, die von @Sasha Pachev gepostete Lösung anzuwenden, aber am Ende habe ich die DLL-Datei so gepatcht, dass sie zu Beginn der Funktion den Wert 0 zurückgibt. Nach einigen Auseinandersetzungen mit der dynamischen Bibliothek konnte ich die Routing-Tabellen nach meinen Wünschen anpassen, aber anscheinend reicht das nicht aus!

Obwohl meine Regeln für Split-Tunneling korrekt zu sein scheinen, erhalte ich immer noch General Failure. Sind Sie auf ein ähnliches Problem gestoßen, das Sie lösen konnten?

  • Mein Gateway zum Internet ist 192.168.163.2
  • Mein Gateway zum Firmennetzwerk ist 10.64.202.1 (also das gesamte 10.. . * Subnetz, das ich als "comapny's" behandle)

So sieht meine Routing-Tabelle jetzt aus (nach manuellen Änderungen bei aktiviertem VPN)

 enter image description here

dennoch folgen die Ergebnisse von Ping

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.

Im Folgenden sehen Sie lediglich als Referenz, wie die Routentabelle aussieht, wenn die VPN-Verbindung getrennt ist (unverändert).

 enter image description here

und so sieht die Tabelle aus, wenn eine VPN-Verbindung besteht (unverändert), in diesem Fall, wenn ich versuche, einen Ping-Befehl zu senden. 8.8.8.8 Ich erhalte einfach eine Zeitüberschreitung (da die Firewall des Unternehmens keinen Datenverkehr außerhalb des Intranets zulässt).

 enter image description here

2
Mike

Wenn Sie die Kontrolle über Ihre Routingtabelle behalten möchten, wenn Sie ein Cisco AnyConnect SSL VPN verwenden, lesen Sie OpenConnect . Beide unterstützen das Cisco AnyConnect SSL VPN und versuchen nicht, Routing-Tabelleneinträge zu stören oder zu sichern. @Vadzim spielt darauf in einem Kommentar oben an .

Nachdem ich alles versucht hatte, außer den AnyConnect Secure Mobility Client zu patchen, konnte ich ihn unter Windows erfolgreich durch OpenConnect GUI ersetzen. Dadurch konnte ich die Konnektivität zu lokalen Ressourcen aufrechterhalten (und die Routingtabelle aktualisieren).

Ich verwende OpenConnect unter Windows, aber es unterstützt auch Linux, BSD und MacOS (unter anderen Plattformen) laut Projektseite .

1
Robert Mooney

Versuchen Sie, diese Einträge mit dem Gateway 10.64.202.13 zu entfernen. Überprüfen Sie, ob der Ping 8.8.8.8 funktioniert, und fügen Sie sie nacheinander wieder hinzu. Ermitteln Sie dann, welcher Eintrag den Fehler verursacht.

Wie haben Sie die DLL gepatcht? Ich kann nicht einmal die Routing-Tabelle ändern, da der 0.0.0.0 mit VPN-Gateway immer wieder hinzugefügt wird.

0
Tony