真正的匿名者,TOR 的原理

真正的匿名者,TOR 的原理(1 )

              —-到底什么才是匿名?

  先说一下我为什么又开了一个系列:美国司法局(背后八成是NSA )对TOR下手了「0 」。TOR 有难,我怎能袖手旁观?是有坏人在使用TOR ,但TOR 所保护的,更多是好人!像天朝这种a发条微博就” 分裂国家” ,转个贴就被” 寻衅滋事” 的狗屁国家,TOR 绝对是每个有志于改变这糟糕的现状的翻墙党的必备装备!在这一系列里,我就仔细聊聊究竟TOR 是如何保护着匿名和隐私保护这两大基本人权的吧(包括TOR Browser 的特别之处)。
  我一直是大名鼎鼎的TOR 「1 」(The Onion Router,洋葱路由)的用户之一,也写了一堆关于TOR 的科普「2 」,但一直都没有具体的分析过TOR 的原理,只是一直在说只有TOR 和I2P 「3 」才是真正的匿名软件。鉴于I2P 的用户体验实在是很糟糕(那速度简直不是人能忍受的),TOR 可以说是安全发言的唯一选择了。
  我知道,很多翻墙党都只注重一个速度,其他几乎不考虑。我也可以理解,像youtube 上的高清视频这种流媒体对于网络带宽的要求是很高的,而TOR 根本就满足不了这种要求(这是由TOR 的原理所决定的)。但除此之外,TOR 完全能够满足诸位的日常需要。对于前置代理+TOR的情况,速度主要由前置代理决定,前置代理本身连接速度不慢的话,TOR 速度也不会慢!
  特别是对于一些和我一样喜欢黑共匪政府的同道们来说,如果你只考虑一个速度,那么,你想死的有多快?

  关于高清视频,也有解决方案:要么装上两个浏览器,一个走TOR 环路,一个随便找个速度快的一重代理,发言时用走TOR 环路的浏览器,看视频时用另一个浏览器,说实在的这一点也不麻烦啊;要么借助privoxy 的帮助,对于不同网站设置不同代理,具体看这里「4 」,也可以解决问题。  我想这下应该没有理由拒绝TOR 了!  在分析TOR 原理之前,先搞清楚一个概念:匿名。
  究竟怎样才叫匿名呢?
  有人说,我注册账号时取了假名字,其他人不知道这个账号是我的,我也没有透露任何能关联到我的真实身份的信息,我是匿名的。
  错!这可不叫匿名,这叫做假名,对于假名用户,技术上很容易就能进行追踪。不过假名其实是匿名的基础,假名是匿名的社会工程学部分「5 」,还有技术部分呢!

  有人说,我挂着代理,隐藏了自己的真实IP,这就是匿名。

  错!绝大部分翻墙党都是挂着一重代理来这的,有一些甚至只是改了hosts就来了,完全没有匿名性。一重代理只能说是一定程度上提升了匿名性而已。

  那么怎样才叫(技术上的)匿名呢?

  先构建一个模型(大部分翻墙党都符合这个模型):来到这里要从本地PC开始,经过交换机(平时很多人说的” 家庭路由器” 真正的名字叫交换机,真正的路由器不是个人能买得起的(PS:共匪权贵除外)),网关(如果是局域网),N 个路由器,GFW ,代理服务器,然后又是N 个路由器,最终到达google服务器。如果是改hosts 来的,那么就没有代理服务器这一步了。

  这其中只要数据是被强加密的,那些交换机路由器网关以及GFW 就都不是问题。当然,在代理服务器之前的交换机网关路由器以及GFW 是知道你的真实IP的(交换机还知道你的真实MAC 地址呢),但在强加密的情况下,他们不知道你干了些什么(” 不知道你具体干了什么” 不等于” 不知道你在翻墙” ,ISP 和GFW想要知道你在翻墙不是一件难事「6 」);

  代理服务器负责处理数据包,对于诸位而言,他是服务器;对于google服务器而言,他是客户端。又当服务器又当客户端,这就是代理服务器的特别之处。代理服务器之后的路由器以及最终的google服务器看到的都是代理服务器的IP了,用户的真实IP就被隐藏起来了,所以说” 有一定的匿名性。”但问题在于代理服务器知道你的真实IP和你干了些什么(HTTP),所以一旦代理服务器出事,后果不堪设想,而一个合格的匿名系统绝对不能完全依赖于某一环节的安全性,不然这一环节出问题就意味着匿名的失效,没有人敢用这么脆
