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

Come consentire l'accesso alla LAN locale mentre si è connessi alla VPN Cisco?

Come posso mantenere l'accesso locale alla LAN mentre sono connesso a Cisco VPN?

Quando ci si connette utilizzando Cisco VPN, il server ha la possibilità di indicare al client di impedire l'accesso locale alla LAN.

Supponendo che questa opzione lato server non possa essere disattivata, come si può consentire l'accesso alla LAN locale mentre si è connessi con un client Cisco VPN?


Pensavo che fosse semplicemente una questione di rotte aggiunte che catturano il traffico LAN con una metrica più alta, per esempio:

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

E provare a cancellare la rotta 10.0.x.x -> 192.168.199.12 non ha alcun effetto:

>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

E mentre potrebbe ancora essere semplicemente un problema di routing, i tentativi di aggiungere o cancellare rotte falliscono.

A quale livello il driver del client Cisco VPN fa cosa nello stack di rete che prende il sopravvento sulla capacità dell'amministratore locale di amministrare la propria macchina?

Il client Cisco VPN non può usare la magia. È ancora un software in esecuzione sul mio computer. Quale meccanismo sta usando per interferire con la rete della mia macchina? Cosa succede quando un pacchetto IP/ICMP arriva sulla rete? In quale punto dello stack di rete il pacchetto viene mangiato?

Vedi anche


Edit: Cose che non ho ancora provato:

>route delete 10.0.*
  • *

Aggiornamento: Dato che Cisco ha abbandonato il suo vecchio client, in favore di AnyConnect (VPN HTTP SSL based), questa domanda, irrisolta, può essere lasciata come una reliquia della storia.

Andando avanti, possiamo provare a risolvere lo stesso problema con il loro nuovo client .

Risposte (10)

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

Il problema con Anyconnect è che prima modifica la tabella di routing, poi la fa da babysitter e la sistema se la si modifica manualmente. Ho trovato un workaround per questo. Funziona con la versione 3.1.00495, 3.1.05152, 3.1.05170, e probabilmente qualsiasi altra della famiglia 3.1. Potrebbe funzionare con altre versioni, almeno un'idea simile dovrebbe funzionare assumendo che il codice non venga riscritto. Fortunatamente per noi Cisco ha messo la chiamata “baby is awake” in una libreria condivisa. Quindi l'idea è che impediamo l'azione di vpnagentd tramite LD\PRELOAD.

  1. Prima creiamo un file hack.c:

Nota: Questo codice funziona solo con Linux. Per applicare questa soluzione ad una macchina macOS, vedere la versione adattata per macOS .

  1. Poi compilatelo in questo modo:

  2. Installare libhack.so nel percorso della libreria Cisco:

  3. Porta giù l'agente:

  4. Assicuratevi che sia davvero giù

  5. Poi sistemate /etc/init.d/vpnagentd aggiungendo LD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.so dove viene invocato vpnagentd in modo che appaia così:

  6. Ora avviate l'agente:

  7. Sistemate iptables, perché AnyConnect li incasina:

  8. Ora sistemate le rotte a vostro piacimento, per esempio:

  9. Controllate se ci sono davvero:

Una versione precedente, più semplice di questo hack dava una funzione che faceva solo “return 0;” - quel poster ha notato che “L'unico effetto collaterale che ho osservato finora è che vpnagentd sta usando il 100% della CPU come riportato da top, ma la CPU complessiva è solo il 3% utente e 20% sistema, e il sistema è perfettamente reattivo. Ho fatto uno stracing, sembra che stia facendo due selezioni in un ciclo quando è inattivo tornando rapidamente da entrambe, ma non legge o scrive mai - suppongo che la chiamata che ho tagliato fuori con LD_PRELOAD doveva leggere. Potrebbe esserci un modo più pulito per farlo, ma per ora è abbastanza buono per me. Se qualcuno ha una soluzione migliore, per favore condividetela”.

Il problema con il banale hack è che faceva sì che un singolo core della cpu fosse al 100% per tutto il tempo, riducendo effettivamente il numero di thread della cpu hardware di uno - che la connessione vpn fosse attiva o meno. Ho notato che le selezioni che il codice stava facendo erano su un socket netlink, che invia dati a vpnagentd quando la tabella di routing cambia. vpnagentd continua a notare che c'è un nuovo messaggio sul socket netlink e chiama il routeCallBackHandler per occuparsene, ma poiché l'hack banale non cancella il nuovo messaggio continua ad essere chiamato ancora e ancora. il nuovo codice fornito qui sopra pulisce i dati netlink così il ciclo infinito che causa il 100% di cpu non accade.

Se qualcosa non funziona, fai gdb -p $(pidof vpnagentd), una volta attaccato:

b socket
c
bt

e vedi in quale chiamata ti trovi. Poi indovina quale vuoi tagliare, aggiungilo a hack.c e ricompila.

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

Questo è MOLTO complicato, ma se crei una VM minima usando VMWare Player o simili, ed esegui il client VPN Cisco AnyConnect in quella, potrebbe essere possibile impostare il routing come vuoi usando gli adattatori di rete virtuali VMWare, o semplicemente usare la VM per accedere a qualsiasi risorsa sia richiesta tramite la VPN SSL Cisco e “trascinare/rilasciare” i file da/per la tua macchina reale.

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

