OSX用のCiscoAnyConnectクライアントでスプリットトンネリングを許可するための解決策を見つけようとしています。私はそれがファイアウォールをどのように変更しているかを見つけました、そしてそれは修正することが可能です。ただし、問題はvpnagentdデーモンがルーティングテーブルをハイジャックし続けることです。
Sasha PachevはLinux用のエレガントなソリューションを提案しました( https://superuser.com/a/546668/568559 )が、OSXに適応させるのに課題があります。
Linux用に書かれたhack.cは、linux/netlink.hを参照します、OSXには存在しません。これがAF_NETLINKの由来だと思います。
#include <sys/socket.h>
#include <linux/netlink.h>
int __ZN25CInterfaceRouteMonitorMac20routeCallbackHandlerEv()
{
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;
}
私はこの言語に精通していないので、どこを見ればよいのかわかりません。元の質問でこれをOSXに適合させることについて他の人が言及しているのを見ることができますが、結果はどこにも公開されていません。
誰かがこの方法をOSXに適応させる運がありましたか?どんな助けでも大歓迎です。
この側面が機能するようになったら、完全なソリューションを共有できることをうれしく思います。
(私はNETLINKデータを排出するこの関数の拡張バージョンを作成しました 傍受する関数を見つけるSasha Pachevの素晴らしい探偵の仕事に続いて 。人々がコードを有用だと思ってくれてうれしいです。)
他のスレッドから、誰かが「nm」を使用してOSXに類似したコールバックハンドラーがあることを発見し、それを置き換える適切な関数を作成しようとしていることがわかりました。 OSXがNETLINKインターフェースをまったく提供していないことは私の理解です。したがって、OSXバージョンのAnyConnectがLinuxクライアントと同じようにルーティングテーブルを制御し続ける可能性はほとんどありません。ルーティングの変更が発生したことをAnyConnectに通知するためにOSXが提供するメカニズムはわかりませんが、NETLINKベースではないため、ここでnetlinkメッセージを排出するコードは適用できません。
皮肉なことに、Sashaが提供する元のスタブ関数スタイルは、ルートが独自のルートに置き換えられるのを防ぐために必要なすべてのスタイルである可能性があります。その関数は次のようになりました。
int __ZN25CInterfaceRouteMonitorMac20routeCallbackHandlerEv()
{
return 0;
}
Linuxでは、コールバックハンドラーの呼び出しをトリガーしたNETLINKイベントがこの何もしないコードによってクリアされることはないため、その元の関数によりCPU使用率が高くなりました。 OSXクライアントでも同じ影響が発生する可能性があり、この関数を呼び出すイベントがトリガーされてもクリアされません。ただし、この関数がインターセプトする正しいハンドラー関数であり、独自のライブラリを作成してその関数をオーバーライドし、実際のライブラリの代わりにそのライブラリをロードできる場合は、少なくとも、ルーティングテーブルが毎回リセットされるのを防ぐことができます。自分で変更しようとするとき。ここまで進んだら、CPUをいくらか犠牲にする価値があるかもしれません。
幸運を!
ちょうどこの投稿に出くわしました。結果を共有したいと思いました。
私はOSXでこのハックをしました。 Rubioが提供するソリューションは確かに機能します(残念ながら、1つのコアで100%のCPUが使用されます)。
OSXはLD_PRELOADを使用せず、DYLD_INSERT_LIBRARIESが何らかの理由でこのバイナリに対して機能していなかったため、ローダーをだまして関数を使用させることができませんでした。他の誰かがその問題に遭遇した場合、私は元のlibvpnagentutilities.dylibアセンブリを編集することによってそれを解決しました(16進エディターはここであなたの親友です)
関数の最初の6バイトを次の命令に置き換えて、上記のCコードと同じ「return0」効果を実現します。
__ZN25CInterfaceRouteMonitorMac20routeCallbackHandlerEv:
0007add0 movl $0x0, %eax
0007add5 retl
ただし、関数呼び出しのトレースをさらに行った後、CPU使用率を上げずにそれを実行する方法を見つけました。それは実際には上記の私の解決策よりも簡単です。 _ZN28CInterfaceRouteMonitorCommon20routeCallbackHandlerEvと呼ばれるルートテーブルを変更するタスクを実際に委任される別のシンボルがあります。その関数の呼び出しスタックをトレースすると、オフセット67c06で変更を実行するために呼び出す関数が見つかりました。
ソリューション?前にリストした変更を無視し、代わりに67c06の呼び出し命令をnopに置き換えます!!
これが前です:
00067c03 movl %eax, (%esp)
00067c06 calll *0x8(%ecx)
00067c09 addl $0x4, %esp
そして、これが最終バージョンです。
00067c03 movl %eax, (%esp)
00067c06 nop
00067c07 nop
00067c08 nop
00067c09 addl $0x4, %esp
変更するのはそれだけです。元のvpnagentutilities.dylibをこの変更されたバージョンに置き換えて、ベビーシッターのいないルートテーブルをお楽しみください。最初の接続時にテーブルを変更しますが、適切と思われる方法で自由に変更できます。
EFF YOU ANYCONNECT!