Come forzare il routing tunnel suddiviso su Mac a una VPN Cisco


40

Qualcuno sa come hackerare la tabella di routing (su un Mac) per sconfiggere la forzatura del routing VPN per ogni cosa su una VPN Cisco? praticamente quello che voglio fare è avere solo gli indirizzi 10.121. * e 10.122. * tramite la VPN e tutto il resto direttamente su Internet.

Risposte:


27

Quanto segue funziona per me. Eseguili dopo esserti connesso alla VPN Cisco. (Sto usando il client Cisco OS X integrato, non il client con marchio Cisco.)

sudo route -nv add -net 10 -interface utun0
sudo route change default 192.168.0.1

Sostituisci 10nel primo comando con la rete che si trova dall'altra parte del tunnel.

Sostituisci 192.168.0.1con il gateway della tua rete locale.

L'ho inserito in uno script bash, in questo modo:

$ cat vpn.sh 
#!/bin/bash

if [[ $EUID -ne 0 ]]; then
    echo "Run this as root"
    exit 1
fi

route -nv add -net 10 -interface utun0
route change default 192.168.0.1

Ho anche trovato una spiegazione su come eseguirlo automaticamente quando ti connetti alla VPN, ma è venerdì tardi e non ho voglia di provarlo :)

Modificare:

Da allora ho lasciato il lavoro dove stavo usando la VPN Cisco, quindi questo è dalla memoria.

Il 10primo comando è la rete che si desidera instradare sulla VPN. 10è una scorciatoia per 10.0.0.0/8. Nel caso di Tuan Anh Tran, sembra che la rete lo sia 192.168.5.0/24.

Per quanto riguarda quale gateway specificare nel secondo comando, dovrebbe essere il gateway locale. Quando si accede a una VPN che impedisce il tunneling diviso, applica tale politica modificando le tabelle di routing in modo che tutti i pacchetti vengano instradati sull'interfaccia virtuale. Quindi vuoi cambiare il percorso predefinito indietro a quello che era prima di accedere alla VPN .

Il modo più semplice per capire il gateway è eseguire netstat -rnprima di accedere alla VPN e guardare l'indirizzo IP a destra della destinazione "predefinita". Ad esempio, ecco come appare sulla mia scatola in questo momento:

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            10.0.1.1           UGSc           29        0     en1
10.0.1/24          link#5             UCS             3        0     en1
10.0.1.1           0:1e:52:xx:xx:xx   UHLWIi         55   520896     en1    481
10.0.1.51          7c:c5:37:xx:xx:xx  UHLWIi          0     1083     en1    350
10.0.1.52          127.0.0.1          UHS             0        0     lo0

Il mio gateway è 10.0.1.1: è a destra della destinazione "predefinita".


1
Puoi spiegarmi un po 'di più per me? il mio ifconfig restituisce utun0: flags = 8051 <UP, POINTOPOINT, RUNNING, MULTICAST> mtu 1280 inet 192.168.5.102 -> 192.168.5.102 netmask 0xffffffff. Inoltre non capisco cosa dovrei sostituire con il numero 10 sopra. Grazie.
Tuan Anh Tran,

@TuanAnhTran: ho aggiornato la mia risposta. Per favore fatemi sapere se questo aiuta.
Mark E. Haase,

Per l'ultima versione, ho /Applications/VPNClient.app installato e non vedo utun0 elencato da ifconfig. Vedo adattatori gif0, stf0 e fw0. Come faccio a determinare qual è l'adattatore giusto? Non vedo alcuna differenza nell'output di ifconfig con e senza vpn collegato (tranne per il valore MTU di en1).
Haridsv,

1
Per coloro che non hanno familiarità con LaunchDaemons, ho scritto una guida nella mia risposta qui descrivendo come chiamare uno script da eseguire ogni volta che ti connetti a VPN . (A proposito, +1 risposta eccellente, ma avevo bisogno di un po 'di più per far funzionare l'essenza).
dr jimbob,

