Http隧道(tunnel)技术与Proxy

转自:
http://www.fenesky.com/blog/2014/07/25/how-http-tunnel-works.html

(tunnel)技术与Proxy
Harlen Tan photo
By Harlen Tan
July 25, 2014
0 条评论
Permalink
Like
Tweet
+1
一直都没有深入研究过 Http Proxy,最近在使用libcurl的过程中,发现在有Proxy的情况下,使用CURL请求一个https的资源,会有返回2个response。经过一番抓包和研究之后,发现另有原因。

根据RFC2817的讲解发现,在使用Proxy请求https的时候,首先会使用HTTP的CONNECT Method向Proxy发起请求。

另外,更具RFC2816中关于CONNECT Method的讲解,HTTP的CONNECT方法是用跟Proxy一起动态的建立HTTP隧道的。

Alt Text
如图所示,通过Proxy,Client和Content Server之间建立起了隧道。这种隧道使得客户端感觉不到代理的存在,在客户端开来,它是直接跟要请求的资源服务器在通信。

Http隧道分为两种:

不使用CONNECT的隧道
使用CONNECT的隧道
不使用CONNECT的隧道,实现了数据包的重组和转发。也就是在我们使用Proxy的时候,然后发起Http请求,使用的就是非CONNECT的隧道。在这种情况下,在Proxy收到来自客户端的Http请求之后,会重新创建Request请求,并发送到目标服务器,也就是图中的Content Server。当目标服务器返回Response给Proxy之后,Proxy会对Response进行解析,然后重新组装Response,发送给客户端。所以,在不使用CONNECT方式建立的隧道,Proxy有机会对客户端与目标服务器之间的通信数据进行窥探,而且有机会对数据进行串改。

而对于使用CONNECT的隧道则不同。当客户端向Proxy发起Http CONNECT Method的时候,就是告诉Proxy,先在Proxy和目标服务器之间先建立起连接,在这个连接建立起来之后,目标服务器会返回一个回复给Proxy,Proxy将这个回复转发给客户端,这个Response是Proxy跟目标服务器连接建立的状态回复,而不是请求数据的Response。在此之后,客户端跟目标服务器的所有通信都将使用之前建立起来的建立。这种情况下的Http隧道,Proxy仅仅实现转发,而不会关心转发的数据。

这也是为什么在使用Proxy的时候,Https请求必须首先使用Http CONNECT建立隧道。因为Https的数据都是经过加密的,Proxy是无法对Https的数据进行解密的,所以只能使用CONNECT,仅仅对通信数据进行转发。

所以,实际上所有的网络库(例如libcurl, chromium_net)在实现的时候,如果使用了Proxy,在请求Https协议的资源是,首先是使用CONNECT方法建立Http隧道,等收到目标服务器建立成功的回复之后,开始做SSL/TLS握手,然后进行数据传输。

虽然Http CONNECT隧道安全,能够使得客户端的数据实现"翻 墙", 但是Http CONNECT容易失控,由于数据都是加密的,Proxy跟目标服务器建立TCP连接之后,之后的所有数据都服用这个连接。但是Http CONNECT隧道不仅仅是可以建立Https 443端口的连接,实际上可以建立任何端口的连接,这也使得Proxy变得非常危险,所以,一般的服务器都会对Http CONNECT隧道进行控制,只能实现Https 443端口的隧道通信。

HTTP Tunnel使用的几种使用(经典)

博客分类: httpwindows xp
http proxySOCKS5HTTP Tunnel
公司的网络该封的都封了, 今天看到有这么个软件, 虽然没有用过, 觉得不一定哪天就用了, 所以收藏到这里.

