Tor The Second-Generation Onion Router学习笔记
前半部分是看油管上一些视频对Tor的初步认识,后面是根据论文记得一些笔记,基本上是直接翻译,添加了一点术语解释。
1.Tor简介
Tor是一种基于电路的低延迟匿名通信服务,2代Tor通过添加完美的前向匿名、拥塞控制、目录服务器、完整性检查、可配置的退出策略以及通过聚合点实现位置隐藏服务的实用设计来解决原始设计中的限制。
Tor设计目标:①以较大的可变的延迟来实现匿名化;
②易于分析,但用户必须信任匿名代理;
③任何结点都可以读取用户流量;
④广播响应来隐藏发起者。
Tor工作原理:Alice->Bob
①Alice的Tor客户端从目录服务器中获得一系列的Tor结点;
②Alice的Tor客户端选择一条随机的到目的服务器的路径,这其中Alice到Tor结点和Tor结点之间 的消息传递都是加密的,Tor结点到Bob的一段是非加密的;
③若之后Alice又对其他节点进行访问,其客户端会根据以上流程进行传输。
Tor通过三层加密来确保信息安全,Tor网络中的结点均是来自世界各地的志愿者结点,并且,网络中的结点越多,Tor的匿名性就越强。
传统的加密方式是围绕信息本身进行加密,但是有时我们甚至不想让人知道自己做出了发信息这一行为,也就是实现完全匿名。
Tor的一次信息传递需要经过三跳,经过三个中间结点。
Tor中的每个结点都知道自己的前驱结点和后继结点,没有一个结点对整个网络一无所知。
2.Tor原理简述
Tor客户端发出的信息经过三次加密,分别对应密钥K1、K2、K3,message被层层包裹在内部,形状很像洋葱。
在上图的传输过程中,Node2无需也不会得知消息的发送者是谁,Node2只需要知道这是一条应该被转发给Node3的信息,将其的K2加密层去除之后,Node2将包转发给Node3.
上述的这种特性使得即使有人成功地攻击了某个路由结点,那么攻击者也无法获得整个路径的信息,从而起到了对个人信息的保护作用。
这种传输方式的坏处在于势必会影响信息的传播速度,并且很依赖志愿者结点的数量以及链路的质量。
假设对图中的①②③④分别进行嗅探,会出现的情况:
①有人在访问Tor网络,在干什么不知道;
②/③完全不可读的加密信息;
④一些访问行为,但是这些行为的发起者是谁不得而知。
上述过程中,①②③都是加密的。
但是如果我们同时监控了①④两处的流量,或许可以从中分析出一些信息,这也是Tor研究的一个重要方向——流量分析。一种方式是以大量的、带有时间戳的流量访问入口结点,并且在出口结点进行监听,分析其中的关联关系。
需要注意的是,和上图所示的洋葱结构的直观感觉不同,Tor Node在进行解密时不会对message本身的大小进行改变,这也是Tor设计的巧妙之处之一。因此整个Tor网络中的任意结点之间的包在大小和格式上都类似于其他的包,起到了伪装作用。
3.Tor设计
Tor网络是一个覆盖网络;每个洋葱路由器(OR)作为一个普通的用户级线程进行,没有任何特权。每个洋葱路由器和其他的洋葱路由器都保持一个TLS连接,每个用户运行一个成为洋葱代理(OP)的本地软件来从目录服务器获取目录,建立跨网络的电路,并且处理来自用户应用程序的连接。这些洋葱代理接受TCP流并在电路中对其进行多路复用,另一端的洋葱路由器连接到TCP流的目的地并中继数据。
(术语解释:
①覆盖网络Overlay Network:简单来说就是应用层网络,面向应用层,不考虑或者很少考虑网络层和物理层的问题,允许对没有IP地址表示的目的主机路由信息。
②安全传输层协议TLS:用于在两个通信应用程序之间提供保密性和数据完整性,该协议由两层组成:TLS记录协议和TLS握手协议。TLS协议采用主从式架构模型,在两个应用程序之间透过网络创建安全的连接,防止在交换数据时受到窃听和篡改。TLS协议不能直接地归于某个单独的通信层,TLS运作基于一些提供可靠通信的传输层协议(例如TCP),这意味着其在传输层之上;同时它也向更高层的通信协议提供加密服务,这项工作在OSI中通常属于表示层协议。但是应用程序通常将TLS协议作为传输层协议对待。)
每个OR维护一个长期身份密钥和一个短期洋葱密钥,身份密钥用于签名TLS证书、签名OR的路由器描述符,以及通过目录服务器签名目录;洋葱密钥用于解密用户建立电路和协商临时密钥时的请求,在OR之间进行通信时,TLS协议还会建立一个短期链路密钥,短期密钥会独立、周期性地轮换,来限制密钥泄漏的影响。
3.1洋葱单元
OR通过带有临时密钥的TLS连接相互通信,并且与用户的OP通信,使用TLS以完美的前向保密方式隐藏链路上的数据,并且防止攻击者修改线路上的数据或者冒充洋葱路由器。
(术语解释:前向保密:也称完美前向安全perfect forward secrecy,是密码学中通讯协议的安全属性,指长期使用的主密钥泄漏不会导致过去的会话密钥泄漏。通俗地说,假设一个长期密钥泄漏了,虽然以后的行为的保密性无法确保,但是之前的行为的安全性是可以保证的,敌手获得了当前你的密钥,但是他无法成功伪造一个过去的签名。一般的实现方法是固定公钥,而密钥随着时间更新,这个更新过程是单向无循环的,这就可以保证历史密钥的安全性)
Tor流量由固定为512字节的单元组成,每个单元都由头部和负载组成。头部包括一个电路标识符circID(指定单元引用哪个电路,多个电路可以通过单个TLS电路进行多路复用)、CMD(描述如何处理单元的负载)。电路标识符是链接特定的:每个电路在其所遍历的每个OP-OR或OR-OR链接上都有一个不同的电路标识符。根据单元头的CMD,单元要么是控制单元(总是由接受他们的结点进行解释)要么是中继单元(携带端到端流数据)。CMD的种类有:padding、创建电路、设置新电路、摧毁电路。
中继单元(上图)在单元头之后有一个附加的中继头,包含一个流标识符(用于多个流在电路上复用时的区分)、用于完整性检查的端到端的校验和、中继有效负载的长度Len、一个中继命令CMD。中继单元在电路上传输时,使用128位AES密码在计数器模式下生成密码流,将中继头的全部内容和中继单元负载一起加密和解密。
(术语解释:AES加密算法:高级加密标准AES,是最常见的对称加密算法,加密和解密需要使用相同的密钥。作为分组密码,AES将明文分成长度相等的组,每次加密一组数据,直到整个明文加密完成。AES规定分组长度只能为128位,密钥的长度有128位、192位或256位几种,常用的是AES-128。具体过程再做笔记吧)
3.2电路和流
洋葱路由最初为每个TCP流建立一个电路,由于公钥加密和网络延迟,这个工作需要耗费大约十分之一秒的时间。在Tor中,每个电路都可以被多个TCP流共享,为了避免延迟,用户预先构造电路,若之前的电路已经被使用,用户的洋葱代理会定期建立一个新电路,并对不在有任何开放流的旧电路进行过期处理。OPs每分钟建立一次新电路,因此即使是大量用户也会花费微不足道的时间来构建电路,通过给定出口的结点,有限数量的请求可以相互连接。此外,由于电路是在后台构建的,OPs在创建电路失败时可以及时恢复,而不是延迟流,这样会损害用户体验。
3.2.1电路的创建
①名为Alice的OP为了创建一个新的电路,发送一个数据包到她选择路径的第一个结点(Bob),这个数据包的circID是新的,没有在其与Bob的连接中使用的。创建数据包的有效负载中包含了Diffie-Hellman握手g^x1的前半部分;
②Bob的响应是创建了包含DH握手后半部分的数据包,以及协商之后的key值。这时,电路就已经建立起来了(在这一步中,Bob证明是他收到了g^x,并且选择了y);
③为了进一步扩展电路,Alice发送中继扩展单元给Bob,指定下一个OR的地址(Carol),并为其加密了g^x2;
④Bob将这个半握手复制到一个数据包内,然后传递给Carol,使电路向下延伸(Bob选择了一个新的circID),这里Alice不需要知道Bob和Carol之间的circID,将Alice和Carol联系在一起的只有Bob;
⑤Carol用创建数据包相应电路扩展请求,Bob将其有效负载封装到中继扩展数据包中,传回Alice,告知Alice电路已经扩展到Carol(现在电路扩展到Carol,Alice和Carol共享一个key K2=g^x2y2,若还需扩展电路,Alice会重复上述的过程);
3.2.2中继数据包
Alice建立电路之后(Alice和电路上的每个OR都共享密钥),她就可以发送中继数据包。每个中继数据包都有一个流ID来表示其属于哪个流。在接收到一个中继数据包之后,OR根据流ID查找相应的电路,并用该电路的会话密钥来解密中继头和负载。若中继数据包是由Alice发出的,OR会检查解密之后的流是否被识别出来,它要么是对应于给定电路的这个OR处的一个打开的流,要么是一个控制数据包(streamID zero)。如果OR识别出了streamID,它会接受这个中继数据包并且按下面的流程处理,否则,OR会查找电路中下一跳的circID和OR,将circID酌情替换,并将解密的中继数据包发送给下一个OR(若电路末端的OR接收到一个无法识别的中继数据包,则认为发生了错误,该中继数据包将被丢弃)。
OP对于传入的中继数据包:使用电路上每个OR共享的会话密钥迭代地打开中继头和负载,若OP在任何阶段接收到了中继数据包,那么它必定起源于最近刚刚解除加密的OR。
为了构建一个定位到目标OR的中继数据包,Alice需要用到达该OR的每一跳的对称密钥迭代加密数据包。在这个过程中,每一步都将streamID加密为不同的值,因此只有在目标OR处,才会是一个有意义的值。这种有漏洞的(能随时下车的)网络拓扑设计允许Alice在单一电路的不同OR退出,Alice可能会因为退出策略选择不同的退出点,或者让OR不知道两个流来自同一个人。
为了拆除一个电路,Alice发送一个破坏数据包,电路中的每个OR接收到之后会关闭该电路上的所有流,并向前传递一个新的破坏数据包。正如电路是逐步建立起来的,它也可以被逐步拆除:Alice发送一个中继截断数据包到电路上的每个OR,这个OR接下来会发送一个破环数据包,并通过中继截断数据包来确认。
Alice可以将电路扩展到不同的结点,而不需要向中间结点发出信号来表示她已经改变了电路。若电路上一个结点出现了故障,它也可以向Alice发送一个中继截断数据包,这样,“断开一个结点,观察哪条电路断开”的攻击方式就被削弱了。
3.2.3打开和关闭数据流
当Alice的应用程序需要一个到给定地址和端口的TCP连接时,它请求OP通过socks建立连接,OP选择一条新的电路(或者根据要求建立一条),并在电路上选择一个合适的OR作为退出结点(这个结点通常是最后一个结点,但是可能由于退出策略冲突而选择其他结点)。OP使用新的随机身份标识符向出口结点发送中继开始单元来打开流。出口结点连接到主机之后,它会向OP回复中继连接单元,OP收到后发送socks回复通知应用程序连接成功。之后,OP接受来自应用程序TCP流的数据,将其打包到中继数据单元中,将这些数据单元沿电路发送到之前建立连接的OR。
Tor数据流的关闭类似于TCP流:对正常操作使用两步握手,对错误操作使用一步握手,若流异常关闭,流上相邻的结点会简单地发送中继拆除单元;若流正常关闭,结点向电路发送一个中继终止单元,当另一方发送回自己的中继中断单元时,流就可以关闭。因为所有的中继单元都使用分层加密,所以只有目的地结点知道这个中继单元是一个关闭流的请求。这两步握手允许Tor支持基于TCP的使用半关闭连接的应用程序。
3.2.4流的完整性检查
旧的洋葱路由设计使用了没有完整性检查的流密码,其流量很容易受到可延展性攻击(尽管攻击者不能解密数据包,但是对加密数据的任何更改都会对离开网络的数据产生相应的更改),这个弱点允许对手将填充数据包更改为破环数据包;或者将中继开始单元中的目的地址修改为对手的网络服务器,等等。任何能够猜到加密内容的对手都可能在流中引入这种破坏。
Tor在其链路上使用了TLS,其完整性检查保护数据不被外部对手修改,但是,解决内部可塑性攻击则更为复杂(?)
我们可以通过包含哈希值或使用一些验证密码模式来在每一跳对中继单元进行完整性检查,但是这存在一些问题:首先,这些方式都会增加每一跳的消息扩展开销,因此我们要么泄漏路径长度,要么就要将所有的中继单元都填充到最大长度,这会造成字节浪费;其次,这些解决方案只能对来自ALice的流量进行验证,由于电路上的OR不知道其他OR的会话密钥,因此OR不能为中间跳产生合适的哈希值(这里可能是说,对电路上所有OR的会话密钥都知道的只有电路的建立者ALice);第三,我们已经承认我们的设计容易受到端到端的定时攻击,那么标记电路内执行的攻击不会给攻击者提供额外的信息(这里可能说的是前面提到的大量带时间戳的流量分析攻击)。
考虑到上面的情况,Tor仅在每条电路的边缘进行完整性检查(之前提到,Tor电路是类似于漏管的电路,因此电路的边缘可以是电路上的每个OR)。
当Alice在和新一跳协商密钥时,他们各自用该密钥的导数初始化一个SHA-1摘要,从而从只有他们俩知道的随机性开始。从这时起,他们每个都递增地将他们创建的所有中继单元的内容添加到SHA-1摘要中,并在每个中继单元中包含当前摘要的前四个字节,每个还保留一个SHA-1的接收数据摘要,来验证接收到的哈希是正确的。
为了达到之前提到的修改或删除(拦截)电路中的一个中继数据单元,攻击者必须能够推断出当前的摘要状态(这取决于Alice和Bob之间的所有流量,从他们一开始协商的密钥开始)。在对SHA-1的攻击中,对手可以逐渐增加到一个哈希值来产生一个新的有效哈希值,但是这种攻击是无效的,因为所有的哈希值都是在整个电路中端到端加密的。对手猜出有效哈希的概率是低到可以接受的,若Alice或Bob收到一个坏的哈希值,那么电路就会被及时关闭。
3.2.5速率限制和公平
Tor服务器使用令牌桶方法来强制传入字节的长期平均速率,同时仍然允许超过允许带宽的短期突发。因为Tor协议生成的出站字节和进入字节大致相同,因此只需要限制一个就行了。
(术语解释:令牌桶算法:一种常用的流量测量方法,令牌桶指的是网络设备的内部存储池,而令牌则是以给定速率填充桶的虚拟信息包。令牌桶有预设的容量,满时,多余的令牌溢出。需要注意的是,令牌桶中存放的不是消息报文,而是令牌。单纯的令牌桶只是流量测量方法,对流量进行过滤、丢弃等其他操作是由其他功能完成的。)
3.2.6拥塞控制
尽管有了速率限制策略,我们还是要考虑拥塞的情况,无论有意还是无意,若有足够多的用户为他们的电路选择相同的OR-to-OR连接,该连接很快就会达到饱和。例如,攻击者可以通过Tor网络向他运行的网络服务器发送一个大文件,然后在电路的网络服务器段拒绝读取,若没有拥塞控制机制,这些数据包会通过整个网络传播回来。下面是我们的策略:
①电路级拥塞控制:为了控制电路带宽使用,每个OR跟踪两个窗口:打包窗口跟踪OR被允许打包多少中继数据单元(从传入的TCP流)以传输回OP;传递窗口跟踪它愿意将多少中继数据单元传递到网络外的TCP流。每个窗口都被初始化,在数据单元被打包或交付时,相应的窗口将减小。当一个OR接收到足够的数据单元时,其向OP发送中继发送单元,流标识符为0.当OR接受到流标识符为0的中继发送单元时,它增加其打包窗口。若封装窗口到达0,OR停止从TCP连接中读取相应电路上的所有流,并不再发送更多的中继数据单元,直到收到一个中继发送单元。OP的行为和OR是相同的,除此之外OP还必须跟踪电路中的每个OR的封装和交付窗口,若封装串口到达0,它将停止从发送给该OR的流中读取数据。
②流级拥塞控制:OP和OR通过发送单元实现对电路中的各个流的端到端流控制。每个流以一个打包窗口开始,并在接受中继发送单元时将该窗口增加一个固定值。流级拥塞控制还必须检查数据是否已成功刷新到TCP流,而不是总是在到达足够的单元后返回中继发送单元,它只在等在刷新的字节数低于某个阈值时才发送中继发送单元。
3.2.7集合点和隐蔽服务
集合点是Tor网络中位置隐藏服务(也称响应者匿名)的一个组成部分。位置隐藏服务允许Bob提供TCP服务而不透露其IP地址,这种类型的匿名保护了分布式Dos攻击(攻击者被迫攻击Tor网络),因为他们不知道Bob的IP地址。
位置隐蔽服务的设计目标:
①访问控制:Bob需要一种方法来过滤传入的请求,这样攻击者就不能仅仅通过和Bob建立许多无意义的连接来攻击他;
②健壮:Bob应该能维持一个长期的假名身份,即使在出现路由器故障的情况下;
③防污迹:一个社会攻击者如果提供了一个非法的或者声名狼藉的位置隐藏服务,就不应该通过让观察者相信是路由器创建了这个服务来陷害一个约会路由器(这没看懂什么意思);
④应用程序透明:虽然我们要求用户运行特殊的软件来访问位置隐藏的服务器,但是我们不能要求他们修改他们的应用程序。
我们允许Bob将几个洋葱路由器作为联络点来为他提供位置隐藏,他可以在任何具有经过身份验证的健壮高效的键值查找系统上坐到这一点。客户端Alice选择OR作为她的集合点,她连接到Bob的一个介绍点,告知Bob她的集合点,接着等待Bob来自己的集合点连接。这种额外的间接层可以帮助Bob的引入点避免与直接提供不受欢迎的文件相关的问题(类似于隔离的作用?)。还允许Bob相应一些请求,并忽略其他的请求。
4.其他设计决定
4.1资源管理和拒绝服务
将Tor作为公共服务给网络带来了许多拒绝服务攻击的机会,虽然有了流量控制和速率限制策略来阻止用户消耗超过路由器所愿意提供的带宽,但用户仍然有机会消耗超出其公平份额的网络资源,这可能会导致网络中的其他人无法使用。
(术语解释:拒绝服务攻击:攻击者想让目标机器停止服务,是常用的攻击手段之一。比较典型的就是针对网络带宽进行的消耗性攻击。几种拒绝服务攻击实际上都是想实现两种效果:①迫使服务器的缓冲区满,使其无法再接受新的请求;②使用IP欺骗,迫使服务器将非法用户的连接复位,影响合法用户的正常连接)
首先,有几种消耗cpu的拒绝服务攻击,攻击者使用这种攻击迫使OR执行昂贵的密码操作。类似地,攻击者可以伪造TLS握手的起始,迫使OR执行TLS握手的另一半,而攻击者实际上没有计算成本。
我们还没有实现对这些攻击的任何防御,但是有几种可能的方法:首先,OR可以要求客户端在开始新的TLS握手或接收创建单元时进行令牌验证,只要这些令牌易于验证并且生成的计算成本较高,就可以达到对攻击的限制目的。此外,OR还可以限制它们接受创建单元和TLS连接的速率,但是这种速率限制可能会让攻击者在其他用户创建新电路时减慢其速度。
4.2退出策略和滥用
每个洋葱路由器的退出策略都描述了路由器将连接到哪些外部地址和端口。OR也可能能够对客户端进行身份验证防止退出滥用而不伤害匿名。
4.3目录服务器
Tor使用一小群冗余的、知名的OR来跟踪网络拓扑和结点状态的变化,包括密钥和退出策略,每个这样的目录服务器作为一个HTTP服务器,因此客户端可以获取当前的网络状态和服务器列表,OR也可以将其状态信息上传到目录服务器。OR定期向每个目录服务器发布其状态的签名,目录服务器将这些信息和他们自己的网络视图结合起来,生成整个网络状态的签名描述(目录)。
5.攻击和防御
5.1被动攻击
①观察用户流量模式:观察用户连接不会显示其目的地或数据,但是可以得到流量模式,通过用户连接模式进行分析需要进一步的处理,因为多个应用程序流可能在同一个电路上串联运行。
②观察用户内容:虽然用户端内容是加密的,但是和应答者之间的连接可能不会加密,实际上,应答者的网站本身可能就是敌对的。虽然过滤内容不是洋葱路由的主要目标,Tor可以直接使用Privoxy和相关的过滤服务来匿名化应用数据流。
③选择可区别性:我们允许客户端选择配置选项。例如,有的用户可能相对于可追溯性,更关注请求链接性,因此这些客户可能会更加频繁地更换电路,这部分用户可能会因此显得与众不同而失去更多的匿名性。
④端到端时间相关性:Tor只能最低限度地隐藏这种相关性。攻击者观察在发起者和响应者的流量模式将能够以高概率确认通信。目前最有效的防止此类确认的保护措施是隐藏洋葱代理和第一个Tor结点之间的连接,可以在Tor结点上或是在防火墙后运行OP。这种方法需要观察者将来自洋葱路由器的流量和经过洋葱路由器的流量分开,全局的观察者可以做到这一点。
⑤端到端大小相关性:简单的包计数也可以有效地确认流的端点。然而,即使没有填充,我们也有一些有限的保护:漏管模型意味着不同数量的数据包可能会进入电路的一个端点(OR),而不是其他的OR。
⑥用户指纹:这种攻击通过尝试分析用户在访问浏览器时的习惯来进行分析攻击。
5.2主动攻击
①妥协的密钥:得知TLS会话密钥的攻击者可以看到该连接上的每个电路的控制单元和加密的中继单元;得知电路会话密钥可以让他解开加密的一层。一个攻击者如果得知了某个OR的TLS私钥,就可以在TLS私钥的生命周期内模仿这个OR,但他还必须得知洋葱密钥来解密创建单元,并且,由于完全的前向保密,攻击者无法在不损害其会话密钥的情况下劫持已经建立的电路。周期性的变换密钥会限制这些攻击的机会窗口。另一方面,攻击者一旦掌握了结点的身份密钥,就可以向目录服务器发送新的伪造描述符来无限期地替换该结点。
②迭代妥协:一个可以危及OR的对手可以沿着危及结点的回路行进,直到他到达终点。然而,除非对手能够在电路的生命周期内完成此次攻击,否则OR将在攻击完成之前丢弃必要的信息。
③运行一个服务器:对手可以运行一个服务器并诱导用户连接到他们的服务器上(可能是通过投放广告的形式),那么对手现在就掌握了链接的一端。
④运行一个洋葱代理:终端用户几乎总是运行他们自己的本地洋葱代理,然而在某些设置中,代理可能需要远程运行,损害一个洋葱代理将损害将来所有通过它的连接(没看懂)。
⑤攻击未被观察到的结点:一个只能监视Tor网络的观察者可以通过攻击没有被观察到的结点来增加这个流量的值,进而关闭他们,降低他们的可靠性,或者让用户相信他们是不值得信任的。
⑥运行敌对的OR:敌对的结点可以通过自身创建电路或者改变流量模式来影响其他结点的流量。
5.3目录攻击