2011-05-17 14:23:58 +0000 2011-05-17 14:23:58 +0000
85
85

Как разрешить доступ к локальной сети при подключении к Cisco VPN?

Как поддерживать доступ к локальной сети при подключении к Cisco VPN?

При подключении с помощью Cisco VPN сервер должен иметь возможность инструктировать клиента по предотвращению доступа к локальной сети.

Предположив, что эта опция на стороне сервера не может быть отключена, как можно разрешить доступ к локальной сети при подключении с помощью Cisco VPN клиента?


Раньше я думал, что это просто вопрос добавления маршрутов, которые захватывают трафик локальной сети с более высокой метрикой, например:

И попытки удалить маршрут 10.0.x.x -> 192.168.199.12 не имеют никакого эффекта:

Network 
Destination Netmask Gateway Interface Metric
   10.0.0.0 255.255.0.0 10.0.0.3 10.0.0.3 20 <--Local LAN
   10.0.0.0 255.255.0.0 192.168.199.1 192.168.199.12 1 <--VPN Link

И хотя это все еще может быть просто проблемой маршрутизации, попытки добавить или удалить маршруты обходятся безуспешно.

На каком уровне клиентский драйвер Cisco VPN делает то, что в сетевом стеке, который берет верх над способностью локального администратора администрировать свою машину?

Клиент Cisco VPN не может использовать магию. Это все еще программное обеспечение, работающее на моем компьютере. Какой механизм он использует для вмешательства в сеть моей машины? Что происходит, когда в сеть поступает IP/ICMP пакет? Где в сетевом стеке съедается пакет?

Смотрите также


Правка: Вещи, которые я еще не пробовал:

>route delete 10.0.0.0
>route delete 10.0.0.0 mask 255.255.0.0
>route delete 10.0.0.0 mask 255.255.0.0 192.168.199.1
>route delete 10.0.0.0 mask 255.255.0.0 192.168.199.1 if 192.168.199.12
>route delete 10.0.0.0 mask 255.255.0.0 192.168.199.1 if 0x3

Обновление: Поскольку Cisco отказалась от своего старого клиента в пользу AnyConnect (HTTP SSL-based VPN), этот вопрос, нерешенный, можно оставить как пережиток истории.

В дальнейшем мы можем попытаться решить ту же проблему с их новым клиентом .

Ответы (10)

56
56
56
2013-02-05 00:07:44 +0000

Проблема с Anyconnect заключается в том, что она сначала изменяет таблицу маршрутизации, а затем нянчится с ней и исправляет ее, если вы изменяете ее вручную. Я нашел обходной путь для этого. Работает с версиями 3.1.00495, 3.1.05152, 3.1.05170 и, возможно, с чем-то еще из семейства 3.1. Может работать и с другими версиями, по крайней мере, подобная идея должна сработать, если код не будет переписан. К счастью для нас, Cisco поместила вызов няни “baby is awake” в общую библиотеку. Так что идея в том, что мы предотвращаем действия vpnagentd через LD_PRELOAD.

  1. Сначала мы создаем файл hack.c:

Заметка: Этот код работает только с Linux. Для применения этого решения на машине с MacOS смотрите версия адаптированная для MacOS .

  1. Затем скомпилируйте его вот так:

  2. Установите libhack.so в путь библиотеки Cisco:

  3. Опустите агента:

  4. Убедитесь, что он действительно уменьшился на

  5. Затем исправьте /etc/init.d/vpnagentd, добавив LD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.so в место вызова vpnagentd, чтобы все выглядело так:

  6. Теперь запустите агента:

  7. Исправьте iptables, потому что AnyConnect с ними связывается:

  8. Теперь исправьте маршруты по своему усмотрению, например:

  9. Проверьте, действительно ли они есть:

