Як змусити маршрутизацію розділеного тунелю на Mac до VPN Cisco


40

Хтось знає, як зламати таблицю маршрутизації (на mac), щоб перемогти форсування маршрутизації VPN за кожну річ через VPN cisco? Я хочу зробити лише 10.121. * та 10.122. * адрес через VPN та все інше безпосередньо в Інтернеті.

Відповіді:


27

Наступні роботи для мене. Запустіть їх після підключення до VPN Cisco. (Я використовую вбудований клієнт Cisco OS X, а не фірмовий клієнт Cisco.)

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

Замініть 10в першій команді мережею, що знаходиться з іншого боку тунелю.

Замініть 192.168.0.1шлюз вашої локальної мережі.

Я помістив його в баш-скрипт, наприклад:

$ 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

Я також знайшов пояснення, як запустити це автоматично, коли ви підключите VPN, але пізно в п’ятницю, і я не відчуваю, як це намагатись :)

Редагувати:

З тих пір я покинув роботу, де я використовував VPN Cisco, так що це з пам'яті.

10У першій команді є мережею , що ви хочете , щоб маршрут через VPN. 10коротка рука для 10.0.0.0/8. У випадку Туан Ан Трана, схоже, мережа є 192.168.5.0/24.

Що стосується того, який шлюз потрібно вказати у другій команді, він повинен бути вашим локальним шлюзом. Коли ви входите в VPN, що перешкоджає розділенному тунелюванню, воно застосовує цю політику, змінюючи таблиці маршрутизації, щоб усі пакети були маршрутизовані у віртуальному інтерфейсі. Таким чином, ви хочете змінити маршрут за замовчуванням назад на те, що було раніше, ніж потрапити на VPN .

Найпростіший спосіб визначити шлюз - це запуститись netstat -rnперед входом у VPN та переглянути IP-адресу праворуч від пункту призначення за замовчуванням. Наприклад, ось як це виглядає на моїй скриньці зараз:

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

Мій шлюз 10.0.1.1- справа від пункту призначення за замовчуванням.


1
Чи можете ви пояснити мені трохи більше? мій ifconfig повертає utun0: flags = 8051 <UP, POINTOPOINT, RUNNING, MULTICAST> mtu 1280 inet 192.168.5.102 -> 192.168.5.102 netmask 0xffffffff. Також я не розумію, що мені слід замінити цифрою 10 вище. Дякую.
Tuan Anh Tran

@TuanAnhTran: Я оновив свою відповідь. Будь ласка, дайте мені знати, якщо це допомагає.
Марк Е. Хааз

Для останньої версії у мене встановлено /Applications/VPNClient.app, і я не бачу utun0, переліченого ifconfig. Я бачу адаптери gif0, stf0 та fw0. Як визначити, який правильний адаптер? Я не бачу різниці у виведенні ifconfig з підключеним vpn і без нього (за винятком значення MTU en1).
haridsv

1
Для тих, хто не знайомий з LaunchDaemons, я написав посібник у своїй відповіді, в якій розповів, як викликати сценарій для запуску кожного разу при підключенні до VPN . (До речі, +1 відмінна відповідь, але мені потрібно було трохи більше, щоб суть працювала).
д-р Джимбоб

1
На жаль, це не працює на моєму клієнті Cisco AnyConnect.
jeremyjjbrown

5

Використовуючи інформацію з mehaase, я написав сценарій Python, який дійсно спрощує цей процес на Mac. Запустивши його, сценарій збереже інформацію про брандмауер, запустить клієнт AnyConnect, зачекає входу, а потім виправить маршрути та брандмауер. Просто запустіть скрипт із "терміналу".

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

Скрипт Python у цій попередній відповіді був корисним, однак він не подбав про маршрути, якими користувався AnyConnect для перенесення інших інтерфейсів на пристрої (таких як інтерфейси VMware). Він також не міг обробляти декілька мереж VPN.

Ось сценарій, який я використовую:

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

Чи працює це з cisco anyconnect 3.1.0? Я не думаю, що це робить ... У вас є оновлений сценарій для 3.1.0? Дякую!
Коста

2

Більш ніж ймовірно, ваш адміністратор повинен захотіти налаштувати VPN-з'єднання для використання локальної маршрутизації для підмереж 10.121. * І 10.122. * І дозволити віддаленому (домашній машині) маршрутизувати всі інші запити. (це економить їх пропускну здатність та відповідальність)

