一个网络访问故障的排查

故障描述:

一个Python程序,在我的Macbook Air上使用Gearman库访问Gearman服务器时始终报错:
Found no valid connections in list:
[<GearmanConnection 111.111.111.111:80 connected=True>]

问题排查过程:

  1. 我的另一台电脑的Linux系统下运行这个程序是正常的,所以证明Gearman服务器本身是好的,程序也是对的。
  2. 别人的Macbook Air/Macbook Pro上运行这个程序也是正常的,系统中的Python版本是一致的,证明这个程序在Mac OS X下并不存在兼容性问题。
  3. 111.111.111.111:80这个是一个从开发环境访问生产环境服务器的虚拟IP/端口,把Gearman服务安装到开发环境网络中222.222.222.222:4730,程序运行正常。
  4. 由于访问开发环境正常、访问生产环境异常,所以怀疑是网络原因。使用ping/traceroute命令访问111.111.111.111,都正常。用telnet 111.111.111.111 80尝试TCP连接,也正常。
  5. 在无线/有线之间切换网络物理连接方式,测试结果一样:本机与目标服务器之间网络通畅,TCP连接正常,但Gearman连接无法正常建立。并且同处于同一个网络中的其它电脑上运行一样程序都访问正常。
  6. 怀疑Gearman的Python库在某些特殊情况下有Bug,在里面加了很多print来打印日志,发现客户端在与服务器建立完连接后,在真正要通信时,连接又变成了断开状态。但由于不太了解Gearman库的实现细节,再要进一步Debug,存在一定困难,暂时放弃这个思路。
  7. 为了排查Gearman连接断开的原因,用Wireshark进行抓包。抓包的结果非常令人惊讶:在程序运行的整个过程中,没有抓到任何客户端与服务器之间通信的数据包。但是程序打印出来的日志却明明显示出连接是先建立再断开的。
  8. 至此,问题已经快要查清楚了:本机有个程序劫持了本机发起的网络通信,实施中间人攻击,造成Gearman连接异常。
  9. 用Python写socket程序尝试向不同目标发起各种TCP连接(后来意识到其实用telnet就可以了),同时用Wireshark抓包,发现本机发起的所有目标为80端口的连接都会被劫持。劫持的效果是如果通过80端口进行HTTP通信,劫持的程序就会充当一个代理服务器的功能,正常完成通信过程。但是一开始出问题的程序是在80端口跑Gearman的通信协议,所以这个劫持程序无法正确处理,造成了通信异常。
  10. 最后就是要找出是哪个程序实施了劫持,用了一个很土的方法:下载一个大文件,同时用netstat -na查出与服务器80端口通信的本地端口号(谁叫Mac OS X的netstat命令没有-p参数直接看是哪个进程的连接呢?),然后用sudo lsof -i :<local port>命令查出这个本地端口号的使用者。

真相大白:

Cisco AnyConnect Secure Mobility Client中自带了一个进程名为acwebsecagent的Web安全模块,这个安全模块不管VPN是否在使用,都会劫持本机所有的发往80端口的通信,具体它做了什么好事坏事就不得而知了。

找到了问题所在,网上搜一搜就能查到很多吐槽这个Web Security模块的贴子了,它会随着AnyConnect默认安装到你的电脑上(我的电脑系统是IT预装的,不然我装AnyConnect时肯定会手工把这个勾勾去掉)。解决问题的方法也很简单 ,一行命令卸载它:
sudo /opt/cisco/anyconnect/bin/websecurity_uninstall.sh

发表评论

电子邮件地址不会被公开。 必填项已用*标注