走近科学 | ”种子“的前世今生

*本文原创作者:追影人

0x00 前言

“种子”是生命的起点,是未来的希望,同时也解决了无数宅男腐女的寂寞时光。本文将带领各位童鞋了解BT种子(torrent)及P2P网络的运行机制,教您如何更加科学的搜索热门种子资源。

0x01 种子的起源

早些时期,文件下载一般都由专门的文件服务器作为下载源,统一对客户机提供下载服务。这种集中式下载方式存在着天然缺陷,当服务器宕机后,将会影响所有用户的下载;

另外,多客户同时进行下载,会因为服务器带宽有限,分配给每个客户机的网速很低,从而出现下图这种痛心疾首的状况。

显然这极大影响了求片心切童鞋的心情,在这用户至上的时代,为了改善这一缺陷,提高用户体验,服务商不得不增加服务器的数量,以应对大流量下载。

但随着互联网的迅速普及,文件数量和体积成指数增长,服务商已经无法承担无限扩增的服务器的成本,尤其对于一些媒体资源服务商,这种状况更加突出。

既然该问题的瓶颈在于服务商,那么是否可以对客户端进行改进?P2P的分布式下载方式较好解决了该问题。

P2P(peer-to-peer)网络,顾名思义,网络中的节点角色对等,节点即是客户端又是服务器,彼此在进行文件下载时可以直接访问无须经过其他中间实体,没有任何“中间商”(NAT后的节点需要进行UDP穿透)。

整个网络“一般”不依赖专用的集中服务器(请注意此处所加的引号,这里并非真正意义上的完全不需要,而是需要一些辅助服务器,后续我们将介绍),也没有专用的工作站,在网络中进行资源下载、查询、响应时完全依赖于各个节点。

P2P网络的出现,改变了互联网以大网络服务商为中心的状态,重新回到了“非中心化”,把权力交还了用户。同时,P2P网络以可扩展、耐攻击、高容错、高性价比等优势迅速普及。

0x02 种子的土壤

P2P网络中节点角色对等,那么如何查找资源成为关键。早期解决这一问题,是由tracker服务器提供资源位置信息。当客户端需要下载资源时,先链接tracker服务器,报告自身信息,从而得到持有该资源的其他节点信息。

Tracker服务器对所有的资源持有者信息进行统一维护,当收到下载请求后,将请求者信息加入到最新的下载资源节点列表中。

一定程度上,tracker服务器起到了中心节点的作用,维护着全网的资源位置。后来,由于法律风险问题以及版权争议,很多tracker服务器被强制关闭,直接影响了网络的正常运行。

为此,DHT(Distributed Hash Table,分布式哈希表)网络诞生,目前很多P2P软件均采用tracker模式和DHT模式相结合的下载方式。

DHT网络中,所有节点的角色对等,各节点即是信息消费者又是信息生产者,路由功能完全由节点间扩散完成。DHT网络在节点路由和资源查询方面使用的最著名的算法便是kademlia算法(简称KAD)。

首先我们先认识两个术语:

Peer:”peer”节点实现了BT协议,使用TCP协议,用于资源文件的传输; node:”node”节点用于实现DHT协议,使用UDP协议,用于节点的路由管理和资源位置的查询。

在实际应用中,peer和node一般都位于同一个物理节点上,我们可以将其理解为两个不同的服务,前者用于资源文件的下载,后者用于DHT网络节点位置的查询以及资源文件所在peer位置的查询定位。

KAD协议主要用于DHT网络的资源查询,由于网络中节点和资源非常众多,而DHT网络中又没有集中式的路由管理节点,所以网络中的每一个节点都需要存储路由信息。

将整个网络的资源信息存储在每一个节点上显然是不现实的,因此每一个节点只存储部分资源信息即可。

标识

KAD协议利用SHA-1算法为node节点随机分配一个全局唯一的nodeID标识,长度为160bit,同时也对资源文件进行计算,也生成一个160bit的标识infohashes。

距离

节点之间的距离由nodeID异或计算。即distance(A,B)=|A xor B|

路由

每一个节点都保存有一个路由表,该路由表以K-buckets(k-桶)的形式存在,每一个bucket对应一个nodeID范围,涵盖了0-2^160的所有范围的ID。

极限情况下,路由表中会有160个k桶,每一个k桶内所放置的节点与本节点的距离如上图所示,且k桶内的节点数目最多不超过k个。

节点通常保存的路由信息并不能完全填充上面的160个k桶,所以节点在初始化时,k桶只有1个,范围覆盖0-2^160,随着后续节点路由信息的不断加入,路由信息数超过k时,k桶便会分裂成两个,每一个新桶的范围都变为原桶的一半,第一个为0-2^159,第二个为2^159-2^160,迭代分裂。

资源

