分布式存储IPFS基本知识

295 阅读14分钟
  • (1)分布式哈希表的历史:
    • 第 1代 P2P 文件网络需要中央数据库协调,这样的设计容易导致单点失效,甚至导致整个网络瘫痪。
    • 在第 2 代分布式文件系统中,Gnutella 使用消息洪泛方法(message flooding)来定位数据。这种方式所需的网络请求量非常大,很容易造成拥堵。
    • 第 3 代分布式文件系统中,DHT ( Distributed Hash Table) 主要思想如下: 全网维护一个巨大的文件索引哈希表,这个哈希表的条目形如 <Key, Value>。这里 Key 通常是文件的某个哈希算法下的哈希值(也可以是文件名或者文件内容描述),而 Value 则是存储文件的 IP 地址。查询时,仅需要提供 Key,就能从表中查询到存储节点的地址并返回给查询节点。当然,这个哈希表会被分割成小块,按照一定的算法和规则分布到全网各个节点上。每个节点仅需要维护一小块哈希表。这样,节点查询文件时,只要把查询报文路由到相应的节点即可。
  • (2)介绍一下kademlia算法:
    • Kademlia算法是一种用于构建分布式哈希表(DHT)的基于网络的算法。它被广泛应用于点对点(P2P)网络和去中心化系统。
    • 具有良好的可扩展性和鲁棒性。它通过将节点和数据分布在整个网络中,以实现分散的存储和查找功能。
    • 使用一种称为K桶的数据结构来维护网络中的节点信息。每个节点在其本地维护一张K桶表,其中每个K桶存储与节点ID距离在某个范围内的其他节点信息。
    • 利用异或运算来计算节点ID之间的距离,并根据距离来选择最佳的节点进行通信。这种基于距离的选择策略保证了消息能够尽快到达目标节点,并且在节点加入、离开或故障时具有良好的容错性。
  • (3)假如有一个节点u要加入这个网络,流程是怎样的?
    1. 如果节点u要加入KAD网络,它必须和一个已经在KAD网络中的节点比如w,取得联系。
    2. u首先把w插入自己适当的桶中,对自己的节点ID执行一次 FINDNODE 操作,然后根据接收到的信息更新自己的K桶内容。
    3. 通过对自己邻近节点由近及远的逐步查询,u完成了仍然是空的K桶信息的构建,同时也把自己的信息发布到其他节点的K桶中。
    4. 在 KAD 网络中,每个节点的路由表都表示为一棵二叉树,叶子节点为K桶,K桶存放的是有相同ID前缀的节点信息,而这个前缀就是该桶在二叉树中的位置。这样,每个K桶都覆盖了ID空间的一部分,全部K桶的信息加起来就覆盖了整个160bit的ID空间而且没有重叠。
  • (4)查找一个id值为t的文件,流程是怎样的?
    1. 计算自己的节点ID,并将其与目标ID的t 进行比较。如果它们相等,则表示已经找到了目标节点,可以直接访问该节点。
    2. 如果自己的节点ID与目标ID t 不相等,则需要向距离目标ID t 最近的已知节点发送请求。这个已知节点可以是自己所维护的路由表中距离目标ID最近的K个节点之一,也可以是其他已知节点。
    3. 向这个已知节点发送请求,请求包含目标ID t 和自己的节点ID。这个请求会被沿着DHT网络传递下去,直到找到一个与目标ID t 距离更近的节点。
    4. 当找到一个更接近目标ID t 的节点时,该节点会将响应返回给发起请求的节点,并告诉它下一步应该向哪个已知节点发送请求。
    5. 重复上述步骤,直到找到了目标ID为t的节点或者确定无法找到该节点为止。

(5)哪些攻击方式?

Kademlia攻击方式包括日蚀攻击、女巫攻击、流失攻击和对抗路由攻击

  1. 日蚀攻击如果一个节点在网络中能够自由选择它的ID,攻击者可以在网络中安放一些恶意节点,使得信息都必须经由恶意节点传递。那么这样一来,恶意节点就能够在网络中将一个或几个节点从网络中隐藏掉。
  2. 女巫攻击在开放的对等网络里,攻击者可以假冒多个ID,用少数网络节点控制多个虚假身份。KAD 网络难以控制节点的数量,那么攻击者伪造大量虚假节点身份,就能控制部分网络。
  3. 流失攻击攻击者拥有网络的一些节点,即恶意节点,这可能会在网络中引发大量流量流失,从而导致网络稳定性降低。
  4. 对抗路由攻击恶意节点在收到查询指令后,不是按照KAD的要求返回距离Key最接近的网络节点,而是转移给同伙节点。同伙节点也做同样的操作,而不返回给查询节点所需要的信息,那么这样一来查询就会失效。我们发现,整个过程中必须将查询信息传递给恶意节点,这一攻击才能发动。那么我们可以在查询时设计算法并行地查询,并且每一条查询路径不相交。这样一来,只要并行查询的路径中有一条不碰到恶意节点,查询就能成功了。