弱的系统保护自己的!而且说实在的流量分析也不是什么新的领域,还有随着云计算的发展而越来
越有效的数据挖掘(关联分析),一重代理完全无法应对这两者(事实上单纯的TOR 也无法应对数据挖掘,所以才有了TOR browser ,而且仅仅使用TOR 是无法规避很多风险的,这点TOR 官网上也有说明「7 」)。
  说到这里,有人又会这么想了:一重代理做不到匿名,那么自己想办法组合二重代理甚至更多重代理不是可以解决问题了吗?要知道TOR 不就是个三重代理吗?「8 」喂喂,事情没有这么简单好吧?首先,自己想办法组合的多重代理未必真的是多重代理:这话听起来很奇怪,但是请想象一下,假设代理服务器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 「9 」,每次启动TOR 时也是随机选择hop 的)
  最后就是中间人攻击的问题了。为了防止老大哥进行中间人攻击破坏用户匿名,TOR 有着自己的一套基于数字证书的身份认证机制「10」,每个hop 都有一个自签发的数字证书,TOR 客户端在连接建立时会进行严格的身份认证。

  补充说明:这套证书系统是TOR 独有的,跟操作系统和浏览器的证书系统完全没有关联,所以GFW 即使利用流氓证书CNNIC ROOT进行中间人攻击也无法影响到TOR ,但TOR 出口节点到目标网站服务器这段路还是需要防备中间人攻击的,所以请大家还是把这些天朝证书轰走吧「11」

  大家应该能看出来了:TOR 对抗的是某一国家的老大哥而不是全球性的老大哥(幸好现在也根本没有全球性的老大哥,不过说实在的NSA 有这个趋势),而且TOR 用户越多,TOR 的匿名程度就越高。

  相对于TOR 之前的匿名系统,TOR 有三点最为特别:
1 ,一个TOR 环路可以被很多人同时使用,说的具体一点,hop 与hop 之间的每个TLS 连接都包括了很多不同用户的TCP 数据流;
2 ,TOR 客户端随机选择了入口节点,入口节点随机选择了中间节点,中间节点又随机选择了出口节点。对,是由精心设计过的算法保证随机选择的,没有规律可循(不过后来发现这算法造成了很搞笑的情景:某一条环路上的三个hop 有很多用户,都塞车了,但另一条环路上的三个hop 用户数少得可怜,所以后来又基于hop 的用户数对算法进行了改进「12」)3 ,TOR 拥有独立于操作系统和浏览器的严格的基于数字证书的身份认证机制。这一点很重要,如果TOR 的身份认证机制和特定的操作系统或浏览器有了关联,那就意味着用户将不得不为了使用TOR 而更换浏览器或操作系统。

  TOR 是面向普通人的低延迟匿名系统,这就对TOR 提出了便携性和易用性的额外要求,TOR 必须在保证高匿名的基础上做到用户友好和适合交互应用。再加上前面所说的一大堆匿名系统的要求和TOR 的特性,不难得出这样的结论:TOR绝对不仅仅是个三重代理!

  那么这个可爱的洋葱头究竟有着什么样的结构呢?

  真正的匿名者,TOR 的原理(2 )

  ————The Green Onions,Go!

  话说上次「1 」咱们聊了聊到底什么才是匿名以及匿名系统需要做到什么,这回就一起来看看这个可爱的洋葱头究竟是怎样保护  我们的吧!  TOR 是The Onion Router的缩写,直译就是洋葱路由。那为什么会叫「洋葱路由」呢? 
  TOR 官网「2 」上简单介绍了TOR 的原理:TOR 是一个三重代理,TOR 客户端先与目录服务器通信获得全球活动中继节点信息,然后再随机选择三个节点组成circuit (电路),用户流量跳跃这三个节点(hop)之后最终到达目标网站服务器,每隔10 分钟左右就会再重新选择三个节点以规避流量分析和蜜罐节点。
  看到这里,有些人就会开始这么说了:「看起来除了每隔10分钟左右变换节点之外,其他与任意三个代理组成的三重代理也没什么区别啊。」
  真的是这样的吗?
  TOR 的具体工作机制可远远没有官网上介绍的简单:当用户启动TOR 后,TOR客户端就会在本机PC上运行一个onion proxy 「3 」,同时开始监听本机的9150端口(Tor Browser 里的Tor 监听端口),所有经过这一端口的流量都会在经过onion proxy 的处理之后进入TOR 电路中。关于端口有必要做一下说明:对于服务器,只要服务器开机,端口就一直存在;但对于本机,只有相应的应用程序试图与远程服务器通过特定端口通信时,端口才会出现,一旦通信结束端口就会立即消失。也就是说,这个9150端口只有在某一应用程序(例如被设置过的浏览器,例如Tor )试图通过它与远程主机通信时才会出现,并不是个物理存在。
  不过这会儿还不能传输用户数据呢,在本机上运行onion proxy 只是第一步而已,然后当然是与存有全球中继节点信息的目录服务器取得联系了。一开始这一步是明文HTTP通信,有着增加流量指纹的风险,后来Tor 开发者进行了改进,让Tor 客户端第一步先与入口节点通信(当然第一次连接是做不到的,以后的连接都可以这么做了)再与目录服务器通信更新节点信息,全过程都是TLS 「4 」的,这样做不仅保证了安全,还避免了单独与目录服务器建立一次性的TLS 连接,提高了效率(因为建立TLS 连接是很消耗资源的,生成随机参数进行密钥交换强加密传输数据都是要进行大量运算的,如果只是为了短暂的一次性连接,那么就有些太浪费了):当完成更新中继节点信息之后,客户端不必切断连接,而是可以直接把原来的TLS 连接「拔出来」再继续组成电路(意思是原来的TLS 连接的参数还可以继续使用,而不用又重新计算生成)「3 」得到中继节点信息之后,电路构造过程就正式开始了!
