昨天遇到了点问题,为了研究清楚原理,把Tor客户端与服务端通信的具体流程学习了一下,这篇博文写来记录

通信流程

这里要描述的通讯是 用户通过 tor浏览器 连接 洋葱服务 的过程

为了方便表达,这里用Alice表示客户端,Bob表示服务端

第一步:服务端设置自己的介绍节点

服务端为了不暴漏自己的IP,使用 介绍节点(introduction points) 来转发来自客户端的介绍信

首先,Bob从 tor中继节点列表 中挑选几个节点来做自己的 介绍节点,然后与它们建立 长连接(long-term circuits)

这里的长连接是通过tor网络建立起来的,所以是匿名的,介绍节点不会知道Bob的IP

同时,Bob会给介绍节点发送一个 身份验证密钥(authentication key),当有客户端连接这个介绍节点时,通过这个密钥便能判断这个连接是否是找Bob的

第二步:服务端公开自己的信息

Bob 生成一个 描述信息(onion service descriptor),里面存储了介绍节点列表,包括介绍节点的ip和相应的身份验证密钥

然后Bob用自己的私钥对这个消息签名,并将这个消息发布到Tor的DHT中

经过这步操作,tor客户端便可以通过某个key从DHT中获取到这个消息,从而找到Bob的介绍节点

第三步:客户端获取介绍节点列表

Alice(客户端)从某些途径知道Bob有一个洋葱服务,并且知道这个服务的onion域名,例如 xyz.onion,此时Alice想要访问Bob.

首先,她向DHT网络请求该域名对应的信息,也就是第二步中Bob发布的那个描述消息

获取到消息后,Alice对其签名进行验证,验证使用的Bob的公钥其实已经被编码到 xyz.onion 这个域名中了,Alice可以从域名中解码出来

消息没问题,Alice从消息中解析出Bob的介绍节点列表,选择其中一个介绍节点,Alice将要向Bob介绍自己

第四步:客户端选择一个会合节点

Alice从tor中继节点列表中选择一个节点作为 会合节点(rendezvous point),然后通过tor与该 会合节点(RP) 建立连接

同时,Alice会给会合节点发送一个 一次性密码(one-time secret),这个密码会在回合过程中使用

第五步:客户端向服务端介绍自己

Alice生成一个消息,包含 会合节点 和 一次性密码,然后用Bob的公钥对消息进行加密

Alice通过Tor网络连接上 Bob 的一个介绍节点,让该介绍节点把加密后的消息转发给Bob

第六步:服务端与客户端回合

此时Bob已经收到介绍节点转发过来的消息,知道Alice想要访问自己,并且知道了会合节点的信息

Bob通过Tor网络连接会合节点,然后将收到的一次性密码发送给会合节点,会合节点由此知道 Bob是要与Alice通信,从而可以将Alice与Bob的消息进行中继

安全性

客户端与服务端最终是通过会合节点通讯的,他们都各自通过tor网络分别连接会合节点,因此既能够保证客户端的隐匿性又能够保证服务端不暴露

在上面流程中的所有通讯都是用过tor网络建立的,包括 服务端与介绍节点的通讯、客户端与介绍节点的通讯、客户端与会合节点的通讯、服务端与会合节点的通讯

因此,正常情况下tor客户端与洋葱服务通讯是经过6次中转的,包括客户端连接会合节点的3次和服务端连接会合节点的3次

如果tor客户端访问的服务不是洋葱服务,那通讯过程就不是上面那个流程了,也只有3次中转了

参考资料

https://community.torproject.org/onion-services/overview/