# Tor洋葱服务如何工作 昨天遇到了点问题,为了研究清楚原理,把Tor客户端与服务端通信的具体流程学习了一下,这篇博文写来记录 ## 通信流程 这里要描述的通讯是 用户通过 tor浏览器 连接 洋葱服务 的过程 为了方便表达,这里用Alice表示客户端,Bob表示服务端 ### 第一步:服务端设置自己的介绍节点 ![第一步](tor-onion-services-1.png) 服务端为了不暴漏自己的IP,使用 介绍节点(introduction points) 来转发来自客户端的介绍信 首先,Bob从 tor中继节点列表 中挑选几个节点来做自己的 介绍节点,然后与它们建立 长连接(long-term circuits) 这里的长连接是通过tor网络建立起来的,所以是匿名的,介绍节点不会知道Bob的IP 同时,Bob会给介绍节点发送一个 身份验证密钥(authentication key),当有客户端连接这个介绍节点时,通过这个密钥便能判断这个连接是否是找Bob的 ### 第二步:服务端公开自己的信息 ![第二步](tor-onion-services-2.png) Bob 生成一个 描述信息(onion service descriptor),里面存储了介绍节点列表,包括介绍节点的ip和相应的身份验证密钥 然后Bob用自己的私钥对这个消息签名,并将这个消息发布到Tor的DHT中 经过这步操作,tor客户端便可以通过某个key从DHT中获取到这个消息,从而找到Bob的介绍节点 ### 第三步:客户端获取介绍节点列表 ![第三步](tor-onion-services-3.png) Alice(客户端)从某些途径知道Bob有一个洋葱服务,并且知道这个服务的onion域名,例如 xyz.onion,此时Alice想要访问Bob. 首先,她向DHT网络请求该域名对应的信息,也就是第二步中Bob发布的那个描述消息 获取到消息后,Alice对其签名进行验证,验证使用的Bob的公钥其实已经被编码到 xyz.onion 这个域名中了,Alice可以从域名中解码出来 消息没问题,Alice从消息中解析出Bob的介绍节点列表,选择其中一个介绍节点,Alice将要向Bob介绍自己 ### 第四步:客户端选择一个会合节点 ![第四步](tor-onion-services-4.png) Alice从tor中继节点列表中选择一个节点作为 会合节点(rendezvous point),然后通过tor与该 会合节点(RP) 建立连接 同时,Alice会给会合节点发送一个 一次性密码(one-time secret),这个密码会在回合过程中使用 ### 第五步:客户端向服务端介绍自己 Alice生成一个消息,包含 会合节点 和 一次性密码,然后用Bob的公钥对消息进行加密 Alice通过Tor网络连接上 Bob 的一个介绍节点,让该介绍节点把加密后的消息转发给Bob ![第五步](tor-onion-services-5.png) ### 第六步:服务端与客户端回合 ![第六步](tor-onion-services-6.png) 此时Bob已经收到介绍节点转发过来的消息,知道Alice想要访问自己,并且知道了会合节点的信息 Bob通过Tor网络连接会合节点,然后将收到的一次性密码发送给会合节点,会合节点由此知道 Bob是要与Alice通信,从而可以将Alice与Bob的消息进行中继 ## 安全性 客户端与服务端最终是通过会合节点通讯的,他们都各自通过tor网络分别连接会合节点,因此既能够保证客户端的隐匿性又能够保证服务端不暴露 在上面流程中的所有通讯都是用过tor网络建立的,包括 服务端与介绍节点的通讯、客户端与介绍节点的通讯、客户端与会合节点的通讯、服务端与会合节点的通讯 因此,正常情况下tor客户端与洋葱服务通讯是经过6次中转的,包括客户端连接会合节点的3次和服务端连接会合节点的3次 如果tor客户端访问的服务不是洋葱服务,那通讯过程就不是上面那个流程了,也只有3次中转了 ## 参考资料 https://community.torproject.org/onion-services/overview/