Tor 究竟如何运作?

2025-06-04

Tor 究竟如何运作?

美国海军研究实验室开发了洋葱路由协议(Tor),用于将美国情报通信投射到网上。讽刺的是,Tor 已被广泛使用,甚至包括那些与美国海军对抗的组织。

你可能知道 Tor 是网络非法活动的发源地,在那里你可以买到任何你想要的毒品,那里充斥着所有非法的东西。Tor 的规模远比媒体报道的要大得多。根据国王学院的说法,Tor 的大部分内容都是合法的。

本文不讨论 Tor 上的内容,也不讨论如何访问 Tor。本文将简要介绍该技术的工作原理,不做任何推测,也不夸大 Tor 的本质。本文旨在供任何人阅读,即使您对网络或 Tor 没有任何了解。

没时间读这篇文章?别担心!点击此处注册我的邮件列表,即可获得这篇博文的 PDF 版本。你还会获得一些之前没有收录在这篇博文中的精彩内容 ✨

Tor 的核心原理是洋葱路由,这是一种通过公共网络进行匿名安全通信的技术。在洋葱路由中,消息被封装在多层加密中。

洋葱有多层结构,通过 Tor 传输的消息也是如此。Tor 中的每一层都是加密,你给 Tor 消息添加了多层加密,而不是仅仅添加一层。
这就是为什么它被称为“洋葱路由协议”,因为它在每个阶段都添加了层。

最终得到的“洋葱”(完全封装的消息)会通过网络中的一系列计算机(称为“洋葱路由器”)进行传输,每台计算机都会剥去一层“洋葱”。每一层都包含下一个目的地——数据包需要前往的下一个路由器。解密最后一层后,您将获得明文(未加密的消息)。

原作者保持匿名,因为网络中的每个节点仅知道路径中的前一个节点和后一个节点(第一个节点除外,它知道发送者是谁,但不知道最终目的地)。

这导致了一些攻击:拥有庞大资源的大型组织运行服务器,试图成为网络中的第一个和最后一个节点。如果该组织的服务器是第一个节点,它就知道是谁发送了消息。如果该组织的服务器是最后一个节点,它就知道最终目的地以及消息的内容。

现在我们对 Tor 有了基本的了解,让我们开始探索 Tor 各个部分的工作原理。

概述

洋葱路由是一种分布式覆盖网络,旨在匿名化基于 TCP 的应用程序,如网页浏览、安全外壳和即时消息。

客户端选择一条通过网络的路径并建立一个电路,其中路径中的每个洋葱路由器都知道前任和后继,但不知道电路中的其他节点。

Tor 电路显示前任 > 你 > 继任者

原作者(最左边的问号)仍然是匿名的,除非您是节点中的第一个路径,因为您知道是谁向您发送了数据包。

用户 > 第一个节点 > 没人知道,这是一个问号

在数据到达路径的最后一个节点之前,没有人知道它发送的是什么;它知道数据,但不知道是谁发送的。路径上的倒数第二个节点不知道数据是什么,只有路径上的最后一个节点知道。

图片显示原作者保持匿名。原作者 > 路径倒数第二个节点 > 路径最后一个节点 > Netflix

这导致了一些攻击:一些拥有庞大资源的大型组织创建Tor服务器,旨在成为路径中第一个和最后一个洋葱路由器。如果这些组织能够做到这一点,他们就能知道是谁发送了数据以及发送了哪些数据,从而有效地攻陷Tor。

糟糕!Netflix 现在知道你看什么了!

如果物理上不靠近组织服务器的位置,那么做到这一点是极其困难的,我们稍后会进一步探讨这个问题。

在本文中,我将以 Netflix 作为常规服务(Bob),以 Amazon Prime Video 作为对手(Eve)。在现实世界中,这种情况极不可能发生。我并非想推测哪些组织可能想要攻击 Tor,因此我使用了两个不太可能的例子,以避免涉及政治层面。