节点持有资源时,需要尽可能多的通知其他节点,以便于其他节点的查询。节点会将自已的位置通知给那些nodeID和资源文件infohashes接近的节点。

这样在网络中查询资源时,只需要去查找资源infohashes附近的节点即可找到资源文件的所在位置信息。

请求

ping:测试节点是否在线。 find_node:发送节点查询请求。 find_value(get_peers):查找资源文件所在位置。 store (announce_peer):将资源文件所在位置通知给目标节点用于其存储。

0x03 种子的诞生

从KAD协议运行过程可见,在查找资源时,非常重要的一个要素就是文件所对应的infohashes。由于infohashes只是一段160bit的hash值,用户无法从中得到任何明文信息,所以设计者为其添加了其他附属信息,形成了一个文本文件,即种子文件,通常以.torrent作为后缀名。

种子文件又称"Metainfo file",里面存储有关于下载内容的tracker服务器地址、文件长度、资源SHA1值等内容。它由Bencode编码组成,且字符串是用UTF-8编码。

种子文件的格式

文件以字典形式存储内容,具体有如下关键字:

announce:tracker服务器的URL

announce-list(可选):备用tracker服务器列表

creation date(可选):种子创建的时间,以unix时间戳形式存在

comment(可选):备注

created by(可选):创建人或创建程序的信息

info:一个字典结构,包含文件的主要信息,为分二种情况:单文件结构或多文件结构

nodes:最后的一个字段是nodes字段,这个字段包含一系列ip和相应端口的列表,是用于连接DHT初始node。

单文件结构如下:

length:文件长度,单位字节(整数)

md5sum(可选):长32个字符的文件的MD5校验和,BT不使用这个值,只是为了兼容一些程序所保留(字符串)

name:文件名(字符串)

piece length:每个块的大小,单位字节(整数)

pieces:每个块的20个字节的SHA1 Hash的值(二进制格式)

多文件结构如下:

files:一个字典结构

length:文件长度,单位字节(整数)

md5sum(可选):同单文件结构中相同

path:文件的路径和名字,是一个列表结构,如/test/test.txt 列表为l4:test8test.txte

name:最上层的目录名字(字符串)

piece length:同单文件结构中相同

pieces:同单文件结构中相同

细心的同学发现,整个种子文件中并没有出现20字节的infohashes,那么下载器是如何通过种子文件去tracker查询该文件呢?难道是通过文件名称?

答案是否定的。以文件名的方式去唯一标定资源,很大概率会发生同名冲突,因此BT协议利用种子文件中的内容计算出infohashes值进行唯一标定。

计算时,从种子文件info字段开始(不包含"info"这四个字节),一直到nodes字段为止(不包含"nodes"这5个字节和nodes前边表示nodes字段长度的"5:"这两个字节),对中间的内容进行SHA-1计算形成infohashes值。

下图为利用某种子搜索平台搜索《变形金刚4:绝迹重生》(英文名:Transformers: Age of Extinction)的结果。

进入某种子链接的详细页面,我们可以看到网站对种子的相关关键字做了解析。

下载该种子,利用notepad将其打开,可见其中的内容如下。

0x04 种子的成长

获得种子文件后,下一步关键是如何找到下载源(即资源的存储位置)。第一代P2P网络以tracker服务器作为中心节点,为客户端提供下载源查询服务。

该过程大致如下:

1、客户端通过对种子文件的解析和计算,获得tracker服务器列表和文件的infohashes值; 2、客户端通过http协议向服务器请求该infohashes对应文件资源的下载源peers列表; 3、tracker服务器会响应该查询请求,返回可用下载源peer的ID、IP、PORT等信息; 4、客户端得到peers列表后,进行点对点的文件下载。

实践出真理,我们依旧举个栗子。

使用迅雷打开上一节我们获取的种子文件。

切换到“属性设置”页面,可以看到tracker服务器列表。

开始下载后,针对tracker服务器列表发送DNS查询请求。

这是其中的一台tracker服务器DNS查询记录。

客户端对该tracker发出的http请求,用于tracker服务器的peers获取。

Tracker查询

● info_hash:.torrent文件中的infohashes,共20字节。 ● peer_id:客户端ID,共20字节。 ● ip:可选,IP地址,没有的话服务器会自己找到。 ● port:监听端口。 ● uploaded/downloaded:上传/下载的字节数(从客户端向Tracker服务器发送”started”开始计算,用于断点续传) ● left:还需下载的字节数。 ● numwant:可选。客户端希望从Tracker服务器得到的对等方的数目。 ● key:可选。一个扩展的唯一性标识,即使改变了IP地址,也可以使用该字段标识该客户端。 ● compact:压缩标志。如果值为1表示接受压缩格式的对等方列表,即用6byte表示一个对等方 (前4byte表示IP地址,后2byte表示端口号);值为0表示不接受。

