Как заставить разделенную туннельную маршрутизацию на Mac Cisco VPN


39

Кто-нибудь знает, как взломать таблицу маршрутизации (на Mac), чтобы победить форсирование VPN-маршрутизации для каждой вещи через VPN cisco? почти все, что я хочу сделать, это иметь только адреса 10.121. * и 10.122. * через VPN и все остальное прямо в Интернет.

Ответы:


27

Следующее работает для меня. Запустите их после подключения к Cisco VPN. (Я использую встроенный клиент 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 с вашим локальным сетевым шлюзом.

Я поместил это в скрипт bash, вот так:

$ 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, но уже поздно в пятницу, и я не испытываю желания попробовать это :)

Редактировать:

С тех пор я оставил работу, где я использовал Cisco VPN, так что это из памяти.

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 & lt; UP, POINTOPOINT, RUNNING, MULTICAST & gt; mtu 1280 inet 192.168.5.102 - & gt; 192.168.5.102 маска сети 0xffffffff. Также я не понимаю, что я должен заменить на номер 10 выше. Спасибо.
Tuan Anh Tran

@TuanAnhTran: я обновил свой ответ. Пожалуйста, дайте мне знать, если это поможет.
Mark E. Haase

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

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

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? Спасибо!
costa

2

Скорее всего, ваш администратор должен настроить VPN-подключения для использования локальной маршрутизации для подсетей 10.121. * И 10.122. * И позволить удаленному (вашей домашней машине) маршрутизировать все остальные запросы. (это экономит их пропускную способность и ответственность)

Используете ли вы Cisco VPN-клиент? ОС OS X?

если вы используете VPN в OS X (настраивается через панель настроек сети), вы можете нажать «Дополнительно» и выбрать вкладку «VPN по требованию». затем укажите необходимые подсети для использования VPN.


4
Клиент OS X vpn имеет отдельную опцию «Cisco» (отдельно от PPTP и L2TP), которая не имеет опций «VPN по требованию».
Mark E. Haase

1

Вы должны иметь возможность попросить администратора маршрутизатора, к которому вы подключаетесь, создать отдельную «группу», которая выполняет раздельное туннелирование, и предоставить вам файл PCF, который содержит имя группы и пароль группы для этой группы.


2
это не произойдет :) Они параноики

1

У меня была такая же проблема, и я получил эту работу благодаря @mehaase

После создания ~/vpn.sh в ответ на вопрос @mehaase вы можете поместить это в сценарий автоматизированного запуска приложения, выполнив следующие действия:

  1. С помощью Automator создайте новое приложение
  2. Добавьте «Запустить AppleScript» в разделе «Библиотека» & gt; коммунальные услуги
  3. Войти: do shell script "sudo ~/vpn.sh" with administrator privileges
  4. Сохранить

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

После подключившись к VPN, вы можете просто запустить этот скрипт приложения. Введите пароль администратора и нажмите ОК - Готово. :)


1

Я хотел собственное «приложение», которое я мог бы запустить при входе в систему (и продолжать работать / скрыто), чтобы включить маршрутизацию Split Tunnel, аналогично функции Locamatic , Возможно, в какой-то момент я раскошелюсь на Locamatic и поиграюсь с ним. Я также могу загрузить этот AppleScript в Github. Я не хотел связываться с демоном, как этот ответ подсказывает.

Этот сценарий предполагает, что VPN имеет значение по умолчанию VPN (Cisco IPSec) имя и VPN-маршрут 10.10.10.1/22 & GT; 10.10.20.10, Их нужно будет изменить / добавить дополнительные маршруты. Запустите терминал & gt; netstat -rn когда VPN подключен (до включения этого скрипта), чтобы увидеть VPN-добавленные маршруты.

Этот скрипт также генерирует уведомления в стиле рычания в Центре уведомлений :)

enter image description here

Я столкнулся с некоторыми проблемами с Марк Э. Хаас «s ответ как мой Cisco VPN изменяет существующий шлюз от UCSc к UGScI (специфичный для интерфейса en0) и добавляет шлюз VPN как UCS маршрут, требующий удаления двух шлюзов по умолчанию и добавления обратно оригинал UGSc шлюз по умолчанию

Слава Богу, StackExchange / google, это мой первый AppleScript, и я бы не смог собрать его без нескольких часов поиска в Google.

Предложения / исправления / оптимизации приветствуются!

AppleScript ( GitHub Gist ):

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 app save settings

щелкните правой кнопкой мыши & gt; показать содержимое пакета, добавьте в info.plist следующее (это скрывает значок приложения от дока, что требует использования Activity Monitor или терминала & gt; 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

наконец, добавьте приложение в системные настройки & gt; Пользователи и группы & gt; элементы входа

Split Tunnel Login Item

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.