每个数据包都以固定大小的单元在网络中传输。这些单元必须大小相同,这样通过 Tor 网络传输的数据才不会显得过大。

这些单元在每个路由器上都会被对称密钥解开,然后沿着路径继续转发。让我们来深入探讨一下 Tor 本身。

Tor 本身

人多力量大

Tor 需要大量用户来创造匿名性,如果 Tor 难以使用,新用户就不会这么快接受它。正因为新用户不愿接受,Tor 的匿名性才会下降。由此推论,不难看出,可用性不仅仅是 Tor 的设计选择,更是提升 Tor 安全性的一项安全要求。

如果 Tor 不好用或者设计不好,就不会有太多人使用它。如果用的人不多,它的匿名性就会下降。

Tor 必须做出一些设计选择,这些选择可能不会提高安全性,但会提高可用性,并希望可用性的提高能够提高安全性。

Tor 不是什么

Tor 并非像许多人认为的那样,是一个完全去中心化的点对点系统。如果它完全是点对点的,那么它就不太好用。Tor 需要一组目录服务器来管理和维护网络在任何特定时间的状态。

Tor 无法抵御端到端攻击。端到端攻击是指一个实体同时控制路径中的第一个节点和最后一个节点,正如前面所述。这是一个网络安全专家尚未解决的问题,因此 Tor 对此没有解决方案。

Tor 不会隐藏发送者的身份。

2013年,哈佛大学期末考试期间,一名学生试图通过发送虚假炸弹威胁来拖延考试。该学生使用Tor和Guerrilla Mail(一种允许人们创建一次性电子邮件地址的服务)向校方发送了炸弹威胁。

尽管该学生已采取预防措施以确保自己不被抓住,但他还是被抓住了。

Gurillar 邮件会在发送邮件时附带一个原始 IP 地址标头,以便接收者知道原始邮件的来源。使用 Tor 时,学生预计 IP 地址会被加密,但当局知道该 IP 地址来自 Tor 的出口节点(Tor 会在目录服务中保存所有节点的列表),因此当局只需查找在邮件发送时正在访问 Tor(在大学内部)的用户即可。

Tor 并非匿名服务,但它可以加密从 A 到 B 的所有流量(只要不进行端到端攻击)。Tor 的速度也非常慢,因此将其用于 Netflix 并不是一个好的用例。

Tor 的优缺点表格。这里没什么新内容,直接复制了前几段内容。

洋葱路由

节点列表

鉴于上述网络,我们将模拟 Tor 的功能。你的电脑在最左边,你正在发送一个请求,要求在 Netflix 上观看《怪奇物语》(因为 Tor 还有什么用途呢?😉)。这条节点路径称为电路。稍后,我们将研究电路的构成以及加密的工作原理。但现在我们先来概括一下 Tor 的工作原理。

图片

我们从消息开始(我们还没有发送它)。我们需要对消息进行 N 次加密(其中 N 表示路径上的节点数)。我们使用 AES(一种对称密钥加密系统)进行加密。密钥使用 Diffie-Hellman 算法协商。不用担心,我们稍后会讨论所有这些。路径上有 4 个节点(不包括你的电脑和 Netflix),所以我们对消息进行了 4 次加密。

图片

我们的“洋葱”包有四层:蓝色、紫色、橙色和青色。每种颜色代表一层加密。

图片

我们将洋葱发送到路径上的第一个节点。然后该节点会移除第一层加密。

路径中的每个节点都知道解密自身层的密钥(通过 Diffie-Hellman 算法)。节点 1 使用其对称密钥(双方都同意的密钥)移除蓝色层。

图片

节点 1 知道你发送了消息,但是消息仍然经过 3 层加密,它不知道消息是什么。

随着数据包沿着路径传播,越来越多的层被剥离。下一个节点不知道是谁发送了数据包。它只知道是节点 1 发送的数据包,并且要将其递送到节点 3。

图片

现在节点 3 剥离了一层。

图片

