Для подключения к корпоративной сети моего клиента я использую Cisco AnyConnect Secure Mobility Client, и он отлично работает, но, похоже, не позволяет мне использовать раздельное туннелирование (несмотря на то, что сама VPN, согласно вкладке «Статистика» приложения, имеет режим туннелирования (IPv4): раздельное включение, что, по моему мнению, должно означать, что я могу это сделать). (Да, я понимаю, почему раздельное туннелирование может быть опасным, но блокировка VPN мешает моей работе, а ИТ-отдел моего клиента не заинтересован в том, чтобы делать исключения для подрядчика, и, как я уже сказал, конфигурациявидиморазрешить это.)
Пытаясь найти способ заставить работать раздельное туннелирование, я установил OpenConnect, и он подключается просто отлично — он принимает мои учетные данные, я вижу сообщение «баннер» компании в журнале, он работает. Но ни одно из направлений, к которым я могу получить доступ только через VPN, не работает.
Я подозреваю, что проблема в маршрутах. И AnyConnect, и OpenConnect добавляют несколько маршрутов к определенным сетевым пунктам назначения (одним и тем же), но имеют разные значения для Gateway и Interface. Например,
AnyConnect
===========================================================================
Interface List
14...00 05 9a 3c 7a 00 ......Cisco AnyConnect Secure Mobility Client Virtual Miniport Adapter for Windows x64
[...]
===========================================================================
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.151 35
[...]
a.b.c.x 255.255.255.255 On-link a.b.c.d 2
a.b.c.y 255.255.255.255 On-link a.b.c.d 2
a.b.c.z 255.255.255.255 On-link a.b.c.d 2
[...]
192.168.1.1 255.255.255.255 On-link 192.168.1.151 36
[...]
224.0.0.0 240.0.0.0 On-link a.b.c.d 10000
[...]
255.255.255.255 255.255.255.255 On-link a.b.c.d 10000
OpenConnect
Interface List
[...]
63...00 ff 8d 2a 8a 57 ......TAP-Windows Adapter V9
[...]
===========================================================================
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.151 36
[...]
a.b.c.x 255.255.255.255 a.b.c.(d+1) 192.168.1.151 36
a.b.c.y 255.255.255.255 a.b.c.(d+1) 192.168.1.151 36
a.b.c.z 255.255.255.255 a.b.c.(d+1) 192.168.1.151 36
[...]
224.0.0.0 240.0.0.0 On-link a.b.c.d 291
[...]
255.255.255.255 255.255.255.255 On-link a.b.c.d 291
Помимо 0.0.0.0
маршрута, все эти маршруты добавляются при подключении к VPN. Для 0.0.0.0
OpenConnect изменяет метрику для маршрута 0.0.0.0
на 36 (значения, показанные в таблице AnyConnect, также такие же, как при полном отключении). (Для справки, AnyConnect также удаляет несколько маршрутов IPv6, которые OpenConnect оставляет в покое — я не думаю, что это имеет значение?)
Чтобы явно противопоставить дополнения, AnyConnect использует «On-link» для шлюза, в то время как OpenConnect использует IP-адрес, который почти такой же, как тот, который AnyConnect использует для интерфейса. Для интерфейса OpenConnect использует частный IP-адрес. IP-адреса, используемые для интерфейса AnyConnect и шлюза OpenConnect, находятся в диапазоне, которым владеет клиент.
Метрики также различаются: AnyConnect использует 2, что имеет более высокий приоритет, чем мой 0.0.0.0
маршрут (устанавливается на 35 при отключении или подключении через AnyConnect), в то время как OpenConnect использует 36, а также изменяет мой 0.0.0.0
маршрут на использование 36, поэтому приоритет тот же (для справки: все остальные маршруты в моей системе используют метрику выше 36).
AnyConnect также добавляет маршрут для 192.168.1.1
, к 192.168.1.151
, который OpenConnect использует для Интерфейса. Это единственный маршрут, который есть у одного и отсутствует у другого.
Оба также добавляют маршруты для 224.0.0.0
и 255.255.255.255
, но AnyConnect использует метрику 10000 (выше, чем у любого другого маршрута), в то время как OpenConnect использует 291 (выше, чем у любого другого добавления, но ниже, чем у некоторых других существующих маршрутов, которые у меня были до подключения). Интересно, что OpenConnect использует тот же шлюз и интерфейс, что и AnyConnect для этих двух маршрутов, несмотря на то, что для всех остальных маршрутов использует разные значения.
Это на машине Windows 10 Pro x64. Cisco AnyConnect — версия 4.5.03040; OpenConnect GUI — «Версия1.5.3(32 бит) [...] На основе OpenConnect v7.08».
Я не так уж много знаю о маршрутизации или VPN; даже чтобы получить столько информации, пришлось много искать и читать. Я даже не знал термина «раздельное туннелирование» до того, как начал это делать. Большая часть информации там устарела — Windows 10 не предлагает опцию «Использовать шлюз по умолчанию в удаленной сети», которую можно было бы снять, как во многих других ответах здесь и в других местах рекомендуется раздельное туннелирование в AnyConnect. Я не знаю, могу ли я предоставить другие соответствующие подробности, но я, безусловно, буду рад, если что-то еще понадобится. Очевидно, я пытался скрыть IP-адреса моих клиентов, но не думаю, что конкретный адрес должен иметь большое значение здесь (я также не знаю, есть ли какая-либо причина для их маскировки, но это не моя информация, поэтому я не буду ею делиться).
решение1
Основываясь на ответе KRyan, я изменил свой скрипт openconnect (vpnc-script.js в папке openconnect gui!) следующим образом, и это помогло мне в похожей ситуации:
for (var i = 0 ; i < parseInt(env("CISCO_SPLIT_INC")); i++) {
var network = env("CISCO_SPLIT_INC_" + i + "_ADDR");
var netmask = env("CISCO_SPLIT_INC_" + i + "_MASK");
var netmasklen = env("CISCO_SPLIT_INC_" + i + "_MASKLEN");
exec("route add " + network + " mask " + netmask);
}
=>
for (var i = 0 ; i < parseInt(env("CISCO_SPLIT_INC")); i++) {
var network = env("CISCO_SPLIT_INC_" + i + "_ADDR");
var netmask = env("CISCO_SPLIT_INC_" + i + "_MASK");
var netmasklen = env("CISCO_SPLIT_INC_" + i + "_MASKLEN");
exec("route add " + network + " mask " + netmask + " " + internal_gw+" metric 2 if "+env("TUNIDX"));
}
(строка 175)
По моему мнению, ошибка здесь:
// Calculate the first usable address in subnet
var internal_gw_array = new Array(
address_array[0] & netmask_array[0],
address_array[1] & netmask_array[1],
address_array[2] & netmask_array[2],
(address_array[3] & netmask_array[3]) + 1
);
var internal_gw = internal_gw_array.join(".");
При маске сети 255.255.255.255 для моего внутреннего IP, переданного через var netmask_array = env("INTERNAL_IP4_NETMASK").split(".");
, этот трюк со шлюзом (в конечном итоге маршрут идет к интерфейсу, IP-адрес шлюза здесь бесполезен), похоже, не срабатывает.
решение2
Я был прав, что проблема была в маршрутах. Потребовалось много проб и ошибок, чтобы добиться правильного результата, но в конечном итоге ручное обновление маршрутов после подключения сработало.
Странно, но route CHANGE
не сработало; мне пришлось использовать route ADD
, хотя, насколько я могу судить, эти маршруты уже существовали после того, как я подключился. Я использовал тот же пункт назначения, маску и шлюз, а затем METRIC 2 IF 17
(поскольку интерфейс «TAP-Windows adapter V9» использовал 17 — я подозреваю, что он будет меняться с каждым перезапуском? отключение и повторное подключение, похоже, постоянно использует 17 на данный момент, но, как вы можете видеть в вопросе, тогда он использовал 63). После этого в списке route PRINT
для этого пункта назначения было две записи (одна, добавленная OpenConnect, и одна, добавленная мной), и это позволило мне подключиться.
Но что я считаю абсолютно странным, так это то, что мой недавно добавленный маршрут имеет метрику 37 — а не 2, которые я указал в команде route ADD
, и больше, чем 36, которые были у существующей записи. Но как бы там ни было, это работает.
К счастью, наш проект поддерживает hosts
файл (который разработчики могут скопировать в свой собственный hosts
файл, когда начнут работать над ним, и который наши инструменты сборки проверяют), поэтому я смог написать пакетный скрипт для корректировки маршрутов. Для тех, кто еще хочет это сделать, мой пакетный скрипт выглядит так
FOR /F "tokens=1" %%i IN (\path\to\our\development\hosts) DO (
route ADD %%i MASK 255.255.255.255 a.b.c.d METRIC 2 IF 17
)
Формат hosts
файла такой же, как и у системного файла: a.b.c.d URL
. Этот скрипт не поддерживает комментарии (хотя я предполагаю, что он route ADD
просто не будет работать), и я не знаю, будут ли пустые строки проблемой или нет (но, опять же, вероятно, просто не будет работать route ADD
).
Вероятно, мне придется скорректировать его для 17, поскольку я подозреваю, что это не будет константой; когда это произойдет, я посмотрю, как определить, что это такое, и вместо этого буду использовать переменную. (И я также обновлю этот ответ.)
решение3
Не то чтобы вы еще не придумали что-то работающее, но вы, похоже, не понимаете, как используются метрики маршрута.Они действительно являются решающим фактором только в очень специфических обстоятельствах.. Цитирую связанный ответ:
Выбор маршрута на окнах включает в себя:
- Поиск наиболее точных маршрутов к месту назначения
- Выбор наиболее специфичного маршрута с наименьшей метрикой.
И если вы хотите сделать свой сценарий менее хрупким, вы можетепрограммно определить номер интерфейса.