对了,诸位猜一下,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算法「5 」的帮助之下,onion proxy 和中间节点通过入口节点的中介交换了参数,然后就能各自算出私钥用于后续通信而不用担心有人监听,入口节点虽然知道这两个参数,但也根本没办法算出私钥来,这是diffie-hellman算法设计时所保证的」。同理也可以与出口节点安全通信,客户端最里面一层的加密只有出口节点能够解开,入口节点和中间节点都看不到只有出口节点才能看到的内容。
  那么,Tor 在建立电路时又是怎么选择节点的呢?
  借助算法随机选择,没错,但「一次性随机选择三个节点」?错了!
  Tor 客户端先随机选择一个入口节点,然后入口节点再随机选择一个中间节点,中间节点又随机选择一个出口节点,这样来最大限度实现随机建立电路。而且Tor 还有一个更特别的地方:很多用户的流量可以被整合到一个TLS 连接里同时传输!看起来就像一个用户一样!「3 」这样一来,匿名程度更高了,但很多时候又会带来一件麻烦事:很多用户的来自同一个IP的大量流量都同时指向同一个网站(例如google),看上去非常像是DoS (拒绝服务)攻击,此时就会触发网站的防御机制,网站会要求用户输入验证码,非常烦人。

  「可爱的洋葱头很努力啊。」现在谁还会说Tor 只是一个三重代理呢?

  真正的匿名者,TOR 的原理(3 )

  ——deep web的秘密!

  话说咱们英勇的Tor 团队设计Tor 出来可不单单是为了帮PC用户们保持匿名的:听说过deep web「1 」吗?只有使用Tor 来到这里的人才能看到deep web的真面目,这里面有军火商,有毒品交易,有盗版书籍和游戏,还有其他在国际互联网上找不到的惊喜等着你!所有的普通网站,访问者都知道网站的真实IP地址,但deep web却不是这样!

  为什么只有通过Tor 才能来到deep web?为什么deep web的服务器真实IP无法被访问者得知呢?

  咱们还是先从用户访问网站的一般流程看起吧:首先,用户在浏览器地址栏中输入URL ,然后回车;紧接着域名解析「2 」就开始了,浏览器通过查询从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 电路本身的证书认证机制「3 」也防止了中间人攻击「4 」。这样说来,hidden service本身再去搞一个证书支持TLS 连接(让浏览器认为建立了加密连接)其实没有意义了。

  ” 那么就此为止了吗?””当然没有,要知道NSA 和FBI 还有GCHQ们看Tor 不爽早就不是一天两天了,下次一起看看英勇的Tor 团队们是怎样对付各种攻击的吧!对了,顺便贴一下流程图,来源是「5 」,原图是英文,不过翻墙党看懂应该没有问题:)”