可以监控应用对外的网络流量、分析协议、重定向、并针对每个协议进行修改,同时可以录制和回放。项目也得到了部门总监和其他leader的肯定,可以多花心思弄弄好。

因为项目的核心是一个Socks代理,通过这个代理捕获双方的流量,并进行后续的操作。

 

后来跟RednaxelaFX提问之后,确认了JVM是根据ClassCloader+package来确定一个包的,所以要使自己写的类能访问sun.nio包的内容,必须使用Boostrap Classloader来加载。后来在javaagent里配置了相应参数,搞定!

 

配置Client

JDK的OIO是支持全局代理的,只需在JVM参数中配置-DsocksProxyHost=xxx -DsocksProxyPort=xxx即可。遗憾的是,这个配置对NIO是不起作用的。

后来考虑过几种办法:

  1. 因为公司项目用到NIO的部分,主要也是通过netty做的。那么改netty的API,使其支持代理,是最简单的做法。使用netty构建一个socks client也是得心应手。但是这种做法不够彻底,且不具有通用性。
  2. 修改NIO的接口SocketChannel.open()的实现,使其返回一个可以使用代理的SocketChannel。这种方法最彻底,但是涉及到JDK一些底层API,有些还没有暴露出来,实现难度有点大。

后来决定采用方法2,顺便学习一下。

SelectorProviderImplSocketChannelImpl都是VM的私有API,只有下载JDK源码才能看到。下载openjdk源码后,在jdk/src/share/classes/目录可找到。

SelectorProvider.provider()是JDK自己的一个扩展点,会根据不同的OS选择不同的SelectorProvider,OSX是KQueue。尝试自己写了一个SocketChannel的子类,做一个全局代理,结果被SelectorImpl摆了一道,里面要求必须实现sun.nio.ch.SelChImpl接口,而这个接口是包级可见的。

抱着侥幸心理,尝试将自己的新类写到sun.nio.ch包下,结果编译通过,加载提示无法访问其父类接口sun.nio.ch.SelChImpl

后来跟RednaxelaFX提问之后,确认了JVM是根据ClassCloader+package来确定一个包的,所以要使自己写的类能访问sun.nio包的内容,必须使用Boostrap Classloader来加载。后来在javaagent里配置了相应参数,搞定!