NAT 上的去中心化应用

Decentralized Application over NAT

我目前正在使用golang 编写一个P2P 应用程序。为此,我选择了 Noise,因为它提供了一个易于使用的网络堆栈。

我的应用程序提供了一个可以通过 localhost 访问的 REST API。发送到本地提供的端点的数据随后将传输到所有连接的对等点,然后将数据分发到其连接的对等点以保持网络同步。

到目前为止,我的实现已经成功,但这只适用于公开暴露的节点或同一网络中的节点。

我希望尽可能简单地使用我的应用程序,对于专用网络中的用户也是如此。因此我想避免手动配置开销(即路由器设置中的端口转发)。如果可能的话,我也想避免使用中央服务器进行 NAT 穿越,因为我的目标是拥有一个真正去中心化的应用程序。

我知道有几种 NAT 穿越技术,例如 STUN and TURN, alongside others, and I am aware that Noise offers already NAT-PMP and UPnP,但不知何故我无法理解它们的工作原理。

我知道,一些 VoIP 或文件共享服务使用 NAT-PMP,它们似乎可以在几乎所有网络上运行,无需任何用户交互。这对我来说似乎有点奇怪,我被卡住了。

我的应用程序怎么可能只是神奇地更改了一些路由器配置以接受传入流量?对我来说,这似乎是一个巨大的安全风险,特别是如果我的应用程序的用户甚至不知道它。此外,我认为并非每个路由器都支持 NAT-PMP 和 UPnP。如果我的用户有其中之一怎么办?

没有 public 中央目录服务器,这是不可能的。对等点无法相互识别。这并不意味着服务器必须参与任何对等通信。我只允许发现进入 p2p 网络的入口点。

On NAT-transversal:UPNP 是零配置的唯一方法。请注意,主要问题不是 NAT,而是防火墙配置。出于安全考虑,大多数专用防火墙(非家用路由器)不支持 UPNP。他们仍然可以建立传出连接。

How is it possible, that my application just magically changes some Router configurations to accept incoming traffic? To me that seems to be a huge security risk, especially if the user of my application does not even know about it.

打开一个传入端口只会让你变得不安全,就像侦听它的特定应用程序的网络堆栈一样,这种不安全的可能性与 client-server 模型并没有什么不同。

以您的浏览器为例。每当您访问某个包含广告网络的随机 Internet 站点时,某些恶意实体可能会放置指向其服务器的广告。如果您的浏览器存在漏洞,则可能会被利用。

如果您的 P2P 应用程序没有打开端口,它仍然会建立到 P2P 网络中各个节点的传出连接,如果其中一个是恶意的并且您的应用程序容易受到攻击,那么它就可以被利用。

为传入连接打开端口只会改变目前的等式,攻击者可以利用某些类型的漏洞(通常是网络堆栈中的低层,连接设置的早期,例如 pre-auth 消息解析)不用等你过来,他们就可以拜访你。这是一个区别,但实际上是一个相当小的区别。

有人 无论如何都必须打开他们的端口,否则互联网上的任何人都无法与其他人交谈。

归根结底,更重要的是集中精力加强应该暴露在互联网上的应用程序的网络堆栈。

防火墙的好处主要在于避免意外暴露未在编写时考虑到安全性的服务,无论是遗留服务还是仅仅假设只有内部用户才能访问它们。它们减少了不必要的攻击面

NAT-PMP 和另一方面的类似存在允许您创建 必要的攻击面 ,只是因为如果没有使用网络的能力,应用程序将无法正常运行.

Also, I figured that not every Router supports NAT-PMP and UPnP. What if my users have one of those?

UDP打洞是一种不需要路由器配合的NAT穿越策略

此外,您可以要求用户手动调整他们的 firewalls/port 转发规则。

但如果所有 nat 遍历策略都失败,那么下一个问题是直接 peer-peer 连接是否是您的协议工作所必需的。例如在 bittorrent 中它们不是,在这种情况下形成一个连接图就足够了,而不是一个完全连接的图。 类似的事情也适用于群聊。

对于 one-on-one 通信,您可以选择通知用户他们的网络正在阻止连接或利用无私(或 paid-for)节点提供数据中继服务。