TOR的原理————Tor的运行

        TOR是TheOnionRouter的缩写,直译就是洋葱路由。
       TOR官网上简单介绍了TOR的原理:TOR是一个三重代理,TOR客户端先与目录服务器通信获得全球活动中继节点信息,然后再随机选择三个节点组成 circuit(电路),用户流量跳跃这三个节点(hop)之后最终到达目标网站服务器,每隔10分钟左右就会再重新选择三个节点以规避流量分析和蜜罐节 点。
看到这里,有些人就会开始这么说了:看起来除了每隔10分钟左右变换节点之外,其他与任意三个代理组成的三重代理也没什么区别啊。
       真的是这样的吗?
       TOR的具体工作机制可远远没有官网上介绍的简单:当用户启动TOR后,TOR客户端就会在本机PC上运行一个onionproxy,同时开始监听本机 的9150端口(TorBrowser里的Tor监听端口),所有经过这一端口的流量都会在经过onionproxy的处理之后进入TOR电路中。关于端 口有必要做一下说明:对于服务器,只要服务器开机,端口就一直存在;但对于本机,只有相应的应用程序试图与远程服务器通过特定端口通信时,端口才会出现, 一旦通信结束端口就会立即消失。也就是说,这个9150端口只有在某一应用程序(例如被设置过的浏览器,例如Tor)试图通过它与远程主机通信时才会出 现,并不是个物理存在。
       不过这会儿还不能传输用户数据呢,在本机上运行onionproxy只是第一步而已,然后当然是与存有全球中继节点信息的目录服务器取得联系了。一开始 这一步是明文HTTP通信,有着增加流量指纹的风险,后来Tor开发者进行了改进,让Tor客户端第一步先与入口节点通信(当然第一次连接是做不到的,以 后的连接都可以这么做了)再与目录服务器通信更新节点信息,全过程都是TLS的,这样做不仅保证了安全,还避免了单独与目录服务器建立一次性的 TLS连接,提高了效率(因为建立TLS连接是很消耗资源的,生成随机参数进行密钥交换强加密传输数据都是要进行大量运算的,如果只是为了短暂的一次性连 接,那么就有些太浪费了):当完成更新中继节点信息之后,客户端不必切断连接,而是可以直接把原来的TLS连接「拔出来」再继续组成电路(意思是原来的 TLS连接的参数还可以继续使用,而不用又重新计算生成)得到中继节点信息之后,电路构造过程就正式开始了!
       对了,诸位猜一下,Tor电路会是怎样的呢?会怎样进行构造呢?
       “既然是个三重代理……要么是这样一个过程:onionproxy先将数据加密传送到入口节点,然后入口节点又加密传送到中间节点,中间节点又加密传输 到出口节点,在HTTP的情况下这三个节点都能看到明文(一般的代理就是这样的)?”我说,你不觉得这样非常不安全吗?要是其中有哪一个节点被攻破或者是 蜜罐,那么你可就呵呵了!还有就是如果不进行特别设置的话,后面两个代理也是知道用户数据流的真实来源的(真实IP),也就是说安全性还是相当于一重代 理!那么,Tor究竟是怎么做的呢?
       “哪个节点都不可信,像洋葱一样”这就是Tor环路的核心思想所在:和普通的TCP流不同(Tor工作在TCP流之上),Tor协议把通信数据打包为了 一个个特殊的cell:一开始建立Tor电路时,本机上的onionproxy向入口节点发送createcell进行TLShandshake,这一过 程的身份认证过程是基于数字证书的:Tor有着自己的一套数字证书系统,每一个洋葱路由(就是节点)都有一个用于签发证书的身份密钥和用于解密用户的电路 建立请求以及协商出一个用于后续通信的(使用时间)短暂的密钥。当节点之间进行通信时,这个特制的TLS协议还会建立短期连接密钥,而且这一密钥会周期性 的独立发生变化以最大限度降低密钥泄露带来的风险
