Cisco VPNに接続している間どのようにローカルLANアクセスを維持できますか。
Cisco VPNを使用して接続するとき、サーバはクライアントにローカルLANアクセスを防ぐように指示する必要があります。
このサーバ側のオプションを無効にできないと仮定して、Cisco VPNクライアントとの接続中にローカルLANアクセスを許可するにはどうすればよいですか。
私はこれが単により高いメトリックで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)を支持して古いクライアントを放棄したため、この問題は未解決で歴史の遺物として残すことができます。
Anyconnectの問題点は、ルーティングテーブルを最初に変更し、次にそれをベビーシットし、手動で変更した場合はそれを修正することです。これに対する回避策を見つけました。バージョン3.1.00495、3.1.05152、3.1.05170、およびおそらく3.1ファミリーの他のもので動作します。他のバージョンでも動作する可能性がありますが、少なくともコードが書き直されないことを前提として同様のアイデアが機能します。幸いなことに、シスコはベビーシッターの "baby is awake"コールを共有ライブラリに追加しました。そのため、LD_PRELOADを介したvpnagentdによるアクションを防止するという考えです。
まずファイルhack.c
を作成します。
#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;
}
それから次のようにコンパイルしてください。
gcc -o libhack.so -shared -fPIC hack.c
libhack.so
をシスコのライブラリパスにインストールします。
Sudo cp libhack.so /opt/Cisco/anyconnect/lib/
エージェントを停止します。
/etc/init.d/vpnagentd stop
本当にダウンしていることを確認してください
ps auxw | grep vpnagentd
そうでなければ、kill -9
は念のために。
次に、vpnagentdが呼び出される場所にLD_PRELOAD=/opt/Cisco/anyconnect/lib/libhack.so
を追加して/etc/init.d/vpnagentdを修正します。
LD_PRELOAD=/opt/Cisco/anyconnect/lib/libhack.so /opt/Cisco/anyconnect/bin/vpnagentd
今すぐエージェントを起動します。
/etc/init.d/vpnagentd start
AnyConnectがそれらと混同するため、iptablesを修正します。
iptables-save | grep -v DROP | iptables-restore
特定のLANホストだけにアクセスを許可するために、ここでもっと高度なことをしたいと思うかもしれません。
さて、あなたが好きなようにルートを修正しましょう。例えば:
route add -net 192.168.1.0 netmask 255.255.255.0 dev wlan0
それらが本当に存在するかどうかを確認してください。
route -n
このハックの以前の、より単純なバージョンは、「return 0;」だけをする関数を与えました。 - そのポスターは、「これまでに観察した唯一の副作用は、vpnagentdがtopで報告されているように100%のCPUを使用していることです。私はそれを強調しました、それはアイドルから両方から素早く戻ってくるときループで2つの選択をしているようですが、決して読み書きしません - 私はLD_PRELOADで切り取った呼び出しが読むことになっていたと思います。それをすることはできますが、これまでのところ私には十分です。誰かがもっと良い解決策を持っている場合は、共有してください。」
些細なハックの問題は、それがシングルCPUコアを常に100%にし、ハードウェアCPUスレッド数を事実上1つ減らすことです - あなたのvpn接続がアクティブだったかどうか。私が気付いたのは、コードが実行していた選択がネットリンクソケットで、ルーティングテーブルが変更されたときにvpnagentdデータを送信するということでした。 vpnagentdは、ネットリンクソケットに新しいメッセージがあることに気付き続け、それを処理するためにrouteCallBackHandlerを呼び出しますが、簡単なハックは新しいメッセージをクリアしないため、何度も何度も呼び出され続けます。上で提供された新しいコードはネットリンクデータをフラッシュするので、100%CPUを引き起こした無限ループは起こりません。
問題が解決しない場合は、接続したらgdb -p $(pidof vpnagentd)
を実行してください。
b socket
c
bt
そして、自分がどの通話に参加しているかを確認します。次に、どの通話を切り取りたいかを推測し、それをhack.cに追加して再コンパイルします。
これは非常に複雑ですが、VMWare Playerなどを使用して最小限のVMを作成し、その中でCisco AnyConnect VPNクライアントを実行すると、VMWare仮想ネットワークを使用しながらルーティングを設定できる可能性があります。アダプタを使用するか、または単にVMを使用して、Cisco SSL VPNを介して必要なリソースにアクセスし、実際のマシンとの間でファイルをドラッグアンドドロップします。
Shrew Soft VPNソフトウェアも、Ian Boydが示唆しているように、私にとってはうまくいきました。
Cisco VPNクライアントプロファイルをインポートできます。 Cisco VPN Clientバージョン5.0.05.0290を使用しました。ShrewVPN(バージョン2.1.7)をインストールしてCiscoプロファイルをインポートした後、Shrew VPN接続を追加設定することなく企業VPNに接続しながらローカルLANにアクセスできましたソフトウェア)。
Sasha Pachev さん、上記のNice hackに感謝します。
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メソッドのように、コールバックをインターセプトして解決しようとしていますが、対応するコールバックまたはメソッドがまだ見つかりません。
更新1/2:strace
は、vpnagentd
がinotify
APIを使用してリゾルバファイルの変更を監視していることを明らかにしました。そこから先は下り坂でした。これが追加のハックです。
int _ZN18CFileSystemWatcher11AddNewWatchESsj(void *string, unsigned int integer)
{
return 0;
}
エージェントを監視するallファイルが無効になるため、これはやややり過ぎです。しかし、うまくいくようです。
以下の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+\1LD_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
私の会社はまだそのVPNを使用しています。 vpncクライアントは単にiptablesの設定を次のように変更します。
#iptables-save #iptables-save v1.4.10 2012年6月17日14時12分20秒 * filter :INPUT DROP [0] :0] :前方への受け入れ[0:0] :OUTPUT DROP [0:0] - A入力-s 123.244.255.254/32 -d 192.168.0.14/ 32 -j ACCEPT - A入力-i tun0 -j ACCEPT - 入力-i lo0 -j ACCEPT - A入力-j DROP - A出力-s 192.168.0.14/32 -d 123.244.255.254/32 -j ACCEPT - 出力-o tun0 -j ACCEPT - 出力-o lo0 -j ACCEPT ] -A OUTPUT -j DROP COMMIT
それはVPNトラフィックを除くすべてをフィルタリングします。
単にiptables-saveを使ってファイルにフィルタを入れ、あなたのニーズに合ったINPUTとOUTPOUTアクセスラインを追加してiptables-restoreを使ってファイルを再適用するだけです。
例えば192.168.0のローカルネットワークにアクセスするため
#iptables-save v1.4.10 at Sun Jun 17 14:12:20 2012 * filter :INPUT DROP [0:0] :転送受け入れ[0:0] :出力ドロップ[0:0] - 入力-s 123.244.255.254/32 -d 192.168.0.14/32 -j ACCEPT -A入力-s 192.168.0.0/24 -d 192.168.0.14/32 -j ACCEPT #local - 入力-i tun0 -j ACCEPT - 入力-i lo0 -j ACCEPT - A入力-j DROP - A出力-s 192.168.0.14/32 -d 123.244.255.254/32 -j ACCEPT - 出力-s 192.168.0.14/32 -d 192.168.0.0/24 -j ACCEPT #local out - A出力-o tun0 -j ACCEPT - 出力-o lo0 -j ACCEPT - A OUTPUT -j DROP COMMIT
これに関する何かニュース?
どのレベルで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
笑ここでは20以下の測定基準はないようです。
正しく理解したかどうかはわかりませんが、まず理解を明確にします。
ローカルLAN(たとえば、10.0.0.0/16、リモートCisco VPN Server(たとえば、64.0.0.0/16)があります。CiscoVPNクライアントを介してVPNサーバに接続するには、まだ必要です。この場合は、10.0.xx/16全体をVPN接続から切り離します。次のルートをMacクライアントに追加する必要があります。
/sbin/route add -net 10.0 -interface en1
en1はLANに接続するときに経由するインタフェースです。私はあなたがWindowsとLinuxにも同じことを追加できることを知っています。
コメントを追加できないので、ここに投稿します。私はWindows上で走っています。
仮想マシンを使用し、VM内でAnyConnectを実行してから、作業環境と会社のネットワーク間のメディエータとしてVMを使用するソリューションでは、「最愛の」IT部門がルーティングしてもうまくいきません。 .0.0 VPN経由であなたのローカルネットワーク(あなたのローカルPCとVM間のこれも含む)でさえもVPNを通してルーティングされます(sic!)。
私は@Sasha Pachevによって投稿された解決策を適用しようとしましたが、結局私はそれが関数の始めに0を返すように.dllにパッチを当てることになりました。動的ライブラリとの戦いの後、やがて私は自分のニーズに応じてルーティングテーブルを修正することができましたが、どうやらそれだけでは不十分です。
私の規則は分割トンネリングを達成するために正しいように思えますが、私はまだ一般的な失敗に遭遇します。 解決できたのと同じような問題に遭遇しましたか?
これは私のルーティングテーブルが現在どのように見えるかです(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を実行しようとすると、単にタイムアウトになります(企業のファイアウォールではイントラネット外へのトラフィックの通過が許可されないため)。
Cisco AnyConnect SSL VPNを使用しているときにルーティングテーブルの制御を維持したい場合は、 OpenConnect を調べてください。どちらもCisco AnyConnect SSL VPNをサポートしており、ルーティングテーブルエントリの中断や「保護」を試みません。 @Vadzim 上記の コメントでこれをほのめかします 。
AnyConnect Secure Mobility Clientにパッチを適用すること以外はすべて試した後、Windows上で OpenConnect GUI に置き換えることに成功しました。これにより、ローカルリソースへの接続性を維持する(そしてルーティングテーブルを更新する)ことができました。
私はWindows上でOpenConnectを使っていますが、Linux、BSD、macOS(他のプラットフォームの中でも)をサポートしています プロジェクトページによると .
ゲートウェイ10.64.202.13
でそれらのエントリを削除してみてください。ping 8.8.8.8
が機能するかどうかを確認してから、それらを1つずつ追加して、問題の原因となっているエントリを特定してください。
DLLにどのようにパッチを当てましたか。ルーティングテーブルを変更することすらできません。VPNゲートウェイで0.0.0.0
を追加し続けているからです。