1
Purtroppo questo non funziona sul mio client Cisco AnyConnect.
jeremyjjbrown,

5

Usando le informazioni di mehaase, ho scritto uno script Python che semplifica davvero questo processo sul Mac. Quando lo esegui, lo script salverà le informazioni del firewall, avvierà il client AnyConnect, attenderà l'accesso, quindi correggerà i percorsi e il firewall. Basta eseguire lo script da 'terminal'.

#!/usr/bin/python

# The Cisco AnyConnect VPN Client is often configured on the server to block
# all other Internet traffic. So you can be on the VPN <b>OR</b> you can have
# access to Google, etc.
#
# This script will fix that problem by repairing your routing table and
# firewall after you connect.
#
# The script does require admin (super user) access. If you are prompted for
# a password at the start of the script, just enter your normal Mac login
# password.
#
# The only thing you should need to configure is the vpn_ip_network.
# Mine is 10.x.x.x so I just specify '10' but you could be more specific
# and use something like '172.16'
vpn_ip_network = '10'

import sys
import subprocess


def output_of(cmd):
    lines = subprocess.Popen(cmd if isinstance(cmd, list) else cmd.split(' '), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0]
    try:
        lines = lines.decode('utf-8')
    except Exception:
        pass
    return [line.strip() for line in lines.strip().split('\n')]

sys.stdout.write("Mac Account Login ")
good_firewall_ids = set([line.partition(' ')[0] for line in output_of('sudo ipfw -a list')])
sys.stdout.write('Firewall Saved.\n')