基本概念不多解释了,直入主题。GNU HTTP Tunnel (http://www.nocrew.org/software/httptunnel.html)是一个开源的http-tunnel项目,包括了tunnel server(hts命令)和tunnel client(htc命令),有(x)nix和windows版本。我们就用它来建立自己的tunnel。
1。静态tunnel。
http-tunnel是一个完全透明的通道,直接将你的连接forward给目标服务端口,因此当你连接tunnel的本地侦听端口时,就相当于直接连接到目标服务端口。例如你要建立一条可以访问外部POP3服务器的隧道,可以建立如下连接:

htc ------------> http proxy ------------------------> hts ------------------------------> POP3 serve
(localhost:8888) (proxyhost:3128) (tunnelserver:80) (pop3server:110)
在你自己的机器上运行htc,外部充当tunnel server的机器上的80端口运行hts,htc将数据打包成http请求,通过proxy连接到hts,hts解包后将连接forward给POP3服务器。命令如下:
在tunnel server机器上:
hts --forward-port pop3server:110 80
(将pop3server替换成实际的IP)
在本地机器上:
htc --forward-port 8888 --proxy proxyhost:3128 tunnelserver:80
(将proxyhost和tunnelserver替换成实际的IP)

通过这样的配置,你可以用Outlook或Foxmail连接本机的8888端口,就相当于直接连接到POP3服务器了。

2。动态的tunnel。
上面建立了一条可以访问POP3服务的隧道,但缺点是只能访问某一个指定的POP3服务器,要访问其他的服务器还得按同样的方法再建立一条隧道,很不方 便。既然hts可以将连接forward给POP3服务器,那让它forward给一个SOCKS5服务,不是就可以实现动态的tunnel,可以连接任 意服务了吗?yeah!没错!我们建立这样的连接:

htc ------------> http proxy ------------------------> hts ------------------------------> SOCKS5 serve
(localhost:8888) (proxyhost:3128) (tunnelserver:80) (socks5server:1080)

命令就不说了,照第一点改一下就行。这样就相当于在localhost:8888运行了一个SOCKS5服务,设置一下你的网络程序(Outlook,NetAnt,FlashGet,QQ......),让他们通过SOCK5访问网络,就OK了。

3。利用http proxy的CONNECT支持。
大多数http proxy支持CONNECT命令,但一般只支持CONNECT到外部服务器的443(https)端口。这是为了允许访问外部的https服务。由于 porxy对于CONNECT的连接是直接转发,不做任何分析处理或缓存,所以利用CONNECT可以获得比较快的速度。
由于hts和htc不支持CONNECT连接,我们可以使用另一个专门支持CONNECT的程序DesProxy http://desproxy.sourceforge.net
来建立一个tunnel。由于使用CONNECT建立了直接的TCP连接,不需要将数据按http格式打包和解包,所以连tunnel server也不需要了,只需要在你原来运行hts机器上运行一个SOCKS5就行了,连接如下:

desproxy -------------> http proxy ----------------------> SOCKS5 server
(localhost:8888) (proxyhost:3128) (tunnelserver:443)

desproxy命令的用法:
desproxy remote_host remote_port proxy_host proxy_port local_port
在这里remot_host,remote_port就是tunnelserver:443,proxy_host,proxy_port是porxyhost:3128,local_port就是8888。

注意必须把SOCKS5运行在443端口,如果运行在其他端口的话,CONNECT请求会被http proxy拒绝。同样,我们在localhost:8888得到了一个可以访问外部的SOCK5服务。

4。最简单,最安全而且快速的方式:利用SSH + CONNECT。
实际上SSH提供了SOCKS5的功能,利用ssh客户端或PuTTY可以在本地建立一个SOCKS5服务,而且PuTTY也直接支持http proxy,最大的好处是ssh的数据连接是加密的,保证了数据的安全。使用ssh的连接如下:
PuTTY(或plink) ------------> http proxy ---------------------> ssh server
(localhost:8888) (proxyhost:3128) (tunnelserver:443->22)
首先我们要让ssh server在443端口侦听,ssh默认端口是22,我们可以修改ssh的配置,或用iptables将443端口重定向到22端口,服务端的配置就 OK了。然后在PuTTY建立一个new session,填上ssh服务器的ip和port;在"Connection->Proxy"页,填上http proxy的ip和port;在"SSH -> Tunnels"页,"Source port"填本地的端口,在这里我们用8888",Destination"选"Dynamic",按"Add"将这个forward port加上,就OK了。配置完成后,用PuTTY登陆上ssh,用netstat -an可以看到PuTTY已经在localhost:8888侦听了,这是一个SOCKS5服务,下面改怎么用,就不用我罗嗦了吧:-)。另外在 "SSH"页,可以根据要求选择"Protocol options"。保存session后,也可以用命令行的plink命令来利用这个session:
plink -load session_name (session_name就是session保存的名称)
登陆后效果也一样。

http://javasky.172baby.com/posts/123518.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值