最终节点知道消息是什么以及要发送到哪里,但不知道是谁发送的。它只知道节点 3 向他们发送了消息,但不知道路径上还有其他人。这里的关键特性之一是,一旦节点解密了一层,它就无法知道还有多少层需要解密。加密层数可能少到 1 层或 2 层,也可能多到 200 层。

图片

现在亚马逊再也无法发现你看 Netflix 了!Netflix 退回了《怪奇物语》的一部分。

让我们看看它反过来是如何工作的。

图片

节点 4 现在添加了自己的加密层。它不知道最初是谁发出的请求,它只知道节点 3 向其发送了请求,因此它将响应消息发送回节点 3。

图片

接下来的几个节点也是如此。

图片

现在响应数据包已完全加密。

图片

现在数据包已完全加密,唯一仍然知道消息包含什么的是节点 4。唯一知道谁发送了消息的是节点 1。现在我们得到了完全加密的响应,我们可以使用所有对称密钥对其进行解密。

图片

你可能会想:“我见过比这还快的蜗牛🐌”,你说得对。这个协议的设计初衷并非追求速度,但同时它又必须关注速度。

该算法可能会慢得多,但安全性会更高(完全使用公钥加密而不是对称密钥加密),但系统的可用性至关重要。所以,是的,它很慢。不,它并没有慢到可以想象的程度。但这完全是一个权衡的过程。

加密通常使用 AES,密钥通过 Diffie-Hellman 共享。我之前写过另一篇关于 Diffie-Hellman 的文章,请点击此处。

Tor 创建的路径称为线路。让我们来探索一下 Tor 如何选择线路中使用的节点。

电路是如何创建的?

每台机器在创建电路时,都会首先选择出口节点,然后再选择电路中的其他节点。Tor 电路始终包含 3 个节点。增加电路长度并不能提高匿名性。如果攻击者控制了网络中的第一个和最后一个节点,即使电路中有 1500 个节点,也仍然无法提高安全性。

Tor 在选择出口节点时,会遵循以下原则:

  1. 客户端的 torrc(Tor 的配置文件)是否有关于不选择哪些出口节点的设置?
  2. Tor 只会选择一个允许您退出 Tor 网络的出口中继。某些出口节点仅允许 Web 流量(HTTP/S 端口 80),这在有人想要发送电子邮件(SMTP 端口 25)时毫无用处。
  3. 出口节点必须具备足够的容量来支持你。Tor 会尝试选择一个拥有足够可用资源的出口节点。

电路中的所有路径都遵循以下规则:

  • 我们不会对同一条路径两次选择同一个路由器。

如果你两次选择同一个节点,那么该节点要么是守卫节点(你进入的节点),要么是出口节点,这两个位置都很危险。同时是守卫节点和出口节点的概率为 2/3,这更加危险。我们希望避免这种进入/出口攻击。

图片
这不对。节点颜色会改变,以表明它们是一样的。

  • 我们不会选择与同一路径上的其他路由器属于同一家族的任何路由器。(如果两个路由器在其描述符的“家族”条目中都列出了对方,则这两个路由器属于同一家族。)

运行多个 Tor 节点的运营商可以选择将其节点标记为“家族”。这意味着所有节点都拥有同一个父节点(即其网络的运营商)。这同样是为了应对进入/退出攻击,尽管运营商可以不声明家族。如果他们想成为守卫节点(稍后讨论),建议声明家族,但这不是强制性的。

图片

  • 我们不会在给定的 /16 子网中选择多个路由器。

子网定义了网络。IP 地址由 8 个八位字节组成。例如,Google 的 IP 地址(二进制)为:

01000000.11101001.10101001.01101010
Enter fullscreen mode Exit fullscreen mode

前 16 位(/16 子网)01000000.11101001表示 Tor 不会选择任何以与该 IP 地址相同的 16 位开头的节点。这同样是针对进入/退出攻击的对策。

图片
不允许。