Tracker响应

Tracker服务器响应是用Bencoding编码的字典。

● 如果响应中有关键字failure reason,则表示查询失败,其值为失败原因字符串。 ● 否则有两个关键字: Interval: 两次发送请求的时间间隔 Peers: 一个字典的列表,每个字典包括一下关键字Peer Id , IP , Port,分别对应Peer所选择的ID, IP地址。

0x05 种子的肥料

P2P下载方式以其诸多优势,碾压传统的集中式下载,迅速普及,先后出现多款P2P下载软件。随着用户量的激增,用户生态逐渐复杂,各类问题也相应出现。文件污染、版权问题、犯罪等问题,使得相关部门不得不对P2P网络下手,一些国家还逮捕了相关作者。

虽然P2P网络为对等网络,下载过程不需要中心服务器,但是在查询资源peers时,需要tracker服务器的辅助,因此整个网络又退回到了拥有中心节点的状态。‘

相关部门也持着“挑软柿子捏”的心态,强制关闭了大量tracker服务器,导致很多资源都无法正常下载,P2P的下载方式也陷入了低谷。

此时,第二节中所介绍的DHT网络闪亮登场,可谓是给P2P下载网络施加了一把肥料。该网络无需tracker中心服务器,所有的peers列表信息都分布在网络中的各个节点上,进一步增强了网络的鲁棒性,P2P下载也由此进入2.0时代。

有关DHT网络的情况在第二节已经介绍了一些,下面重点介绍torrent文件如何和DHT网络结合使用。

一个无tracker服务器的种子文件不包含tracker服务器列表,而是存储着一些节点信息,其内容为torrent创建者的路由表中K个nodeID最接近infohashes的nodes。由此可以看出,在DHT网络中最关键的步骤是让客户端找到网络中的可用节点。

当一个新的客户节点首次试图加入DHT网络时,需要做如下三件事:

1、获知一个已经加入DHT网络的节点信息,并将其加入自己的k-buckets; 2、向该节点发起一次针对自己NodeID的节点查询请求,从而通过该节点获取一系列与自己距离邻近的其他节点的信息; 3、刷新所有的k-bucket,保证自己所获得的节点信息全部都是可用的。

而在第一个步骤中,节点一般通过如下方式获取已知节点信息:

1、种子文件中预置; 2、客户端中预置有长期稳定在线的节点信息; 3、从公网中的DHT服务器获取在线节点信息,例如router.bittorrent.com: 6881,router.utorrent.com:6881,router.bitcomet.com: 6881,dht.transmissionbt.com:6881

节点加入DHT网络后,通过find_value请求携带种子文件的infohashes值查询资源所在的位置,如果被查询的节点持有该资源的相关源信息,则会返回一个token,并将下载源的ID、IP和PORT等信息返回给客户端。

此时客户端便开始从下载源下载资源,同时该客户端也成为新的下载源,为了能够被其他下载客户查询到,需要将自身的信息扩散。客户端会携带刚才的token和自己的地址信息,以store请求的形式向之前的查询节点发送请求,将自己的信息存储在查询节点上。

磁力链接

随着BT服务器的大量关闭,导致很多种子文件无法获取。既然DHT网络的资源查询只需要infohashes即可,那么种子文件便可以简化成一个链接,这便是磁力链接(Magnet links)。

磁力链接是以“magnet:?xt=urn:btih:”开头的字符串,后面则是资源文件的infohashes值。

magnet:?xt=urn:btih:D3F7987EDF395104240AA16B30564B7372E55FFA

该链接为变形金刚4的磁力链接,是从迅雷下载中直接复制得到。由于HASH是不可逆的,所以从磁力链接上不能倒退出种子文件的信息,需要借助第三方种子库完成该转换。

迅雷种子库hxxp://bt.box.n0808.com提供该服务,转换时需要访问hxxp://bt.box.n0808.com/D3/FA/D3F7987EDF395104240AA16B30564B7372E55FFA.torrent即可下载对应的种子文件,其中的/D3/FA分别为infohashes的第一个字节后末尾字节。

我们在使用迅雷打开磁力链接进行下载时,迅雷会先从种子库中获取种子,得到具体文件信息后再进行下载。

迅雷之所以这样做,而非直接使用infohashes去DHT网络查询,也是为了给客户展示更过文件信息,提供良好客户体验,而不是下载时只能看到一个以HASH值为名的文件。

0x06 种子的脆弱

基于DHT网络的开放性,所有节点都在不断的加入和退出,而不需要特殊的认证机制,因此这也给DHT网络带来了诸多安全隐患。