(6)解决方法?

  1. 采用S/K防护:每个节点在接入前必须解决两个密码学问题,静态问题是:产生一对公钥和私钥,并且将公钥做两次哈希运算后,具有 c1 个前导零。那么公钥的一次哈希值,就是这个节点的NodeID。动态问题是:不断生成一个随机数X,将X与NodeID求XOR后再求哈希,哈希值要求有 c2个前导零。静态问题保证节点不再能自由选择节点 ID 了,而动态问题则提高了大量生成ID 的成本。那么女巫攻击和日蚀攻击将难以进行。

    1.   S/K节点ID分配策略方案有3个要求: 节点不能自由选择其ID; 不能生成多个ID; 不能伪装和窃取其他节点的ID。
  2. 为确保节点身份不被窃取,节点需要对发出的消息进行签名。在其他节点接收到消息时,首先验证签名的合法性,然后检查节点ID是否满足上述两个难题的要求。 对于网络其他节点验证信息的合法性,它的时间复杂度仅有O(1);但是对于攻击者,为了生成这样一个合法的攻击信息。合理选取c1和c2,就能有效避免这3种攻击方式了。

  3. 每次查询从d个不同的 Bucket选择k个节点。这d个Bucket并行查找,Bucket内部查找方式和KAD协议完全相同。这样一来,d条查找路径就能做到不相交。 通过不相交路径查找,能解决对抗路由攻击。S/K协议将 Kademlia协议改进后,针对常见的攻击,其安全性能大大提高了。 1.分布式存储是指将数据存储在多个独立的存储设备中,通过网络连接的方式共同工作,共同提供数据存储和访问服务的系统。

优化查询效率?

  1. 计算到t的距离:d(x,t)=x⊕t。
  2. 从x的第log(d)个K桶中取出a个节点的信息,同时进行FIND_NODE操作。如果这个K桶中的信息少于a个,则从附近多个桶中选择距离最接近x的 a 个节点。
  3. 对接收到查询操作的每个节点,如果发现自己就是t,则回答自己是最接近t的;否则测量自己和t的距离,并从自己对应的K桶中选择a个节点的信息给 x。
  4. x对新接收到的每个节点都再次执行FIND_NODE操作,此过程不断重复执行,直到每一个分支都有节点响应自己是最接近t的。
  5. 通过上述查找操作,x得到了k个最接近t的节点信息。

在BitSwap中,我们与其他节点交换数据时,不会通过交易市场进行。

通过使用S/Kademlia生成PeerId的算法,可以决对抗路由攻击。

IPFS协议栈:

(1)一共分了几层?

身份层、网络层、路由层、交换层、对象层、文件层、命名层 (2) 每层的功能是什么? 身份层:创建用于P2P通讯的节点信息 网络层:支持传输层的协议 路由层:内容路由、节点路由、文件存取 交换层:保证节点网络稳定,激励交换数据行为 对象层:内容可寻址的、不可篡改的、去冗余的对象链接 文件层:版本控制的文件系统 命名层:SFS&IPNS,给文件加“别名”

BitTorrent协议:

(1)其中的术语(torrent,tracker,peer,seed,swarm):

torrent: 它是服务器接收的元数据文件 (通常结尾是Torent)。这个文件记录了下载数据的信息 (但不包括文件自身),例如文件名、文件大小、文件的哈希值,以及 Tracker 的 URL 地址。 tracker :是指互联网上负责协调 BitTorrent 客户端行动的服务器。当你打开一个 torrent 时,你的机器连接 tracker,并且请求一个可以接触的peers 列表。在传输过程中,客户端将会定期向 tracker 提交自己的状态。tracker 的作用仅是帮助 peers 相互达成连接,而不参与文件本身的传输。 peer : peer 是互联网上的另一台可以连接并传输数据的计算机。通常情况下,peer 没有完整的文件。peer 之间相互下载、上传。 seed:有一个特定 torrent 完整拷贝的计算机称为 seed。文件初次发布时需要一个 seed 进行初次共享。 swarm:连接一个 torrent 的所有设备群组。 Chocking: Chocking 阻塞是一种临时的拒绝上传策略,虽然上传停止了,但是下载仍然继续。BitTorrent 网络下载需要每个 peer 相互上传,对于不合作的 peer,会采取临时的阻断策略。 Pareto 效率: 帕累托效率 ( Pareto efhicieney) 是指资源分配已经到了物尽其用的阶段,对任意一个个体进一步提升效率只会导致其他个体效率下降。此时说明系统已经达到最优状态了。 针锋相对 (Tit-fot-Tat): 又叫一报还一报,是博弈论中一个最简单的策略。以合作开局,此后就采取以其人之道还治其人之身的策略。它强调的是永远不先背叛对方,除非自己被背叛。在 BitTorrent 中表现为,Peer 给自己贡献多少下载速度,那么也就贡献多少上传速度给他。 (2)在bittorrent中发布一个文件的流程:

