为什么每个人都使用 MASQUERADE/SNAT 而不是 NAPT/PAT?

Ale*_*xis 3 nat

故事

我有一个 VPN 线卫虚拟接口wg0(可以是其他任何接口)和一个物理接口eth0。我想将数据包从 VPN 路由到 LAN,或者从一个接口路由到另一个接口。

几乎所有博客、文章、教程都建议使用MASQUERADESource NAT仅使用:iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

而且,IP masquerade只是一个SNAT(源NAT),它不会改变源端口。

问题

  • 我是否错误地认为我应该使用NAPT/PAT来代替?
  • 为了完整起见,如何使用 iptables 和/或 nftables 添加 NAPT/PAT 规则?

想法

主机生成并从wg0(或任何其他虚拟/物理接口)转发的数据包之间可能存在(源端口)冲突。恕我直言,必须使用 NAPT 来避免这些冲突。

RFC 2663,网络地址端口转换 (NAPT)

Nik*_*nov 9

您在某种程度上错误地区分了SNAT/MASQUERADENAPT/PAT。它不在那里。

在 Linux 中,有两种类型的动态 NAT 规则,都称为“NAPT”:

  • 源 NAT,旨在保持目标地址不变,仅更改地址。有时它也会改变源端口。例如,如果连接跟踪表已包含具有此特定(proto, src-addr, src-port, dst-addr, dst-port)元组的记录(src-addr 和 src-port 是翻译后的),则为了能够区分哪个是哪个,新的翻译必须使用另一个src端口(因为这是唯一的自由度),因此“NAPT”将不可避免地发生。SNAT 类型规则的示例是SNATMASQUERADE它们之间的区别在于,使用 SNAT 时,您需要在规则中指定要转换为哪个地址(以及可能要使用的端口范围),而使用 MASQUERADE 时,它会根据数据包的接口自行做出选择注定要出口。POSTROUTING在进行大多数其他处理(包括数据包的路由)之后,它们都将被安装到链中。这种类型的规则用于允许许多计算机隐藏在单个出口IP 地址后面,例如通过LAN 访问Internet 等。如果您打算通过 VPN 访问互联网,这也包括任何 VPN 用户。
  • 目标 NAT,它保留源地址不变,只更新目标地址,如果您配置了目标端口,那么这也是“NAPT”规则。这种类型的规则有DNAT,,可能REDIRECT还有CLUSTERIP其他一些,我不记得了;这些被安装到PREROUTING链中,因为路由决策通常应该在规则的影响下改变。最初发往机器本身(将其地址作为目的地)并要遍历INPUT并到达某个本地进程的数据包正在被转换,并且在遍历FORWARD链之后,它被进一步转发到某个其他系统。或相反亦然。去哪里,INPUT 或 FORWARD,是我们必须根据规则更改的路由决策。此类规则用于从 Internet 访问某些内部系统。

顺便说一句,有时,两个规则都可能用于单个数据包(和连接)。这是特殊情况,但如果您需要来自某个外部系统的数据包(因此必须在 PREROUTING 中使用 DNAT)显示为来自某个内部地址(在 POSTROUTING 中使用 SNAT),则很有用。

Linux中还有静态NAT类型的规则,NETMAP这种规则比较特殊,很少使用。我怀疑您是否在谈论它,并且您是否看过任何提及此类规则的指南。

Linux完全不区分私有地址 (RFC1918) 和公共地址。如果需要,您可以对公有子网进行 NAT(但这会浪费地址)。您可以保留私有 IP 而不进行转换(但这通常会导致它们无法连接互联网)。