如果子网听起来令人困惑,我编写了这个 Python 代码来帮助解释它们:

  • 除非我们进行了配置,否则我们不会选择任何未运行或无效的路由器。默认情况下,我们配置为允许在“中间”和“会合”位置使用无效路由器。

非运行状态表示节点当前不在线。您不想选择不在线的节点。无效状态表示节点 torrc 中的某些配置有误。您不想接受奇怪的配置,以防他们试图入侵或破坏某些东西。

  • 第一个节点必须是守卫节点

守卫节点是特权节点,因为它可以查看用户的真实 IP。成为守卫节点的成本很高(需要保持数周的高正常运行时间并拥有良好的带宽)。

图片

对于拥有 99.9% 正常运行时间和高带宽的大公司(例如 Netflix)来说,这是可能的。Tor 无法阻止强大的对手注册大量的守卫节点。目前,Tor 的配置是每次使用一个守卫节点 12 周,因此您每年只能选择 4 个新的守卫节点。

这意味着,如果你使用 Tor 观看 Amazon Prime Video 一次,Netflix 成为你的守卫节点的可能性就相对较小。当然,Netflix 创建的守卫节点越多,这种可能性就越大。不过,如果 Netflix 知道你连接到 Tor 网络观看 Amazon Prime Video,那么他们必须等待 4 周才能证实他们的怀疑,除非他们攻击并接管守卫节点。

对于大型组织来说,成为守卫节点相对容易。成为出口节点略难,但仍然有可能。我们必须假设大型组织拥有无限的计算能力才能做到这一点。解决方案是让攻击成本高昂,成功率低。

Tor 的常规用户越多,大型组织就越难攻击它。假设 Netflix 控制着网络中 50/100 个节点:

图片

您从 Netflix 中选择守卫节点的概率是 50%。

如果突然有 50 个普通用户节点加入,那么这个比例就是 50/150,从而降低了 Netflix 拥有守卫节点(从而受到潜在攻击)的可能性,并使其成本更加昂贵。

图片

Tor 服务中,人数越多,力量就越大。

Tor隐藏服务

有没有听说过这样的传言:“暗网上有一些网站,在 Tor 上,当你访问这些网站时,你会看到有人在做肮脏的事情,贩卖非法物品,甚至更糟:观看《宿醉 3》”

当人们谈论这些网站时,他们指的是 Tor 隐藏服务。
这是一个很疯狂的概念,老实说,值得专门写一篇博文来阐述。隐藏服务就是服务器,就像任何普通的计算机服务器一样。

图片

除了 Tor 隐藏服务之外,用户和服务器可以在不知道对方身份的情况下进行通信。

图片

设备(问号)知道自己想要访问 Netflix,但它对服务器一无所知,服务器对被请求访问的设备也一无所知。这有点令人困惑,不过别担心,我会用一些很酷的图表来解释这一切。✨

当在 Tor 上设置服务器作为隐藏服务时,该服务器会向一些选定的洋葱路由器发送消息,询问它们是否愿意成为服务器的引入点。服务器最终将决定选择哪台洋葱路由器作为其引入点,但通常会选择 3 个洋葱路由器作为其引入点。

图片

介绍点知道他们将要向人们介绍服务器。

然后,服务器会创建一个称为隐藏服务描述符的东西,其中包含公钥和每个引入点的 IP 地址。然后,它会将此隐藏服务描述符发送到一个分布式哈希表,这意味着每个洋葱路由器(不仅仅是引入点)都会保存隐藏服务的部分信息。

如果您尝试查找隐藏服务,负责该服务的引入点将为您提供完整的隐藏服务描述符,即隐藏服务的引入点的地址。

这个哈希表的密钥是洋葱地址,而洋葱地址是从服务器的公钥派生出来的。

这个想法是,洋葱地址不会在整个 Tor 网络上公开,而是你通过另一种方式找到它,比如从朋友那里或在互联网上(地址以 .onion 结尾)。

分布式哈希表的编程方式意味着绝大多数节点不知道给定键的描述符是什么。