首先,seed 会生成一个扩展名为 .torrent 的文件,它包含如下信息: 文件名、大小、tracker 的 URL。一次内容发布至少需要一个 tracker 和一个 seed,tracker 保存文件信息和 seed 的连接信息,而 seed 保存文件本身。一旦 seed 向 tracker 注册,它就开始等待为需要这个 torrent 的 peer 上传相关信息。

通过 .torrent 文件,peer 会访问 tracker,获取其他 peer/seed 的连接信息,例如 IP 和端口。tracker 和 peer 之间只需要通过简单的远程通信,peer 就能使用连接信息,与其他 peer/seed 沟通,并建立连接下载文件。

(3)介绍一下其中的片段选择算法:

优先完成单一片段: 如果请求了某一片段的子片段,那么本片段会优先被请求。这样做是为了尽可能先完成一个完整的片段,避免出现每一个片段都请求了同一个子片段,但是都没有完成的情况。 优先选择稀缺片段: 选择新的片段时,优先选择下载全部 peer 中拥有者最少的片段。拥有者最少的片段意味着是大多数 peer 最希望得到的片段。这样也就降低了两种风险,其一,某个 peer 正在提供上传,但是没有人下载(因为大家都有了这一片段); 其二,拥有缺片段的 peer 停止上传,所有 peer 都不能得到完整的文件。 第一个片段随机选择: 下载刚开始进行的时候,并不需要优先最稀缺的。此时,下载者没有任何片断可供上传,所以,需要尽快获取一个完整的片断。而最少的片断通常只有某一个 peer 拥有,所以,它可能比多个 peer 都拥有的那些片断下载得慢。因此,第一个片断是随机选择的,直到第一个片断下载完成,才切换到“优先选择稀缺片段”的策略。 结束时取消子片段请求: 有时候,遇到从一个速率很慢的 peer 请求一个片断的情况,peer 会向它的所有的 peer 都发送对某片断的子片断的请求,一旦某些节点发送的子片断到了,那么就会向其他 peer 发送取消消息,取消对这些子片断的请求,以避免浪费带宽。

libp2p:

(1)介绍一下libp2p的分层

第1层是接口层,它帮我们实现了ID-service、pub- sub、dht、ping 偏应用属性的功能接口,开发人员只需关注这一层,即可快速上手,使用libp2p进行开发。

第2层是 host层,分为routed host和basic host,这两个host是继 承关系,routed 是basic的一个扩展实现。在libp2p中,一个host代表一个节点,所以在IPFS中,以host为单位进行数据分发与传输。

  • (2)swarm五个组件的作用
    1. Peerstore:节点之间建立连接,形成一个对等网络。每个节点都可以连接到多个其他节点,通过这些连接进行数据交换和共享。
    2. listener管理:负责监听和管理节点的网络连接,以实现节点之间的通信和数据传输。
    3. 回调管理:当有一个新的 stream 进来,调用中转函数进行逻辑处理。
    4. Transport管理:提供底层的网络传输协议,用于节点之间的数据传输。IPFS支持多种传输协议,如TCP、WebRTC和QUIC,以适应不同的网络环境和需求。
    5. Conn管理:负责管理节点之间的连接状态,包括建立连接、维护连接和处理连接中断等。它确保节点之间的通信可靠性和稳定性,以便有效地交换数据。

节点之间的三次握手:

  1. 第1次握手互换信息(公钥、nonce、节点支持的非对称加密的列表和对称加密列表、支持的哈希方式列表)。
  2. 第2次握手,交换信息 (临时密钥、签名信息),根据对方的公钥进行加密。对方收到数据后使用自己的私钥去解密即可。至此,节点之间就完成了可用的通信密钥交换
  3. 第3次握手验证信息,验证双方有没有按照正确的方式完成信息交换