目录
在通过https握手rtt识别TCP代理(socks5/http)之后,渐渐的发现这个事情没想象中的靠谱,主要原因分析大概如下:
- iphone在部分情况会有谜之延迟,如果通过设置清楚浏览器缓存和记录,可以稳定得到一个近500ms 的延迟。个人认为客户端在没有https证书缓存的情况下验证会出现这个情况。对应的就是用户第一次访问你的服务器。
  
- https 几乎都是配合H2或者https/1.1使用,由于链接复用,都很难再次触发重新握手(写这文章时还这么认为),则无法进行多次检测加以验证。
302图片特点
为了规避以上问题,我想到一个简单的方法,就是一个302图片跳转。事实上只要是个302跳转就行,用图片的原因有:
- 图片可以通过img标签引入,页面无需跳转
- img 默认支持302,并且可以视为完整且不易被干扰的过程
- img 默认支持跨域,方便其他人使用
原理
通过https握手rtt发现代理的本质原因是:
- 这是个连续过程
- 有必然来自客户端的数据(密钥交换)
- ack应答包被代理先应答
对比302图片过程
正常情况下
	cliet	================== 	server
1		== img request ==>
2		<= 	ack	==
3		<=   302 header ==
4		== 	ack	=>
5		==302img request=>
6		<= 	ack	==	
7 		<=   img body   ==
8		== 	ack	=>
在代理的情况下
	cliet	==================	proxy	==================	server
1		== img request ==>		
2		<= 	ack	==		==  img request =>
3						<= 	ack	==
4						<=   302 header ==		
5		<=   302 header ==		== 	ack	=>
6		== 	ack	=>
7		==302img request=>
8		<= 	ack	==		==302img request=>
9						<= 	ack	==
10						<=   img body   ==
11 		<=   img body   ==		== 	ack	=>
12		== 	ack	=>
这是我们也会发现,302图片符合上面提到的原理:
- 这也是一个近乎连续的过程
- 有来自客户端数据(302img request)
- ack包被proxy代理先应答
与https不同的地方
由于302图片过程存在在整个数据中间,并且包并不用于TLS是明文并且可以被简单识别。那么我们需要通过某种方法吧这个过程的包提取出来。
提取关键数据
我是用的方法是通过记录2次img请求到达时间,提取中间的抓到的数据包进行分析。对应上述的过程,则是:
- 不使用代理的步骤 2、3、4、5
- 使用代理的步骤 3、4、5、6、7、8
这时就会发现,关键的点就是 302 header对应的ack应答包已经后续的 302img request。其到达时间间隔则可以视为客户端到代理的延迟。
相比TLS握手优点
- 由于302图片依然可以在https协议下运行,因此,一个302图片可以至少得到2次检测机会
- 302图片可以发起多次请求,在一次检测结束后,在重复加载图片可以在得到一次数据
- 由于http2和http/1.1会话复用,页面多次刷新触发的302图片会让结果更接近真实情况
demo
proxy guess demo