我希望通过使用分布式数据系统来创建高可用性、可扩展的网络解决方案。这里的节点是指可以控制一份数据副本的网络。这些节点可能包含多台机器,但只有一份数据副本。
节点将包含处于已使用状态或未使用状态的数据记录。客户端可以请求将记录从未使用状态转换为已使用状态(请求使用)。如果他们能够多次成功执行此操作,则存在安全风险。
如果单个节点与所有其他节点都有连接,则可以告知节点已请求支出,并确保没有其他节点想要访问数据,并且支出尚未发生。该节点可以将数据状态更改为已支出,而其他节点不会这样做,因为它们知道其中一个节点正在更新数据并处理支出。所有节点都将更改数据,因此记录处于已支出状态。
如果一个节点无法到达另一个节点,它可以假设另一个节点已关闭并将继续与其他节点一起运行,直到另一个节点恢复。在这种情况下,节点会将所有更新发送到恢复的节点。如果此故障节点当时正处于未完成的支出操作中,它可以完成该操作。这会导致某些操作短暂停机。这种情况可能发生在节点告诉其他节点它将支出,然后在完成支出过程之前发生故障的情况下。在这种情况下,其他节点无法更新它,因此故障节点需要重新上线才能完成。
问题是,支出处理只能发生一次。如果网络被分区,知道这一点的攻击者可以在一个分区和另一个分区请求支出。网络的每个分区都会假设另一个分区已关闭,因此将独立运行。这可能导致支出被处理多次。
如果在网络被分割期间没有向网络两端发出请求,那么这不会成为问题。当重新建立连接时,网络将最终保持一致。如果攻击成功,节点将在重新建立连接时获悉攻击,因为网络两端都会宣布相同的变化。
因此,这是可检测的攻击,但实际上可能吗?
攻击者必须故意尝试这样做。该软件并非设计用于一次发出多个支出请求。攻击需要时间成本。如果攻击者失败,他们需要花费一些时间才能重新创建未花费的记录。创建未花费的记录需要花钱。而单次攻击需要花费更多钱才能获得更高的收益。之所以需要时间成本,是因为需要花时间才能收回钱并再次尝试。他们可以承受多次较小的攻击,这样他们获得的收益就会更少,造成的损失也会更少。
当然,分区在自然界中非常罕见,以至于攻击者如果在任何时候尝试攻击,都必须非常幸运才能获胜?
如果连接自然丢失,节点可以停止所有操作并尝试重新连接。使用较低的超时时间连接到节点意味着它不必导致任何停机时间(可能只是偶尔增加延迟)。如果重新连接失败,它将继续尝试,然后重新启动操作(假设节点已关闭)。这样的方法可以防止偶尔出现连接错误吗?
那么攻击者是否能够检测/导致网络分区?分区发生的可能性有多大,持续多长时间?如果可能的话,有什么方法可以解决问题?
谢谢。
答案1
我曾经在集群场景中处理过类似的问题,因此对您描述的情况很熟悉。此类系统通常具有仲裁的概念,这就是为什么此类系统需要奇数个成员节点。仲裁用于确定多数分区和少数分区。
仲裁数是一个大于一半的数字,它定义了提供服务所需的最小可用节点数。如果发生网络分区,则只有一个分区具有仲裁数,另一个分区将停止服务,直到分区消失。如果多个分区事件发生时,可能会导致根本不提供服务。但是,它确实保证只有一个节点在提供服务,这就是提供一致性的方式。
至于分区的可能性,这取决于您的基础设施以及您的节点如何相互传达可用性状态。
至于它们检测分区事件的能力,这取决于你的代码。使这种攻击成为可能的主要原因是两个分区都可独立寻址在分区期间,情况可能并非如此。根据我的经验,网络分区经常会将最终用户排除在一个分区以及其他节点之外。如果分区不可寻址,那么这种攻击成功的可能性就会大大降低。
答案2
分布式存储最适合每 n 秒复制一次单一数据来源,例如使用 SQL 索引和复制规则来推送数据。此外,中央内存“SQL”还用于控制状态。
简单地说,当您改变对象状态时,这会被传达给原始节点,并且事务会在 SQL 中使用记录锁来执行。
如果节点当时无法到达原点,则操作必然失败,因为原点状态仅在原点服务器上。
这类似于原点-边缘工作流,其中原点有“记忆” - 状态,而边缘有“内容” - 对象。
从理论上讲,在保持安全性的同时绕过上述边缘和中央存储器模型并以简单的方式实现这一目标是不可能的。上述模型是最有效和最正确的,对其进行模糊测试只会让事情变得困难。
答案3
如果您正在寻找一个实用的解决方案以允许交易在分区时继续进行,我有一个想法。
对于每个未使用的新数据记录,将其分配给单个节点。当网络被分区时,分配给可访问节点的数据记录是唯一允许客户端使用的数据记录。当分区解决时,所有节点都会重新同步已使用的数据记录。由于只有客户端可访问的模式才会使用分配给这些节点的记录,因此不应该有超额使用的记录。
必须考虑如何将记录分配给节点,以及在统一和分区操作期间当节点用完其自己的记录时该怎么办。