Предыдущая, более простая версия этого взлома давала функцию, которая только “возвращала 0;” - на этом плакате было отмечено, что “Единственным побочным эффектом, который я наблюдал до сих пор, является то, что vpnagentd использует 100% процессора, как сообщалось на вершине, но общий процессор составляет только 3% пользователя и 20% системы, и система отлично реагирует на изменения”. Я зациклился на этом, кажется, что он делает два выбора в цикле, когда холостой возвращается из обоих быстро, но он никогда не читает и не пишет - я полагаю, что звонок, который я вырезал с LD_PRELOAD должен был прочитать. Может быть, есть более чистый способ сделать это, но пока это достаточно хорошо для меня. Если у кого-то есть лучшее решение, пожалуйста, поделитесь".

Проблема с тривиальным взломом заключается в том, что из-за него ядро одного процессора постоянно на 100%, что эффективно уменьшает количество потоков вашего аппаратного процессора на единицу - независимо от того, было ли ваше соединение vpn активным или нет. Я заметил, что код, который выбирал, был на сетевом сокете, который посылает данные vpnagentd, когда изменяется таблица маршрутизации. vpnagentd продолжает замечать, что на сетевом сокете есть новое сообщение, и вызывает routeCallBackHandler, чтобы разобраться с ним, но так как тривиальный хак не очищает новое сообщение, оно просто продолжает вызываться снова и снова. новый код, предоставленный выше, смывает данные с сетевого сокета, так что бесконечный цикл, который вызвал 100% процессор, не случается.

Если что-то не работает, сделайте gdb -p $(pidof vpnagentd), после вложения:

b socket
c
bt

и посмотрите, в каком вызове вы находитесь. Затем просто угадайте, какой из них вы хотите вырезать, добавьте его в hack.c и перекомпилируйте.

11
11
11
2011-12-24 14:43:04 +0000

Это ОЧЕНЬ извилисто, но если вы создадите минимальную ВМ с помощью VMWare Player или аналогичного приложения и запустите Cisco AnyConnect VPN клиент, то, возможно, вы сможете настроить маршрутизацию так, как вам нужно, используя виртуальные сетевые адаптеры VMWare, или просто использовать ВМ для доступа к любым ресурсам, требующимся через Cisco SSL VPN и “перетаскивать” файлы на/с вашей реальной машины.

7
7
7
2013-03-05 13:17:21 +0000

[ Shrew ]0x3 & Soft VPN программное обеспечение сделало трюк для меня, также, как предложил Иан Бойд.

Оно может импортировать профили клиентов Cisco VPN. Я использовал Cisco VPN Client версии 5.0.05.0290, и после установки Shrew VPN (версия 2.1.7) и импорта профиля Cisco, я смог получить доступ к локальной локальной сети при подключении к корпоративной VPN без дополнительной настройки Shrew VPN соединения (или программного обеспечения).

5
5
5
2015-01-28 18:51:15 +0000

Спасибо Саша Пачев за хороший взлом выше.

vpnagentd также портит резольвер, перезаписывая изменения, внесенные в /etc/resolv.conf. Я решил проблему, в конце концов выиграв гонку против него:

#!/bin/bash

dnsfix() {
    [-f /etc/resolv.conf.vpnbackup] || echo "Not connected?" >&2 || return 0 # do nothing in case of failure
    while ! diff -q /etc/resolv.conf /etc/resolv.conf.vpnbackup #>/dev/null
    do
         cat /etc/resolv.conf.vpnbackup >/etc/resolv.conf
    done
    chattr +i /etc/resolv.conf
    diff -q /etc/resolv.conf /etc/resolv.conf.vpnbackup >/dev/null 
}

while ! dnsfix
do
    echo "Retrying..."
    chattr -i /etc/resolv.conf
done

Не забудьте chattr -i /etc/resolv.conf при отключении.

Я пытаюсь решить это, перехватив обратный вызов, как для метода маршрутов выше, но пока не могу найти соответствующий вызов или метод.

Обновление1/2: strace показал, что vpnagentd использует API inotify для отслеживания изменений файла резольвера. С этого момента он был вниз по склону. Вот дополнительный хак:

int _ZN18CFileSystemWatcher11AddNewWatchESsj(void *string, unsigned int integer)
{
  return 0;
}

Это немного чересчур, да, так как он отключает all файл, наблюдая за агентом. Но, похоже, работает нормально.

