OpenConnect не может достичь пунктов назначения, поддерживающих только VPN

OpenConnect не может достичь пунктов назначения, поддерживающих только VPN

Для подключения к корпоративной сети моего клиента я использую 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.0OpenConnect изменяет метрику для маршрута 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

Не то чтобы вы еще не придумали что-то работающее, но вы, похоже, не понимаете, как используются метрики маршрута.Они действительно являются решающим фактором только в очень специфических обстоятельствах.. Цитирую связанный ответ:

Выбор маршрута на окнах включает в себя:

  • Поиск наиболее точных маршрутов к месту назначения
  • Выбор наиболее специфичного маршрута с наименьшей метрикой.

И если вы хотите сделать свой сценарий менее хрупким, вы можетепрограммно определить номер интерфейса.

Связанный контент