1. DHT网络没有可信的认证中心,提供身份认证、通信加密等服务; 2.DHT网络的节点的NodeID虽然是随机生成,但是并没有严格的唯一性认证,容易被身份伪造; 3.DHT网络的节点对于路由消息的来源和内容无安全判断,可能导致路由表反射攻击和路由表污染攻击; 4.DHT网络对于节点发布的资源信息的来源和内容无安全判断,可能导致资源索引污染攻击;

因此,DHT网络可能会遭受多种攻击,例如Sybil攻击、Eclipse攻击、路由表攻击、DDoS攻击等。

DHT爬虫便是一个很好的说明,其利用DHT的开放性,将自己伪装成一个节点,收集其他节点的find_node、find_value、store等请求,从而获取到资源信息。如果将大批僵尸节点伪装为DHT节点加入DHT网络,对路由表和资源索引进行攻击,则会直接影响到整个网络的安全运行。

0x07 总结

本文从种子文件出发,简要介绍了P2P网络的发展历程,KAD协议、DHT网络、种子文件、磁力链接的基本知识,并指出DHT网络的脆弱性。

由于版权的问题,P2P网络从一开始就备受争议,版权组织和软件作者进行了一次次的交锋,从tracker服务器的关闭到磁力链接的诞生,这都是交锋后的产物,那么P2P的3.0时代会是怎么样呢?我们拭目以待。

0x08 参考&感谢

DHT Protocol http://www.bittorrent.org/beps/bep_0005.html

BT(带中心Tracker)通信协议的分析 http://blog.chinaunix.net/uid-26548237-id-3056731.html

百度百科-磁力链接

对BitTorrent通信协议的分析与检测 http://www.dns001.com/tech/content-47-27541-1.html

B编码以及BT种子文件分析 http://www.cnblogs.com/DxSoft/archive/2012/02/11/2346314.html

* 作者:追影人,本文属FreeBuf原创奖励计划文章,未经许可禁止转载

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2016-06-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏二次元

萌音影视 - 在线影视应用

虽然在线影视网上也是遍地都是,但这并不影响我自个写一个,这样以后自己看番也方便,毕竟自己动手才能丰衣足食,又能学习到新的知识,岂不美哉。

52820
来自专栏农夫安全

运维的福利,黑客的噩梦

CYWL_Team服务器防御工具1.0 0x01开发前言 很多小黑都希望搭建自己的博客,论坛,来记录自己在安全之路上面的点点滴滴,不过总是被一些大牛来进行恶搞,...

39880
来自专栏工科狗和生物喵

Python爬虫小白入门(一)

开篇语 本篇文章适用人群 >有一点点语法基础,至少知道Python这个东西,如果有其他方面语言的基础那也凑合 >会一点点Linux系统的操作,最好是ubunt...

519110
来自专栏张戈的专栏

WordPress发布文章主动推送到百度,加快收录保护原创

工作实在太忙,也没时间打理网站。最近公司额外交待了一些网站 SEO 方面的优化任务让我关注(这就是啥都要会、啥都要做的苦逼运维的真实写照了...)。 于是抽空看...

36060
来自专栏V站

图片API丨V站二次元随机图片API(自判断)

①于2018.03.31公布,采用高速服务器运行! ②PC版随机图片拥有200+张,PE版拥有100+张超精美二次元风随机图片,每星期一更! ③全程免费,欢迎支...

4.4K100
来自专栏IT派

Python库大全,建议收藏留用!

学Python,想必大家都是从爬虫开始的吧。毕竟网上类似的资源很丰富,开源项目也非常多。

24820
来自专栏Golang语言社区

Go的单元测试技巧

本文为社区粉丝原创投稿,再次感谢作者DrmagicE的分享,欢迎大家在评论区留言和作者讨论,同时也欢迎大家踊跃投稿,分享您的golang语言学习经验!投稿邮箱地...

13730
来自专栏pangguoming

使用JAVA开发微信公众平台(一)——环境搭建与开发接入

一、 初始微信公众平台 微信公众平台,即我们平时所说的“公众号”,曾用名“官方平台”、“媒体平台”,但最终命名为“公众平台”。从微信的命名我可以发现,公众平台不...

61860
来自专栏王清培的专栏

记5.28大促压测的性能优化—线程池相关问题

目录: 1.环境介绍 2.症状 3.诊断 4.结论 5.解决 6.对比java实现 废话就不多说了,本文分享下博主在5.28大促压测期间解决的一个性能问题,觉得...

25170
来自专栏大数据挖掘DT机器学习

基于Hadoop 的分布式网络爬虫技术

一、网络爬虫原理 Web网络爬虫系统的功能是下载网页数据,为搜索引擎系统提供数据来源。很多大型的网络搜索引擎系统都被称为基于 Web数据采集的搜索引擎系统,比如...

52880

扫码关注云+社区

领取腾讯云代金券