Скрипт обертки клиента vpn, приведенный ниже, интегрирует всю функциональность (обновленную для включения этого дополнительного взлома). chattr больше не используется/не требуется.

Обновление 3: Исправлены настройки имени пользователя/пароля в сценарии. Теперь он использует файл vpn.conf в формате, описанном ниже(и с правами root-only).

#!/bin/bash

# Change this as needed
CONF="/etc/vpnc/vpn.conf"
# vpn.conf format
#gateway <IP>
#username <username>
#password <password>
#delete_routes <"route spec"...> eg. "default gw 0.0.0.0 dev cscotun0"
#add_routes <"route spec"...> eg. "-net 192.168.10.0 netmask 255.255.255.0 dev cscotun0" "-host 10.10.10.1 dev cscotun0"

ANYCONNECT="/opt/cisco/anyconnect"

usage() {
    echo "Usage: $0 {connect|disconnect|state|stats|hack}"
    exit 1
}

CMD="$1"
[-z "$CMD"] && usage

ID=`id -u`

VPNC="$ANYCONNECT/bin/vpn"

dnsfix() {
    [-f /etc/resolv.conf.vpnbackup] || echo "Not connected?" >&2 || return 0 # do nothing in case of failure
    while ! diff -q /etc/resolv.conf /etc/resolv.conf.vpnbackup >/dev/null
    do
         cat /etc/resolv.conf.vpnbackup >/etc/resolv.conf
    done
# chattr +i /etc/resolv.conf
    diff -q /etc/resolv.conf /etc/resolv.conf.vpnbackup >/dev/null 
}

case "$CMD" in
    "connect")
        [$ID -ne 0] && echo "Needs root." && exit 1
        HOST=`grep ^gateway $CONF | awk '{print $2}'`
        USER=`grep ^user $CONF | awk '{print $2}'`
        PASS=`grep ^password $CONF | awk '{print $2}'`
        OLDIFS=$IFS
        IFS='"'
        DEL_ROUTES=(`sed -n '/^delete_routes/{s/delete_routes[\t\"]*//;s/\"[\t]*\"/\"/g;p}' $CONF`)
        ADD_ROUTES=(`sed -n '/^add_routes/{s/add_routes[\t\"]*//;s/\"[\t]*\"/\"/g;p}' $CONF`)
        IFS=$OLDIFS

        /usr/bin/expect <<EOF
set vpn_client "$VPNC";
set ip "$HOST";
set user "$USER";
set pass "$PASS";
set timeout 5
spawn \$vpn_client connect \$ip
match_max 100000
expect { 
    timeout {
        puts "timeout error\n"
        spawn killall \$vpn_client
        exit 1
    }
    ">> The VPN client is not connected." { exit 0};
    ">> state: Disconnecting" { exit 0};
    "Connect Anyway?"
}
sleep .1
send -- "y\r"
expect { 
    timeout {
        puts "timeout error\n"
        spawn killall \$vpn_client
        exit 1
    }
    "Username:"
}
sleep .1
send -- "\$user\r"
expect { 
    timeout {
        puts "timeout error\n"
        spawn killall \$vpn_client
        exit 1
    }
    "Password: "
}
send -- "\$pass\r";
expect eof
EOF
        sleep 2
        # iptables
        iptables-save | grep -v DROP | iptables-restore

        # routes
        for ROUTE in "${DEL_ROUTES[@]}"
        do
# echo route del $ROUTE
            route del $ROUTE
        done
        for ROUTE in "${ADD_ROUTES[@]}"
        do
# echo route add $ROUTE
            route add $ROUTE
        done

        # dns
        while ! dnsfix
        do
            echo "Try again..."
# chattr -i /etc/resolv.conf
        done

        echo "done."
        ;;
    "disconnect")
# [$ID -ne 0] && echo "Needs root." && exit 1
        # dns
# chattr -i /etc/resolv.conf

        $VPNC disconnect
        ;;
    "state"|"stats")
        $VPNC $CMD
        ;;
    "hack")
        [$ID -ne 0] && echo "Needs root." && exit 1
        /etc/init.d/vpnagentd stop
        sleep 1
        killall -9 vpnagentd 2>/dev/null
        cat - >/tmp/hack.c <<EOF
