转自
技术上的匿名
先构建一个模型(大部分翻墙党都符合这个模型):来到这里要从本地PC开始,经过交换机(平时很多人说的” 家庭路由器” 真正的名字叫交换机,真正的路由器不是个人能买得起的),网关(如果是局域网),N 个路由器,GFW ,代理服务器,然后又是N 个路由器,最终到达google服务器。如果是改hosts 来的,那么就没有代理服务器这一步了。
这其中只要数据是被强加密的,那些交换机路由器网关以及GFW 就都不是问题。当然,
在代理服务器之前的交换机网关路由器以及GFW 是知道你的真实IP的(交换机还知道你的真实MAC 地址呢),但在强加密的情况下,他们不知道你干了些什么(” 不知道你具体干了什么” 不等于” 不知道你在翻墙” ,ISP 和GFW想要知道你在翻墙不是一件难事) 。
代理服务器负责处理数据包,对于诸位而言,他是服务器;对于google服务器而言,他是客户端。又当服务器又当客户端,这就是代理服务器的特别之处。
代理服务器之后的路由器以及最终的google服务器看到的都是代理服务器的IP了,用户的真实IP就被隐藏起来了,所以说” 有一定的匿名性 。
但问题在于代理服务器知道你的真实IP和你干了些什么(HTTP),所以一旦代理服务器出事,后果不堪设想,而一个合格的匿名系统绝对不能完全依赖于某一环节的安全性,不然这一环节出问题就意味着匿名的失效,没有人敢用这么脆弱的系统保护自己的!
而且说实在的流量分析也不是什么新的领域,还有随着云计算的发展而越来越有效的数据挖掘(关联分析),一重代理完全无法应对这两者(事实上单纯的TOR 也无法应对数据挖掘,所以才有了TOR browser ,而且仅仅使用TOR 是无法规避很多风险的,这点TOR 官网上也有说说明)。
说到这里,有人又会这么想了:一重代理做不到匿名,那么自己想办法组合二重代理甚至更多重代理不是可以解决问题了吗?要知道TOR 不就是个三重代理吗?喂喂,事情没有这么简单好吧?
首先,
自己想办法组合的多重代理未必真的是多重代理 :这话听起来很奇怪,但是请想象一下,假设代理服务器P1和P2组合成了代理链条,然后P1知道了你的真实IP和你干了什么(HTTP)或者你去了哪里(HTTPS ),P2也有可能知道你的真实IP的(这取决于代理服务器的设置,有些代理服务器在和其他代理服务器通信时是不会装成客户端的),那么实际上不是还是一重代理吗?
其次,就算P2不知道你的真实IP,它还是会知道你干了什么的,假设有个攻击者控制了P2,那么他就会进行逆向追踪以找出你的真实身份,然后就不用我说了:脆弱的P1保护不了你的!如果是P1被黑了那么情况就更糟糕了!
那么我们就应该可以想到一些关键点:
首先,对于一个匿名系统,它的各个环节除了必要的信息之外,其他什么都不该知道,这样当某一环节被攻破时,用户匿名失效的可能性最小;
其次,应该让用户通信时跨越适当数量的跳板(hop ,或者叫中继节点),而且最好是不同国家的hop ,这样流量分析就难以进行,逆向追踪的难度也大大增加了,这些hop 也只是知道他们正常工作必须知道的信息而已,除此之外什么也不知道!
例如有三个hop :h1,h2,h3. 用户首先连到h1,然后h1连接到h2, h2连接到h3,h3最终连接到目标网站服务器上。在这一过程中,h1知道用户的真实IP,h2知道它从h1接收用户数据以及要把数据送到h3,h3知道用户想干什么(HTTP)或者用户要去哪里(HTTPS ) ,除此之外这些hop 不应该知道其他任何有关用户的信息,这样的话即使三个hop 中有一个是攻击者的蜜罐,用户身份也不会暴露(不过如果三个hop 都是蜜罐,用户的身份还是会暴露的,但当三个hop分别位于三个不同的国家时,这种可能性很小 )还有就是” 藏叶于林” 了,如果前面提到的三个hop 是某人专用的,那么一旦某个hop 被攻破(尤其是h1或h3),那么那人被逆向追踪的可能性非常大;但如果有很多人同时使用那三个hop ,那么老大哥想要找出其中某个具体用户就很困难了 。同样道理,每次连接建立时都应该随机选择hop ,这样老大哥都不知道该如何进行有效的监视(TOR 的策略是每10分钟就重新随机选择三个hop,每次启动TOR 时也是随机选择hop 的 )
最后就是中间人攻击的问题了。为了防止老大哥进行中间人攻击破坏用户匿名,TOR 有着自己的一套基于数字证书的身份认证机制,每个hop 都有一个自签发的数字证书,TOR 客户端在连接建立时会进行严格的身份认证 。
TOR的特点
一个TOR 环路可以被很多人同时使用,说的具体一点,hop 与hop 之间的每个TLS 连接都包括了很多不同用户的TCP 数据流;
TOR 客户端随机选择了入口节点,入口节点随机选择了中间节点,中间节点又随机选择了出口节点 。对,是由精心设计过的算法保证随机选择的,没有规律可循(不过后来发现这算法造成了很搞笑的情景:某一条环路上的三个hop 有很多用户,都塞车了,但另一条环路上的三个hop 用户数少得可怜,所以后来又基于hop 的用户数对算法进行了改进)
TOR 拥有独立于操作系统和浏览器的严格的基于数字证书的身份认证机制。这一点很重要,如果TOR 的身份认证机制和特定的操作系统或浏览器有了关联,那就意味着用户将不得不为了使用TOR 而更换浏览器或操作系统。
TOR绝对不仅仅是个三重代理
TOR 是面向普通人的低延迟匿名系统,这就对TOR 提出了便携性和易用性的额外要求,TOR 必须在保证高匿名的基础上做到用户友好和适合交互应用 。再加上前面所说的一大堆匿名系统的要求和TOR 的特性,不难得出这样的结论:TOR绝对不仅仅是个三重代理!
TOR 官网「2 」上简单介绍了TOR 的原理:TOR 是一个三重代理,TOR 客户端先与目录服务器通信获得全球活动中继节点信息,然后再随机选择三个节点组成circuit (电路),用户流量跳跃这三个节点(hop)之后最终到达目标网站服务器,
每隔10 分钟左右就会再重新选择三个节点以规避流量分析和蜜罐节点 。
TOR 的具体工作机制可远远没有官网上介绍的简单:当用户启动TOR 后,TOR客户端就会在本机PC上运行一个onion proxy,同时开始监听本机的9150端口(Tor Browser 里的Tor 监听端口),所有经过这一端口的流量都会在经过onion proxy 的处理之后进入TOR 电路中。关于端口有必要做一下说明:对于服务器,只要服务器开机,端口就一直存在;但对于本机,只有相应的应用程序试图与远程服务器通过特定端口通信时,端口才会出现,一旦通信结束端口就会立即消失。也就是说,这个9150端口只有在某一应用程序(例如被设置过的浏览器,例如Tor )试图通过它与远程主机通信时才会出现,并不是个物理存在。
不过这会儿还不能传输用户数据呢,在本机上运行onion proxy 只是第一步而已,
然后当然是与存有全球中继节点信息的目录服务器取得联系了 。一开始这一步是明文HTTP通信,有着增加流量指纹的风险,后来Tor 开发者进行了改进,让Tor 客户端第一步先与入口节点通信(当然第一次连接是做不到的,以后的连接都可以这么做了)再与目录服务器通信更新节点信息,全过程都是TLS 的,这样做不仅保证了安全,还避免了单独与目录服务器建立一次性的TLS 连接,提高了效率(因为建立TLS 连接是很消耗资源的,生成随机参数进行密钥交换强加密传输数据都是要进行大量运算的,如果只是为了短暂的一次性连接,那么就有些太浪费了):当完成更新中继节点信息之后,客户端不必切断连接,而是可以直接把原来的TLS 连接「拔出来」再继续组成电路(意思是原来的TLS 连接的参数还可以继续使用,而不用又重新计算生成)得到中继节点信息之后,电路构造过程就正式开始了!
对了,诸位猜一下,Tor 电路会是怎样的呢?会怎样进行构造呢?
「既然是个三重代理……要么是这样一个过程:onion proxy 先将数据加密传送到入口节点,然后入口节点又加密传送到中间节点,中间节点又加密传输到出口节点,在HTTP的情况下这三个节点都能看到明文(一般的代理就是这样的)?」我说,你不觉得这样非常不安全吗?要是其中有哪一个节点被攻破或者是蜜罐,那么你可就呵呵了!还有就是如果不进行特别设置的话,后面两个代理也是知道用户数据流的真实来源的(真实IP),也就是说安全性还是相当于一重代理!那么,Tor 究竟是怎么做的呢?
「哪个节点都不可信,像洋葱一样」这就是Tor 环路的核心思想所在:和普通的TCP 流不同(Tor 工作在TCP 流之上),Tor 协议把通信数据打包为了一个个特殊的cell:一开始建立Tor 电路时,本机上的onion proxy 向入口节点发送create cell 进行TLS handshake,这一过程的身份认证过程是基于数字证书的:Tor 有着自己的一套数字证书系统,每一个洋葱路由(就是节点)都有一个用于签发证书的身份密钥和用于解密用户的电路建立请求以及协商出一个用于后续通信的(使用时间)短暂的密钥。当节点之间进行通信时,这个特制的TLS 协议还会建立短期连接密钥,而且这一密钥会周期性的独立发生变化以最大限度降低密钥泄露带来的风险
那么接下来又会发生什么呢? Tor 电路默认由客户端和三个节点组成,那么我们就来看看在这种情况下Tor电路究竟是怎样建立的吧:
首先是客户端(onion proxy )发送create cell 与入口节点完成handshake,然后客户端向入口节点发送TLS加密数据relaycell……「里面是用户数据吧!发送到入口节点之后,入口节点就进行解密,然后再重新打包并与中间节点建立连接……」「当然不是了!这样的话,入口节点什么都知道了,哪里还有安全性呢?Tor是这么做的:客户端最先发过去的relay cell 1是入口节点与中间节点建立TLS 连接时所需要的参数,接着发过去的relaycell 2是中间节点与出口节点建立TLS 连接时所需要的参数,接下来是只有目标网站和对应端口信息的relay cell 3,在返回表明已成功建立环路的relay cell 4之后才会真正开始发送包含用户信息的relay cell 5.这一过程中relay cell 1被一重加密,到了入口节点之后就被解密,再用来与中间节点完成握手;relay cell 2被两重加密,到了入口节点时第一重加密解除,到了中间节点时第二重加密解除,中间节点可以看到明文,用来与出口节点完成握手; relay cell 3被三重加密,只有出口节点能看到明文,被用来与目标网站建立连接。同样relay cell 5也是三重加密的,只有出口节点能看到明文(HTTP)。「就像洋葱一样」,对,用户数据就像洋葱一样,被层层包裹着,只有到了终点包裹才会解开。在这一过程中,只有入口节点知道用户的真实IP地址,出口节点知道用户的目的地和传输内容(HTTP),Tor 电路的cell里没有其他任何关于用户真实身份的信息(这里不考虑cookie和flash 插件等应用层协议和程序带来的隐私问题(这些也不是Tor 本身能够左右的,Tor 使用的是在传输层之上应用层之下的SOCKS 代理,无法操纵修改上层协议,但这也使得Tor 能成为很多软件的代理,不被应用层协议们所左右),只针对于传输过程而言)
「似乎有哪里不对呢:如果说这几重加密都是预设的参数,那么一是做不到完全随机了(一定要人为去划分入口节点中间节点出口节点才能做到事先内置相应的解密密钥),二是一旦密钥泄露后果就会相当严重的。但如果不是预设参数而是每次连接时都随机协商,那么又该怎么做呢?」
「你说得没错,Tor 电路中的节点们并没有预设参数,而是采取了「半握手」的方法:在diffie-hellman算法的帮助之下,onion proxy 和中间节点通过入口节点的中介交换了参数,然后就能各自算出私钥用于后续通信而不用担心有人监听,入口节点虽然知道这两个参数,但也根本没办法算出私钥来,这是diffie-hellman算法设计时所保证的」。同理也可以与出口节点安全通信,客户端最里面一层的加密只有出口节点能够解开,入口节点和中间节点都看不到只有出口节点才能看到的内容。
那么,Tor 在建立电路时又是怎么选择节点的呢?
借助算法随机选择,没错,但「一次性随机选择三个节点」?错了!Tor 客户端先随机选择一个入口节点,然后入口节点再随机选择一个中间节点,中间节点又随机选择一个出口节点,这样来最大限度实现随机建立电路。
而且Tor 还有一个更特别的地方:很多用户的流量可以被整合到一个TLS 连接里同时传输!看起来就像一个用户一样! 这样一来,匿名程度更高了,但很多时候又会带来一件麻烦事:很多用户的来自同一个IP的大量流量都同时指向同一个网站(例如google),看上去非常像是DoS (拒绝服务)攻击,此时就会触发网站的防御机制,网站会要求用户输入验证码,非常烦人。
Tor与Deep Web
为什么只有通过Tor 才能来到deep web?为什么deep web的服务器真实IP无法被访问者得知呢?
咱们还是先从用户访问网站的一般流程看起吧:首先,用户在浏览器地址栏中输入URL ,然后回车;紧接着域名解析就开始了,浏览器通过查询从DNS服务器得知目标网站的真实IP地址,然后开始发起连接……
打住!既然deep web的服务器的真实IP地址是被隐藏的,那么有一点马上就可以被确认了:这个世界上所有的DNS 服务器都不知道deep web服务器(又名hiddenservice )对应域名的真实IP!因为只要有一台DNS 服务器存储了真实IP,那么hidden service就暴露啦!(小声:所以诸位也就不要想着从国际互联网直接访问hidden service啦)” 如果是这样,那么用户又该怎样和hidden service建立连接呢?对了,说起来deep web中网站的域名都蛮奇怪的,例如说这个
http://allyour4nert7pkh.onion/wiki/index.php?title=Main_Page
我知道。onion 是顶级域名,代表着这网站在deep web中,无法从明网中直接访问;但前面那一大堆又是什么?”这要从hidden service的建立开始说了。
在deep web里有一个类似于DNS 服务器的存在:数据库。 客户端要想访问deep web中的网站,首先要与数据库建立连接从而取得相关信息,那么又是什么样的信息呢?
要想在deep web里建立自己的网站,首先要随机选择几个” 介绍点” (introductionpoint ),与之建立电路(也就是说在hidden service和介绍点之间有三个中继节点作为跳板),介绍点不知道hidden service的真实IP;然后hidden service组合起一个描述符,里面包括了公钥和各个介绍点的摘要,然后用私钥签名,最后把描述符上传到前面提到的数据库里(准确叫法是分布式散列表)。这样网站就建立好了!对了,这个网站的域名就是:一个从公钥派生出的16位字符。onion(所以deep web里的网站的网址看起来才那么奇怪)。网址和描述符是一一对应的。
接下来,我们好奇的客户端就上场了:客户端从某个渠道得知了某个hiddenservice 的网址,想要去看一下。那么他该怎么做呢?
首先,他得开启Tor ,还要设置好浏览器代理,接着输入网址,回车。
然后,他通过Tor 电路与数据库建立连接(这里要注意一下,因为始终都不会访问明网,所以第三个跳板节点在这里就是数据库了,接下来建立连接时第三个跳板节点会变成相应的节点),开始查询(对比是否存在和目标网站网址对应的描述符),同时随机选择一个节点作为” 会合点” (rendezvous point)。
OK,查到了!那么,接下来就产生一个随机的一次性rendezvous cookie 作为一次性的secret吧!然后用刚刚得知的公钥加密cookie和会合点IP,再把密文发送给介绍点!” 喂喂,那个会合点是干嘛用的?”“不要急吗,等会儿就讲到了!”
介绍点接到数据之后,就传回给hidden service(当然始终是通过Tor 电路间接传递的)。hidden service用私钥解密一看:哎,有用户来了啊,赶快招待!然后就急忙与会合点建立连接(当然也是经过三次跳板中转的完整Tor 电路),同时把之前的cookie(也就是一次性secret)发送回去。
客户端接到数据,解密一看:哈哈,就是之前的那个cookie,这就意味着我和hidden service之间已经成功建立连接了!那么,现在正式开始通信!最终在客户端和hidden service之间有六个中继节点:客户端入口节点,客户端中间节点,会合点(原先出口节点的位置),hidden service出口节点,hidden service中间节点,hidden service入口节点。从头到尾客户端和hidden service的通信都是被TLS 强加密的(尽管浏览器不这么认为,在访问deep web网站的时候浏览器显示客户端和网站之间的连接是未加密的,但实际上刚好相反),Tor 电路本身的证书认证机制也防止了中间人攻击。这样说来,hidden service本身再去搞一个证书支持TLS 连接(让浏览器认为建立了加密连接)其实没有意义了。