Використовуєте ви "VPN-клієнт" Cisco? OS OS X?

якщо ви використовуєте VPN ОС X (встановлений через мережеву панель налаштувань), ви повинні мати можливість натиснути «розширений» та вибрати вкладку «VPN на вимогу». потім надайте необхідні підмережі для використання VPN.


4
У клієнта OS X vpn є окрема опція "Cisco" (окремо від PPTP та L2TP), що не має параметрів "VPN на вимогу".
Марк Е. Хааз

2

Мені хотілося, щоб вбудована програма, яку я могла запускати під час входу (і продовжувати працювати / приховувати), дозволила маршрутизувати розділений тунель подібно до функції Locamatic . Можливо, я в якийсь момент розпалю Локаматик і пограю з ним. Я також можу завантажити цей AppleScript в Github. Я не хотів возитися з демоном, як підказує ця відповідь.

Цей сценарій передбачає, що VPN має VPN (Cisco IPSec)ім'я за замовчуванням, а VPN маршрут 10.10.10.1/22> 10.10.20.10. Їх потрібно буде змінити / додати додаткові маршрути. Запустіть термінал>, netstat -rnколи VPN підключено (до ввімкнення цього сценарію), щоб побачити маршрути, додані VPN.

Цей сценарій також генерує сповіщення у стилі гарла в Центрі сповіщень :)

введіть тут опис зображення

Я зіткнувся з деякими проблемами з Mark E. Гаазе «s відповідь , як мій Cisco VPN модифікує існуючий шлюз від а UCScдо UGScI(інтерфейс конкретного en0) маршруту і додає VPN шлюз як UCSмаршрут, вимагаючи видалення двох шлюзів по замовчуванням і додати назад оригінальний UGScшлюз за замовчуванням

Слава богу за StackExchange / google, це мій перший AppleScript, і я б не зміг скласти його без кількох годин гуглінгу.

Пропозиції / виправлення / оптимізації вітаються!

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

зберегти як додаток:

Налаштування збереження додатка Split Tunnel

клацніть правою кнопкою миші> показати вміст пакета, додайте наступне до info.plist (це приховує піктограму програми з док-станції, що вимагає використання Монітора активності або терміналу>, pkill -f 'Split Tunnel'щоб вийти з програми, опустіть, якщо ви хочете піктограму дока:

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

створити новий однорядковий routeNOPASSWDфайл (без розширення), використовуючи наступний код ТОЧНО (це може запобігти доступу до sudo, якщо це зроблено неправильно, google visudoдля отримання додаткової інформації - це дозволяє командам sudo в AppleScript запускати БЕЗ підказки пароля, опускайте, якщо хочете запрошення пароля, коли таблицю маршрутизації потрібно змінити):

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

скопіюйте цей файл у /etc/sudoers.d

запустіть наступні команди в терміналі (друга команда підкаже про введення пароля - це дозволяє sudo routeкомандам в AppleScript запускати БЕЗ запитів на отримання пароля, опустіть, якщо потрібне запит пароля, коли сценарій змінює таблицю маршрутизації)

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

нарешті додайте додаток до системних налаштувань> Користувачі та групи> елементи входу

Елемент для входу в розділений тунель


1

Ви повинні мати можливість попросити адміністратора маршрутизатора, до якого ви підключаєтесь, щоб створити окрему "групу", яка розділяє тунелювання та надасть вам файл PCF, який містить ім'я групи та пароль групи для цієї групи.


2
це не відбудеться :) Вони параноїдальні

1

У мене був такий самий випуск, і я почав працювати це завдяки @mehaase

Створивши ~/vpn.shвідповідь на @mehaase, ви можете помістити це в сценарій автоматизації застосунку, який можна запустити, виконавши наступні дії:

  1. За допомогою Automator створіть нову програму
  2. Додати "Запустити AppleScript" у розділі Бібліотека> Утиліти
  3. Введіть: do shell script "sudo ~/vpn.sh" with administrator privileges
  4. Зберегти

Вам також може знадобитися запустити chmod 700 ~/vpn.shз терміналу, щоб надати сценарію виконання привілеїв.

Після підключення до VPN ви можете просто запустити цей скрипт програми. Введіть пароль адміністратора і натисніть ОК - Готово. :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.