#include <sys/socket.h>
#include <linux/netlink.h>

int _ZN27CInterfaceRouteMonitorLinux20routeCallbackHandlerEv()
{
  int fd=50; // max fd to try
  char buf[8192];
  struct sockaddr_nl sa;
  socklen_t len = sizeof(sa);

  while (fd) {
     if (!getsockname(fd, (struct sockaddr *)&sa, &len)) {
        if (sa.nl_family == AF_NETLINK) {
           ssize_t n = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
        }
     }
     fd--;
  }
  return 0;
}

int _ZN18CFileSystemWatcher11AddNewWatchESsj(void *string, unsigned int integer)
{
  return 0;
}
EOF
        gcc -o /tmp/libhack.so -shared -fPIC /tmp/hack.c
        mv /tmp/libhack.so $ANYCONNECT
        sed -i "s+^\([\t]*\)$ANYCONNECT/bin/vpnagentd+LD_PRELOAD=$ANYCONNECT/lib/libhack.so $ANYCONNECT/bin/vpnagentd+" /etc/init.d/vpnagentd
        rm -f /tmp/hack.c
        /etc/init.d/vpnagentd start
        echo "done."
        ;;
    *)
        usage
        ;;
esac
4
4
4
2012-06-17 13:37:24 +0000

Моя компания до сих пор использует vpn. Клиент vpnc просто изменяет настройки iptables следующим образом:

# iptables-save # Generated by iptables-save v1.4.10 on Sun Jun 17 14:12:20 2012 \*filter :INPUT DROP [0:0] :FORWARD ACCEPT [0:0] :OUTPUT DROP [0:0] -A INPUT -s 123.244.255.254/32 -d 192.168.0.14/32 -j ACCEPT -A INPUT -i tun0 -j ACCEPT -A INPUT -i lo0 -j ACCEPT -A INPUT -j DROP -A OUTPUT -s 192.168.0.14/32 -d 123.244.255.254/32 -j ACCEPT -A OUTPUT -o tun0 -j ACCEPT -A OUTPUT -o lo0 -j ACCEPT -A OUTPUT -j DROP COMMIT

Он фильтрует все, кроме vpn трафика.

Просто получите фильтр в файл с iptables-save, добавьте строки доступа INPUT и OUTPOUT, которые соответствуют вашим потребностям, и повторно примените файл с iptables- restore.

, например, для доступа к локальной сети на 192.168.0

