当我通过 cisco anyconnect 客户端连接到 VPN 时,路由添加不再有效

dai*_*isy 13 cisco

当我通过Cisco AnyConnect客户端连接到 VPN 服务器时,我的虚拟机路由信息消失了。

# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         *               0.0.0.0         U     0      0        0 cscotun0
default         172.21.157.1    0.0.0.0         UG    256    0        0 eth0
172.23.36.90    172.21.157.1    255.255.255.255 UGH   0      0        0 eth0
172.23.236.0    *               255.255.254.0   U     0      0        0 cscotun0
Run Code Online (Sandbox Code Playgroud)

然后我尝试通过以下方式恢复它:

# ip route add 192.168.56.0/24 via 192.168.56.1 src 192.168.56.1
Run Code Online (Sandbox Code Playgroud)

命令成功没有错误,但从route命令它不添加任何东西

# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         *               0.0.0.0         U     0      0        0 cscotun0
default         172.21.157.1    0.0.0.0         UG    256    0        0 eth0
172.23.36.90    172.21.157.1    255.255.255.255 UGH   0      0        0 eth0
172.23.236.0    *               255.255.254.0   U     0      0        0 cscotun0
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?我已将 apparmor 配置为阻止 vpnagentd 运行 iptables 或 modprobe 命令(如果相关)。

dai*_*isy 8

原来是 Cisco AnyConnect 客户端正在监控路由表。

C++ 函数CHostConfigMgr::StartInterfaceAndRouteMonitoring()正在完成这项工作。您可以修改函数以使其立即返回(并修复 vpnagentd 中的校验和验证)或使用新函数名称尝试此解决方案_ZN14CHostConfigMgr32StartInterfaceAndRouteMonitoringEv


小智 8

介绍和其他选项

大约 5.5 年了,所以我主要把这个答案留给人们,试图用现代 Cisco Anyconnect 4.x 解决同样的问题。就我而言,Anyconnect 正在将流量封装到由 Minikube 在 macOS 上启动的本地 Kubernetes 集群。

类似_ZN27CInterfaceRouteMonitorLinux20routeCallbackHandlerEv__ZN25CInterfaceRouteMonitorMac20routeCallbackHandlerEv描述的方法:

似乎不再起作用了。此外,很多指南都与修复以前版本中由ipfw实用程序表示的 OS X 防火墙相关,例如此处,因此它们无关紧要。

修补 vpnagentd

2019 年,我们仍在与这两个问题作斗争,因为公司避免了拆分路由和提出不合理的防火墙规则。这里修复。

你需要修补拨打方法的 CHostConfigMgr::StartInterfaceAndRouteMonitoring()vpnagentd二,这在我的版本位于0x09cbf6。这是一个简单的jmp qword命令,永远不会返回到这个地方,所以单个nop就足够了。但是,用 6nop秒完全擦除命令可能是值得的。

这里的 Python 脚本可以为您自动执行此过程,但是任何反汇编实用程序都可以帮助您。在我最初的研究和 hack 中,我使用了radare2这对于不每天执行此类操作的人来说非常方便:

#!/usr/bin/python3

MAGIC_OFFSET = "0x09cbf6"
MAGIC_BYTE = 144

def eff_anyconnect(file):

    print("Opening {} to patch it".format(file))
    with open(file, "rb+") as f:
        print("Going to {}".format(MAGIC_OFFSET))

        print("Current command to call method for watching our routing table")
        f.seek(int(MAGIC_OFFSET, 16))
        print(hex(int.from_bytes(f.read(6), "big")))

        f.seek(int(MAGIC_OFFSET, 16))
        f.write(bytes([MAGIC_BYTE]))

        print("NOP any longer:")
        f.seek(int(MAGIC_OFFSET, 16))
        print(hex(int.from_bytes(f.read(6), "big")))

eff_anyconnect("/your/path/to/cisco/bin/vpnagentd")
Run Code Online (Sandbox Code Playgroud)

下一步,在修补二进制文件后,您应该终止当前vpnagent进程并重新连接到您的 VPN。您可能会发现所需的路由仍然受到影响,但上面的 hack 将解锁路由表,因此您可以覆盖路由。

路线

我建议添加-static一个,那些完全不受 AnyConnect 干扰,而非静态仍然被隧道复制。我在这里没有好的解决方案,对于我的情况,单个静态路由就足够了:

sudo route -n delete $(minikube ip) 
sudo route -n add $(minikube ip) -interface bridge100 -static
Run Code Online (Sandbox Code Playgroud)

防火墙

最后,防火墙步骤。这非常简单,您需要检查拒绝或仅允许 AnyConnect 标记规则的规则是什么。就我而言,所有未标记的内容都被阻止,因此我创建了一个包含以下条目的文件:

nat on utun1 proto {tcp, udp, icmp} from 192.168.64.0/24 to any -> utun1 
pass in log on bridge0 inet all flags S/SA keep state tag cisco_anyconnect_vpn_pass
pass in log on bridge100 inet all flags S/SA keep state tag cisco_anyconnect_vpn_pass
Run Code Online (Sandbox Code Playgroud)

注意以下几点:

  • utun1 是您的 AnyConnect 接口
  • bridge0并且bridge100是您的 Minikube/Docker 桥接器。出于某种原因,AnyConnect 会重命名网桥。
  • 192.168.64.0/24 是您的 Minikube 子网。

然后运行:

sudo pfctl -e enable packet-filtering
sudo pfctl -f <your_file_with_rules> -v
Run Code Online (Sandbox Code Playgroud)

从现在开始,直到下一次重新连接,您应该在路由和防火墙方面做得很好。