因此,几乎每个洋葱路由器都对隐藏服务知之甚少,除非他们明确想要找到它。

图片

假设有人给了你一个洋葱地址。你从哈希表中请求描述符,然后就能得到服务引入点。

如果你想访问一个洋葱地址,你首先需要从哈希表中请求描述符,这个描述符包含 4 到 5 个介绍节点的 IP 地址。然后你随机选择一个,比如说最上面的那个。

图片

您将要求介绍点将您介绍到服务器,而不是直接连接到服务器,而是从给定的一组洋葱路由器中随机在网络中创建一个会合点。

图片

然后,你与该集合点建立一条线路,并向集合点发送一条消息,询问它是否可以使用你刚才使用的介绍点将你引导到服务器。然后,你向集合点发送一个一次性密码(在本例中,我们使用“Labrador”作为密码)。

会合点与引入点建立电路并向其发送单词“拉布拉多”及其 IP 地址。

图片

引入点将消息发送到服务器,服务器可以选择接受或不执行任何操作。

图片

如果服务器接受该消息,它将创建到会合点的电路。

图片

服务器向汇聚点发送一条消息。汇聚点会查看来自你的计算机和服务器的消息。它会说:“嗯,我收到了这台计算机发来的消息,说它想连接到这个服务,同时我还收到了该服务发来的消息,询问它是否可以连接到另一台计算机,因此它们肯定想互相通信。”

会合点将充当电路上的另一个跳跃并连接它们。

图片

简而言之,隐藏服务的工作原理如下,摘自

  1. 隐藏服务计算其密钥对(私钥和公钥,非对称
  2. 然后隐藏服务选择一些中继作为其介绍
  3. 它将自己的公钥通过 Tor 告知那些引入点
  4. 之后,隐藏服务创建一个隐藏服务描述符,其中包含其公钥及其引入点
  5. 隐藏服务使用其私有的
  6. 然后,它将隐藏的服务描述符上传到分布式哈希表 (DHT)。
  7. 客户端从带外的隐藏服务中了解 .onion 地址。(例如公共网站)($hash.onion 是从服务的公钥派生出来的 16 个字符的名称。)
  8. 检索 .onion 地址后,客户端连接到 DHT 并请求该 $hash。
  9. 如果存在,客户端就会了解隐藏服务的公钥及其引入点。
  10. 客户端随机选择一个中继,与其建立连接,并向其传递一次性秘密。该中继充当汇合点。
  11. 客户端创建一个介绍消息,其中包含会合点的地址和一次性秘密,然后使用隐藏服务的公钥加密该消息。
  12. 客户端通过 Tor 电路将其消息发送到其中一个引入点,要求将其转发到隐藏服务。
  13. 隐藏服务使用其私钥解密介绍消息以了解会合点和一次性秘密。
  14. 隐藏服务创建一个包含一次性机密的会合消息,并通过电路将其发送到会合点。
  15. 会合点告诉客户端连接已建立。
  16. 客户端和隐藏服务通过这个汇聚点相互通信。所有流量都经过端到端加密,汇聚点只是来回中继。需要注意的是,客户端和隐藏服务各自都建立了一条通往汇聚点的线路;每条线路三跳,总计六跳。

结论

Tor 是一个引人入胜的协议,其算法多年来不断精进。我越来越欣赏 Tor,希望你也一样。可惜的是,这篇文章太长,无法一一概括。如果你想了解更多,可以阅读关于 Tor 的论文《Tor:第二代洋葱路由器》

如果您喜欢这篇文章并希望获得更多类似的文章,请注册我的电子邮件列表✨只有当我有新内容时,我才会向您发送电子邮件,大约每个月/ 2 个月一次。

文章来源:https://dev.to/brandonskerritt/how-does-tor-really-work--334d
PREV
如何将浏览量从 3 次提升到 1,000,308 次
NEXT
你需要了解的关于大 O 符号的所有信息 [Python 示例] 目录 🟡 线性时间 🤯 大 O 符号备忘单