VPN只不过是机器中的附加网络接口,应该这样对待。因此,如果您有公共地址,则可以使用 VPN 的公共地址。例如,我可能有一些 /29 子网由 VPN 路由器路由到并设置 OpenVPN,因此整个公共子网将是我的 VPN 网络!虽然 OpenVPN 示例看起来很人为,但 WireGuard更有可能是这样配置的。例如,新的命名空间解决方案允许wireguard成为系统中的唯一接口。如果系统需要直接拥有公共IP(我不会讨论此要求可能来自的任何原因),那么您最终将不可避免地在VPN内使用公共IP!最有可能的是,他们没有任何 NAT。

  • @Alexis“NAT”只是任何类型的网络和端口转换的标准通用行业术语。除非您正在编写 RFC,否则不需要明确区分 NAT、NAPT 和 PAT。(您还会看到人们谈论“全锥 NAT”和“对称 NAT”等。) (6认同)
  • 为什么你认为你遇到的定义是正确的,或者不可能有另一个定义?NAT 可以被定义,因此它也包括端口转换,并且*该*定义在 Linux 中使用,而不仅仅是在 Linux 中。实际上“严格”版本是相当不切实际的,因为现在 NAT 的普遍使用是允许许多机器使用单个公共 IP 地址访问互联网,并且这也*需要*端口转换,因为我在回答中提到的原因。因此,出于实际目的,更明智的做法是采用“包括”端口转换的 NAT 定义。 (4认同)
  • 定义正确词汇的不是您或 RFC。语言是一头活生生的野兽,我们似乎完全无法控制它;)这里唯一有效的是公众共识。 (2认同)

Dyl*_*lan 8

如果目标可以将其流量路由到源,则不需要 NAT 或 PAT。

例如,如果 10.8.0.0/24 中的 VPN 客户端想要与 192.168.1.0/24 中的 LAN 设备通信,则不需要 NAT/PAT,只要相关设备可以路由到其他网络(通过其网关) )。

当源位于 rfc1918(私有 IP)网络中且目标为公共 IP 时,由于 rfc1918 网络不可通过 Internet 路由,因此需要 NAT 将私有 IP 替换为公共 IP。这就是源地址转换。这项工作可以通过 SNAT 而不是 PAT 来完成。

此外,假设 SNAT/MASQUERADE 不会更改源端口是错误的。

--to-source 选项用于指定数据包应使用哪个源。最简单的是,此选项采用一个 IP 地址,我们希望将其用作 IP 标头中的源 IP 地址。如果我们想在多个 IP 地址之间进行平衡,我们可以使用一系列 IP 地址,并用连字符分隔。例如,--to--source IP 号码可能类似于上面的示例:194.236.50.155-194.236.50.160。然后,我们打开的每个流的源 IP 将从这些中随机分配,并且单个流将始终对该流中的所有数据包使用相同的 IP 地址。我们还可以指定 SNAT 使用的端口范围。所有源端口将被限制为指定的端口。规则的端口位将如上例所示:1024-32000。仅当在相关规则的匹配中的某处指定了 -p tcp 或 -p udp 时,这才有效。如果可能的话,iptables 将始终尝试避免进行任何端口更改,但如果两个主机尝试使用相同的端口,iptables 会将其中一个端口映射到另一个端口。如果未指定端口范围,则如果需要,所有低于 512 的源端口将映射到低于 512 的其他端口。源端口 512 和 1023 之间的端口将映射到低于 1024 的端口。所有其他端口将映射到1024或以上。如前所述,iptables 将始终尝试维护进行连接的实际工作站所使用的源端口。请注意,这与目标端口无关,因此如果客户端尝试与防火墙外部的 HTTP 服务器联系,则不会将其映射到 FTP 控制端口。

https://www.frozenux.net/iptables-tutorial/iptables-tutorial.html#SNATTARGET

请注意,如果您的设备想要访问给定目标端口上的远程服务器,则操作系统可能已经分配了超过 1024 的随机源端口。在端口 443 上访问远程 HTTPS 服务器并不涉及源端口是443.

  • @Alexis,说实话,你有点傻。[`iptables` 手册页](https://man7.org/linux/man-pages/man8/iptables-extensions.8.html) 说 `SNAT` 进行端口转换,而 `MASQUERADE` 是类似的。您链接到的 RFC 甚至没有提到这两个术语中的任何一个。因此,它的用途已被记录下来,而且 RFC 甚至没有使用相同的术语,因此它甚至不是一个超载的含义。那里没问题。如果您只想进行地址转换,那么您将不得不使用一些其他功能。`NETMAP` 看起来可能是一个,但我还没用过它。 (2认同)