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

Cisco VPN接続中にローカルLANアクセスを許可するには?

Cisco VPN接続中にローカル LAN アクセスを維持するにはどうすればいいですか?

Cisco VPNを使用して接続する際に、サーバー側でクライアントにローカルLANアクセスを禁止するように指示する機能があります。

サーバー側のオプションをオフにすることはできないと仮定して、Cisco VPN クライアントで接続中にローカル LAN アクセスを許可するにはどうすればいいですか?

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

10.0.x.x -> 192.168.199.12 のルートを削除しようとしても何の効果もありません。

>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 VPN クライアントドライバはどのレベルで、ローカル管理者がマシンを管理する能力を上書きするネットワークスタックの何をしているのでしょうか?

Cisco VPN クライアントは魔法を使っているはずがありません。まだ私のコンピュータ上で動作しているソフトウェアです。どのようなメカニズムで私のマシンのネットワークを妨害しているのでしょうか?IP/ICMPパケットがネットワーク上に到着すると何が起こりますか?パケットはネットワークスタックのどこで食われているのでしょうか?

参照


編集:まだ試していないこと。

>route delete 10.0.*

更新: Ciscoは古いクライアントを放棄し、AnyConnect(HTTP SSLベースの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はベビーシッターの “赤ちゃんが起きている "コールを共有ライブラリに入れています。そのため、LD_PRELOADを経由してvpnagentdのアクションを阻止するというアイデアです。

1.まずファイルhack.cを作成します。

*注意:このコードはLinuxでのみ動作します。この解決策をmacOSマシンに適用するには、 macOS適応版 . *

  1. 次に、次のようにコンパイルします。

  2. libhack.soをCiscoライブラリのパスにインストールします。

  3. エージェントを停止させる:

  4. 本当にダウンしていることを確認する。次に、/etc/init.d/vpnagentd を修正し、vpnagentd が呼び出される場所に LD_PRELOAD=/opt/cisco/anyconnect/lib/libhack.soを追加して、以下のようにします。

  5. これでエージェントを起動します:

    1. iptables を修正します。
    1. ここで、ルートを好きなように修正します。本当に存在するかどうかを確認してください。

このハックの以前のシンプルなバージョンでは、"return 0; "のみを行う関数を提供していました - その投稿者は、"私がこれまでに観察した唯一の副作用は、トップが報告したようにvpnagentdが100%のCPUを使用しているということですが、全体的なCPUは3%のユーザと20%のシステムのみで、システムは完全に反応しています。辿ってみると、アイドル時にループで2つの選択をしているようで、両方から素早く戻ってくるのだが、読み書きはしない。もっとすっきりした方法があるかもしれないが、今のところこれで十分だ。誰か良い解決策があれば、教えてください。”

この些細なハックの問題は、1つのCPUコアを常に100%にしてしまい、効果的にハードウェアのCPUスレッド数を1つ減らしてしまうことです。vpnagentd はネットリンクソケット上に新しいメッセージがあることに気付き、それに対処するために routeCallBackHandler を呼び出していましたが、些細なハックでは新しいメッセージがクリアされないので、何度も何度も呼び出され続けていました。

何かがうまくいかない場合は、一度アタッチした後、gdb -p $(pidof vpnagentd)を実行してください。

b socket
c
bt

とし、どのコールに入っているかを確認します。あとはどれを切り取りたいかを推測して、hack.cに追加して再コンパイルすればいい。

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

これは非常に複雑ですが、VMWare Player などを使用して最小限の VM を作成し、その中で Cisco AnyConnect VPN クライアントを実行すれば、VMWare の仮想ネットワークアダプタを使用して好きなようにルーティングを設定することができるかもしれません。

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

Shrew](http://www.shrew.net “Free as of March 2013”) Soft VPNソフトウェアは、Ian Boydが提案したように、私のためにトリックを実行してくれました。

Cisco VPNクライアントのプロファイルをインポートすることができます。私はCisco VPNクライアントのバージョン5.0.05.0290を使用していますが、Shrew VPN(バージョン2.1.7)をインストールしてCiscoプロファイルをインポートしたところ、Shrew VPN接続(またはソフトウェア)の追加設定なしで、企業VPNに接続したままローカルLANにアクセスすることができました。

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

Sasha Pachev ](https://superuser.com/users/195546/sasha-pachev)さん、上の素敵なハックをありがとうございます。

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を忘れずに。

上記のroutesメソッドのようにコールバックを傍受することで解決しようとしているのですが、対応するコールバックやメソッドがまだ見つかりません。

Update1/2: straceで、vpnagentdがレゾルバファイルの変更を監視するためにinotifyのAPIを使っていることが判明。そこから先は下り坂でした。追加のハックはこちら。

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

これは少しやり過ぎです。しかし、問題なく動作しているようです。

以下の vpn クライアントラッパースクリプトはすべての機能を統合しています(この追加のハックを含めるために更新されました)。chattr はもう使わない/必要ない。

アップデート3: スクリプト内のユーザ名/パスワード設定を修正しました。vpn.confファイルを以下のフォーマットで使用するようになりました(rootのみのパーミッションもあります)。

#!/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 をチェックしてください。OpenConnectはCisco AnyConnect SSL VPNをサポートしており、ルーティングテーブルのエントリを混乱させたり「安全」にしたりすることはありません。

を試してみましたが、Cisco AnyConnect SSL VPN をサポートしているので、Cisco AnyConnect SSL VPN をサポートしています。

AnyConnect Secure Mobility Clientのパッチ適用以外のすべてを試した結果、Windows上のAnyConnect Secure Mobility Clientを OpenConnect GUI に置き換えることに成功しました。これにより、ローカルリソースへの接続性を維持することができました(ルーティングテーブルも更新しました)。

私はWindowsでOpenConnectを使用していますが、Linux、BSD、macOS(他のプラットフォームの中では)もサポートしています プロジェクトページによると

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

これについて何かニュースはありますか?

Cisco VPNクライアントドライバは、どのレベルで、ローカル管理者がマシンを管理する能力を上書きするネットワークスタックの何をしているのでしょうか?

私も全く同感で、同じことを考えていました。

とにかく、インストールには管理者権限が必要なアプリで、実行中はあなたの行動をフィルタリングしているかもしれません…。

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

あはは。ここでは20以下の指標はないようです。

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

コメントを追加できないので、こちらに投稿します。私はWindowsで実行しています。

Virtual Machineを使用して、VM内でAnyConnectを実行し、VMを作業環境と会社のネットワークの仲介役として使用する方法は、IT部門が0.0.0.0.0をVPN経由でルーティングしているため、ローカルネットワーク(ローカルPCとVMの間を含む)までもがVPN経由でルーティングされている場合には機能しません。

私は @Sasha Pachev さんが投稿してくれた解決策を適用しようとしましたが、結局 .dll にパッチを当てて関数の先頭に 0 を返すようにしてしまいました。結局、ダイナミックライブラリと格闘した結果、必要に応じてルーティングテーブルを修正することができましたが、どうやらそれだけでは十分ではないようです。

スプリットトンネリングを実現するためのルールが正しいように見えるにもかかわらず、General Failureが発生します。 *

これが今の私のルーティングテーブルの様子です(VPNオン時に手動で修正した後)

まだpingの結果は以下のようになっています

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 を pingしようとしたときにタイムアウトが発生しました(会社のファイアウォールがトラフィックがイントラネットの外に出ることを許可していないため)

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

私が正しく理解しているかどうかわかりませんが、まず私の理解を明確にします。

ローカル LAN (例えば、10.0.0.0.0/16) とリモートの Cisco VPN サーバー (例えば、64.0.0.0.0/16) があるとします。Cisco VPN クライアントを使って VPN サーバーに接続したいが、LAN アクセスが必要だとします。この場合、10.0.0.x.x/16全体をVPN接続から分離したい)。Macクライアントでは次のようなルートを追加する必要があります:

/sbin/route add -net 10.0 -interface en1

ここでen1はLANに接続しているインターフェイスです。WindowsやLinuxでも同じように追加できると思います。

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

ping 10.64.202.13が動作するかどうか、ゲートウェイ 8.8.8.8でこれらのエントリを削除してみて、問題の原因となっているエントリを1つずつ追加してください。

DLLにはどのようにパッチを当てましたか?VPNゲートウェイを使って0.0.0.0を追加し続けているので、ルーティングテーブルを修正することもできません。