(http://www.shrew.net “Free as of March 2013”) Soft VPN software ha fatto il trucco per me, anche, come Ian Boyd ha suggerito.

Può importare profili client Cisco VPN. Ho usato Cisco VPN Client versione 5.0.05.0290, e dopo aver installato Shrew VPN (versione 2.1.7) e importato il profilo Cisco, sono stato in grado di accedere alla LAN locale mentre ero connesso alla VPN aziendale senza alcuna configurazione aggiuntiva della connessione Shrew VPN (o software).

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

Grazie a Sasha Pachev per il simpatico hack di cui sopra.

vpnagentd incasina anche il resolver sovrascrivendo le modifiche fatte a /etc/resolv.conf. L'ho risolto vincendo alla fine la gara contro di esso:

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

Non dimenticare di chattr -i /etc/resolv.conf quando ti disconnetti.

Sto cercando di risolverlo intercettando il callback, come per il metodo delle rotte sopra, ma non riesco ancora a trovare il callback o il metodo corrispondente.

Update1/2: Una strace ha rivelato che vpnagentd sta usando l'API inotify per monitorare le modifiche al file resolver. Da lì in poi è stato in discesa. Ecco l'hack aggiuntivo:

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

Questo è un po’ eccessivo, dato che disabilita tutti i file watching per l'agente. Ma sembra funzionare bene.

Lo script wrapper del client vpn qui sotto integra tutte le funzionalità (aggiornato per includere questo ulteriore hack). chattr non è più usato/necessario.

Aggiornamento 3: Sistemate le impostazioni di username/password nello script. Ora usa un file vpn.conf con il formato descritto di seguito (e permessi di solo 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

La mia azienda usa ancora quella vpn. Il client vpnc cambia semplicemente le impostazioni di iptables in questo modo:

# 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 tutto tranne il traffico vpn.

Semplicemente prendi il filtro in un file con iptables-save, aggiungi le linee di accesso INPUT e OUTPOUT che corrispondono ai tuoi bisogni e riapplica il file con iptables-restore.

per esempio per accedere a una rete locale su 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

Per coloro che cercano di mantenere il controllo della loro tabella di routing quando usano una VPN SSL Cisco AnyConnect, controlla OpenConnect . Supporta sia la VPN SSL Cisco AnyConnect che non tenta di interrompere o ‘proteggere’ le voci della tabella di routing. @Vadzim allude a questo in un commento sopra .

Dopo aver provato di tutto tranne che patchare l'AnyConnect Secure Mobility Client, sono riuscito a sostituirlo con successo su Windows con OpenConnect GUI . Questo mi ha permesso di mantenere la connettività alle risorse locali (e di aggiornare la tabella di routing).

Uso OpenConnect su Windows ma supporta anche Linux, BSD e macOS (tra le altre piattaforme) secondo la pagina del progetto .

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

Qualche notizia su questo?

A quale livello il driver del client Cisco VPN fa cosa nello stack di rete che prende il sopravvento sulla capacità dell'amministratore locale di amministrare la propria macchina?

Sono pienamente d'accordo e mi stavo chiedendo la stessa cosa.

Comunque, è un'applicazione che richiede i privilegi di amministratore per essere installata e mentre gira può benissimo filtrare quello che fai…

Anche i miei tentativi su Windows falliscono:

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. Nessuna metrica sotto il 20 qui sembra.

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

Dato che non posso aggiungere commenti, posterò qui. Sto girando su Windows.

La soluzione di usare la macchina virtuale ed eseguire AnyConnect all'interno della VM e poi usare la VM come mediatore tra il tuo ambiente di lavoro e la rete aziendale non funzionerà se il tuo “amato” dipartimento IT instrada 0.0.0.0 attraverso la VPN, quindi anche la tua rete locale (inclusa questa tra il tuo PC locale e la VM) viene instradata attraverso la VPN(sic!).

Ho provato ad applicare la soluzione postata da @Sasha Pachev ma alla fine ho finito per patchare la .dll in modo che restituisca 0 all'inizio della funzione. Alla fine, dopo qualche lotta con la libreria dinamica, sono stato in grado di modificare le tabelle di routing secondo le mie esigenze, ma a quanto pare non è abbastanza!

Anche se le mie regole sembrano essere corrette per ottenere lo split tunneling, ottengo ancora General Failure.Ti sei imbattuto in un problema simile e sei riuscito a risolverlo?

  • Il mio gateway verso internet è 192.168.163.2
  • Il mio gateway verso la rete aziendale è 10.64.202.1 (quindi tutta la 10... * subnet che tratto come “comapny’s”)

Ecco come appare ora la mia tabella di routing (dopo le modifiche manuali mentre la VPN è attiva)

ancora il risultato del ping sono i seguenti

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.

solo per il riferimento, qui sotto è come appare la tabella delle rotte quando la VPN è disconnessa (inalterata)

e questa è come appare la tabella quando la VPN è connessa (inalterata) in quel caso quando cerco di fare un ping a 8.8.8.8 ottengo semplicemente un timeout (dato che il firewall della compagnia non permette al traffico di andare fuori dalla intranet)

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

Non so se ho capito bene, ma prima chiarisco la mia comprensione:

Avete una LAN locale (per esempio, diciamo 10.0.0.0/16, e un server VPN Cisco remoto (per esempio, 64.0.0.0/16). Si vuole connettersi al server VPN attraverso il client Cisco VPN e tuttavia è necessario avere l'accesso alla LAN. In questo caso si vuole separare l'intero 10.0.x.x/16 dalla connessione VPN). La seguente rotta deve essere aggiunta in un client Mac:

/sbin/route add -net 10.0 -interface en1

dove en1 è l'interfaccia attraverso la quale sei connesso alla tua LAN. So che puoi aggiungere la stessa cosa anche in Windows e Linux.

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

Prova a rimuovere quelle voci con gateway 10.64.202.13 e vedi se ping 8.8.8.8 funziona, poi aggiungile di nuovo una per una e identifica quale sta causando il problema.

Come hai patchato la DLL. Non posso nemmeno modificare la tabella di routing perché continua ad aggiungere lo 0.0.0.0 con il gateway VPN.