Tor电路默认由客户端和三个节点组成,那么我们就来看看在这种情况下Tor电路究竟是怎样建立的吧:
       Tor是这么做的:客户端最先发过去的relaycell1是入口节点与中间节点建立TLS连接时所需要的参数,接着发过去的relaycell2是中间节点与出口节点建立TLS连接时所需要的参数,接下来是只有目标网站和对应端口信息的relaycell3, 在返回表明已成功建立环路的relaycell4之后才会真正开始发送包含用户信息的relaycell5。这一过程中relaycell1被一重加密, 到了入口节点之后就被解密,再用来与中间节点完成握手;relaycell2被两重加密,到了入口节点时第一重加密解除,到了中间节点时第二重加密解除, 中间节点可以看到明文,用来与出口节点完成握手;relaycell3被三重加密,只有出口节点能看到明文,被用来与目标网站建立连接。同样 relaycell5也是三重加密的,只有出口节点能看到明文(HTTP)。
       「就像洋葱一样」,对,用户数据就像洋葱一样,被层层包裹着,只有到了终点包裹才会解开。在这一过程中,只有入口节点知道用户的真实IP地址,出口节点 知道用户的目的地和传输内容(HTTP),Tor电路的cell里没有其他任何关于用户真实身份的信息(这里不考虑cookie和flash插件等应用层 协议和程序带来的隐私问题(这些也不是Tor本身能够左右的,Tor使用的是在传输层之上应用层之下的SOCKS代理,无法操纵修改上层协议,但这也使得 Tor能成为很多软件的代理,不被应用层协议们所左右),只针对于传输过程而言)「似乎有哪里不对呢:如果说这几重加密都是预设的参数,那么一是做不到完 全随机了(一定要人为去划分入口节点中间节点出口节点才能做到事先内置相应的解密密钥),二是一旦密钥泄露后果就会相当严重的。但如果不是预设参数而是每 次连接时都随机协商,那么又该怎么做呢?」「你说得没错,Tor电路中的节点们并没有预设参数,而是采取了「半握手」的方法:在diffie- hellman算法的帮助之下,onionproxy和中间节点通过入口节点的中介交换了参数,然后就能各自算出私钥用于后续通信而不用担心有人监听,入 口节点虽然知道这两个参数,但也根本没办法算出私钥来,这是diffie-hellman算法设计时所保证的」。同理也可以与出口节点安全通信,客户端最 里面一层的加密只有出口节点能够解开,入口节点和中间节点都看不到只有出口节点才能看到的内容。
       那么,Tor在建立电路时又是怎么选择节点的呢?
       借助算法随机选择,没错,但“一次性随机选择三个节点”,错了!
       Tor客户端先随机选择一个入口节点,然后入口节点再随机选择一个中间节点,中间节点又随机选择一个出口节点,这样来最大限度实现随机建立电路。而且 Tor还有一个更特别的地方:很多用户的流量可以被整合到一个TLS连接里同时传输!看起来就像一个用户一样!这样一来,匿名程度更高了,但很多时 候又会带来一件麻烦事:很多用户的来自同一个IP的大量流量都同时指向同一个网站(例如google),看上去非常像是DoS(拒绝服务)攻击,此时就会 触发网站的防御机制,网站会要求用户输入验证码,非常烦人。
“可爱的洋葱头很努力啊。”现在谁还会说Tor只是一个三重代理呢?

TOR有三点最为特别:
        1、一个TOR环路可以被很多人同时使用,说的具体一点,hop与hop之间的每个TLS连接都包括了很多不同用户的TCP数据流;
        2、TOR客户端随机选择了入口节点,入口节点随机选择了中间节点,中间节点又随机选择了出口节点。对,是由精心设计过的算法保证随机选择的,没有规律可 循(不过后来发现这算法造成了很搞笑的情景:某一条环路上的三个hop有很多用户,都塞车了,但另一条环路上的三个hop用户数少得可怜,所以后来又基于 hop的用户数对算法进行了改进)

       3、TOR拥有独立于操作系统和浏览器的严格的基于数字证书的身份认证机制。这一点很重要,如果TOR的身份认 证机制和特定的操作系统或浏览器有了关联,那就意味着用户将不得不为了使用TOR而更换浏览器或操作系统。