# Generated by iptables-save v1.4.10 on Sun Jun 17 14:12:20 2012 \*filter :INPUT DROP [0:0] :FORWARD ACCEPT [0:0] :OUTPUT DROP [0:0] -A INPUT -s 123.244.255.254/32 -d 192.168.0.14/32 -j ACCEPT -A INPUT -s 192.168.0.0/24 -d 192.168.0.14/32 -j ACCEPT #local in -A INPUT -i tun0 -j ACCEPT -A INPUT -i lo0 -j ACCEPT -A INPUT -j DROP -A OUTPUT -s 192.168.0.14/32 -d 123.244.255.254/32 -j ACCEPT -A OUTPUT -s 192.168.0.14/32 -d 192.168.0.0/24 -j ACCEPT #local out -A OUTPUT -o tun0 -j ACCEPT -A OUTPUT -o lo0 -j ACCEPT -A OUTPUT -j DROP COMMIT
```.
4
4
4
2019-02-05 01:45:11 +0000

Для тех, кто хочет сохранить контроль над таблицей маршрутизации при использовании Cisco AnyConnect SSL VPN, ознакомьтесь со ссылкой OpenConnect . Он оба поддерживает Cisco AnyConnect SSL VPN и не пытается нарушить или “обезопасить” записи таблицы маршрутизации. @Vadzim указывает на это в комментарии выше .

После того, как я попробовал все, кроме исправления клиента AnyConnect Secure Mobility Client, я смог успешно заменить его на Windows с помощью OpenConnect GUI . Это позволило мне поддерживать подключение к локальным ресурсам (и обновить таблицу маршрутизации).

я использую OpenConnect на Windows, но он также поддерживает Linux, BSD и macOS (среди прочих платформ) согласно странице проекта .

3
3
3
2011-07-23 19:49:44 +0000

Есть новости?

На каком уровне драйвер клиента Cisco VPN делает то, что в сетевом стеке, который берёт верх над способностью локального администратора администрировать свою машину?

я полностью согласен и задаюсь тем же вопросом.

В любом случае, это приложение, для установки которого требуются привилегии администратора, и во время его работы оно может очень хорошо фильтровать то, что вы делаете…

Мои попытки в Windows тоже заканчиваются неудачей:

route change 0.0.0.0 mask 0.0.0.0 192.168.1.1 metric 1
 OK!

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.230 21 <-- LAN
          0.0.0.0 0.0.0.0 192.168.120.1 192.168.120.3 2 <-- VPN

Haha. Похоже, здесь нет метрики ниже 20.

3
3
3
2014-02-28 10:12:50 +0000

Так как я не могу добавлять комментарии, я напишу здесь. Я работаю на Windows.

Решение, использующее виртуальную машину и запускающее AnyConnect внутри ВМ, а затем использующее ВМ в качестве посредника между вашей рабочей средой и сетью компании, не будет работать, если ваш “любимый” IT-отдел маршрутизирует 0.0.0.0 через VPN, таким образом, даже ваша локальная сеть (включая эту маршрутизацию между вашим локальным ПК и ВМ) маршрутизируется через VPN(sic!). 0x2 и 0x2 и я попытался применить решение, размещенное @Sasha Pachev, но в конце концов я нашел заплатку .dll, чтобы она вернула 0 в начале функции. В конце концов, после некоторой борьбы с динамической библиотекой, я смог модифицировать таблицы маршрутизации в соответствии с моими потребностями, но, видимо, этого недостаточно!

Несмотря на то, что мои правила кажутся правильными для достижения раздельного туннелирования, я все еще получаю General Failure.Вы столкнулись с похожей проблемой, как и смогли ее решить?

  • Мой шлюз в интернет 192.168.163.2
  • Мой шлюз в сеть компании 10.64.202.1 (таким образом, весь 10... * подсеть, которую я считаю “комапнией”)

Так выглядит моя таблица маршрутизации сейчас (после ручных изменений при включенной VPN)

, но результат пингования следующий за

C:\Users\Mike>ping -n 1 10.64.10.11
Reply from 10.64.10.11: bytes=32 time=162ms TTL=127

C:\Users\Mike>ping -n 1 8.8.8.8
PING: transmit failed. General failure.

C:\Users\Mike>ping -n 1 192.168.163.2
General failure.

Просто для справки, ниже показано, как выглядит таблица маршрутизации, когда VPN отключен (без изменений)

, и вот как выглядит таблица, когда VPN подключен (без изменений) в том случае, когда я пытаюсь пинговать 8.8.8.8 я просто получаю таймаут (поскольку брандмауэр компании не разрешает трафику выходить за пределы интрасети)

3
3
3
2011-11-06 11:44:34 +0000

Не знаю, правильно ли я понял, но сначала уточняю свое понимание:

У вас локальная сеть (например, 10.0.0.0/16, и удаленный сервер Cisco VPN (например, 64.0.0.0/16). Вы хотите подключиться к VPN серверу через клиента Cisco VPN, и все же вам нужен доступ к локальной сети. В этом случае вы хотите отделить все 10.0.x.x/16 от VPN соединения). В клиент Mac необходимо добавить следующий маршрут:

/sbin/route add -net 10.0 -interface en1

где en1 - это интерфейс, через который вы подключены к вашей локальной сети. Я знаю, что вы можете добавить то же самое в Windows и Linux.

1
1
1
2014-05-01 03:42:23 +0000

Попробуйте удалить эти записи со шлюзом 10.64.202.13 посмотрите, работает ли ping 8.8.8.8, затем добавьте их обратно по одному и определите, какой из них вызывает проблемы.

Как вы исправили DLL. Я даже не могу изменить таблицу маршрутизации, потому что она продолжает добавлять 0.0.0.0 с VPN-шлюзом обратно.