gateway = None
for line in output_of('route get default'):
    name, delim, value = line.partition(':')
    if name == 'gateway':
        gateway = value.strip()
        p = subprocess.Popen(['/Applications/Cisco/Cisco AnyConnect VPN Client.app/Contents/MacOS/Cisco AnyConnect VPN Client'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        was_disconnected = False
        while True:
            line = p.stdout.readline()
            if line == '' or p.poll():
                sys.stdout.write("Never connected!\n")
                break
            try:
                line = line.decode('utf-8')
            except Exception:
                pass
            if 'Disconnected' in line:
                sys.stdout.write('Waiting for you to enter your VPN password in the VPN client...\n')
                was_disconnected = True
            if 'Connected' in line:
                if was_disconnected:
                    subprocess.Popen(['sudo','route','-nv','add','-net',vpn_ip_network,'-interface','utun0'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).wait()
                    subprocess.Popen(['sudo','route','change','default',gateway], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).wait()
                    unfriendly_firewall_ids = list(set([line.partition(' ')[0] for line in output_of('sudo ipfw -a list')])-good_firewall_ids)
                    extra = ''
                    if unfriendly_firewall_ids:
                        subprocess.Popen('sudo ipfw delete'.split(' ') + unfriendly_firewall_ids, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).wait()
                        sys.stdout.write("VPN connection established, routing table repaired and %d unfriendly firewall rules removed!\n" % len(unfriendly_firewall_ids))
                    else:
                        sys.stdout.write("VPN connection established and routing table repaired!\n")
                else:
                    try:
                        subprocess.Popen.kill(p)
                        sys.stdout.write('VPN was already connected. Extra VPN client closed automatically.\n')
                    except Exception:
                        sys.stdout.write('VPN was already connected. Please close the extra VPN client.\n')
                break
        break
else:
    sys.stdout.write("Couldn't get gateway. :-(\n")

4

Lo script Python in questa risposta precedente è stato utile, tuttavia, non si è occupato delle rotte utilizzate da AnyConnect per assumere altre interfacce sul dispositivo (come le interfacce VMware). Inoltre, non è stato in grado di gestire più reti VPN.

Ecco lo script che uso:

#!/bin/bash

HOME_NETWORK=192.168
HOME_GATEWAY=192.168.210.1
WORK_NETWORKS="X.X.X.X/12 10.0.0.0/8 X.X.X.X/16"

# What should the DNS servers be set to?
DNS_SERVERS="10.192.2.45 10.216.2.51 8.8.8.8"

##
## Do not edit below this line if you do not know what you are doing.
##
function valid_ip()
{
    local  ip=$1
    local  stat=1

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
            && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        stat=$?
    fi
    return $stat
}

# Nuke any DENY firewall rules
for RULE in `sudo ipfw list | grep deny | awk '{print $1}' | xargs`; do sudo ipfw delete $RULE; done

# Delete any routes for the home network that Anyconnect might have made
sudo route delete -net ${HOME_NETWORK}
sudo route add -net ${HOME_NETWORK} ${HOME_GATEWAY}

# Get the AnyConnect interface
ANYCONNECT_INTERFACE=`route get 0.0.0.0 | grep interface | awk '{print $2}'`

# Add the work routes
for NETWORK in ${WORK_NETWORKS}; do
    sudo route -nv add -net ${NETWORK} -interface ${ANYCONNECT_INTERFACE}
done

# Set the default gateway
sudo route change default ${HOME_GATEWAY}

# Mass route changes
for NET in `netstat -nr | grep -e ^${HOME_NETWORK} | grep utun1 | awk '{print $1}' | xargs`; do 
    if valid_ip ${NET}; then
        echo "Changing route for network"
        sudo route change ${NET} ${HOME_GATEWAY}
    else
        echo "Changing route for host"
        sudo route change -net ${NET} ${HOME_GATEWAY}
    fi      
done

# Set the nameservers
sudo scutil << EOF
open
d.init
d.add ServerAddresses * ${DNS_SERVERS}
set State:/Network/Service/com.cisco.anyconnect/DNS
quit
EOF

Funziona con Cisco Anyconnect 3.1.0? Non credo che lo faccia ... Hai uno script aggiornato per 3.1.0? Grazie!
costa,

2

Molto probabilmente l'amministratore dovrebbe voler configurare connessioni VPN per utilizzare il routing locale per le subnet 10.121. * E 10.122. * E lasciare che il remoto (il computer di casa) instradi tutte le altre richieste. (consente loro di risparmiare larghezza di banda e responsabilità)

Stai utilizzando il "client VPN" di Cisco? OS OS X?

se si utilizza la VPN di OS X (impostata tramite il riquadro delle preferenze di rete), si dovrebbe essere in grado di fare clic su "Avanzate" e selezionare la scheda "VPN su richiesta". quindi fornire le sottoreti necessarie per l'utilizzo della VPN.


4
Il client vpn di OS X ha un'opzione "Cisco" separata (separata da PPTP e L2TP) che non ha le opzioni "VPN on Demand".
Mark E. Haase,

2

Volevo un'app nativa che potessi eseguire all'accesso (e continuare a correre / nascosta) per abilitare il routing Split Tunnel, simile a una funzione di Locamatic . Forse a un certo punto forcherò Locamatic e ci giocherò. Potrei anche caricare questo AppleScript su Github. Non volevo scherzare con un demone come suggerisce questa risposta.

Questo script presuppone che VPN abbia un VPN (Cisco IPSec)nome predefinito e che il percorso VPN sia 10.10.10.1/22> 10.10.20.10. Questi dovranno essere cambiati / percorsi aggiuntivi aggiunti. Esegui terminale> netstat -rnquando la VPN è connessa (prima di abilitare questo script) per vedere i percorsi aggiunti dalla VPN.

Questo script genera anche notifiche in stile ringhio nel Centro notifiche :)

inserisci qui la descrizione dell'immagine

Ho riscontrato alcuni problemi con la risposta di Mark E. Haase mentre la mia VPN Cisco modifica il gateway esistente da una a una route (specifica dell'interfaccia en0) e aggiunge il gateway VPN come route, richiedendo l'eliminazione di due gateway predefiniti e l'aggiunta di nuovo il gateway predefinito originaleUCScUGScIUCSUGSc

Grazie al cielo per StackExchange / google, questo è il mio primo AppleScript e non sarei stato in grado di metterlo insieme senza qualche ora di ricerca su Google.

Suggerimenti / correzioni / ottimizzazioni sono benvenuti!

AppleScript ( GitHubGist ):

global done
set done to 0

on idle
    set status to do shell script "scutil --nc status "VPN (Cisco IPSec)" | sed -n 1p"
    # do shell script "scutil --nc start "VPN (Cisco IPSec)"
    if status is "Connected" then
        if done is not 1 then
            display notification "VPN Connected, splitting tunnel"
            set gateway to do shell script "( netstat -rn | awk '/default/ {if ( index($6, \"en\") > 0 ){print $2} }' ) # gets non-VPN default gateway"
            do shell script "sudo route delete default" # deletes VPN-assigned global (UCS) default gateway
            do shell script "sudo route delete default -ifscope en0" # deletes en0 interface-specific (UGScI) LOCAL non-vpn gateway that prevents it being re-added as global default gateway
            do shell script "sudo route add default " & gateway # re-adds LOCAL non-vpn gateway (from get command above) as global default gateway
            do shell script "sudo route add 10.10.10.1/22 10.10.20.10" # adds VPN route
            display notification "VPN tunnel has been split"
            set done to 1
        end if
    else
        if done is not 2 then
            display notification "VPN Disconnected"
            set done to 2

        end if
    end if
    return 5
end idle

salva come app:

Impostazioni di salvataggio dell'app Split Tunnel

fare clic con il tasto destro> mostra il contenuto del pacchetto, aggiungere quanto segue a info.plist (ciò nasconde l'icona dell'app dal dock, richiedendo l'uso di Activity Monitor o terminale> pkill -f 'Split Tunnel'per uscire dall'app, omettere se si desidera un'icona dock:

<key>LSBackgroundOnly</key>
<string>1</string>

crea un nuovo routeNOPASSWDfile di una riga (senza estensione) usando ESATTAMENTE il seguente codice (questo può impedire l'accesso a sudo se fatto in modo errato, google visudoper maggiori informazioni - questo consente ai comandi sudo in AppleScript di eseguire SENZA una richiesta di password, ometti se vuoi una richiesta di password quando è necessario modificare la tabella di routing):

%admin ALL = (ALL) NOPASSWD: /sbin/route

copia questo file in /etc/sudoers.d

eseguire i seguenti comandi nel terminale (il secondo comando richiederà la password - ciò consente ai sudo routecomandi in AppleScript di eseguire SENZA richiesta di password, omettere se si desidera una richiesta di password quando lo script modifica la tabella di routing)

chmod 440 /private/etc/sudoers.d/routeNOPASSWD
sudo chown root /private/etc/sudoers.d/routeNOPASSWD

infine aggiungi l'app a Preferenze di sistema> Utenti e gruppi> elementi di accesso

Voce di accesso Split Tunnel


1

Dovresti essere in grado di chiedere all'amministratore del router a cui ti stai connettendo di impostare un "gruppo" separato che esegue il tunneling diviso e ti fornisce un file PCF che contiene il nome del gruppo e la password del gruppo per quel gruppo.


2
non succederà :) Sono paranoici

1

Ho avuto lo stesso problema e ho funzionato grazie a @mehaase

Dopo aver creato la ~/vpn.shrisposta di @mehaase, puoi inserirlo in uno script di automazione dell'applicazione eseguibile usando questi passaggi:

  1. Utilizzando Automator creare una nuova applicazione
  2. Aggiungi "Esegui un AppleScript" in Libreria> Utilità
  3. Accedere: do shell script "sudo ~/vpn.sh" with administrator privileges
  4. Salvare

Potrebbe anche essere necessario eseguire chmod 700 ~/vpn.shdal Terminale per dare allo script i privilegi di esecuzione.

Dopo esserti connesso alla VPN puoi semplicemente eseguire questo script dell'applicazione. Immettere la password dell'amministratore e fare clic su OK - Fine. :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.