故事
我有一个 VPN wireguard 虚拟接口wg0
(可以是任何其他接口)和一个物理接口eth0
。我想将数据包从 VPN 路由到我的 LAN,或者从一个接口路由到另一个接口。
几乎所有的博客、文章、教程都建议使用MASQUERADE
或Source NAT
仅使用:iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
而且,IP masquerade
它只是一个SNAT(源NAT),它不会改变源端口。
问题
- 我是不是错了,认为我应该使用副乳/乳糖反而?
- 为了完整起见,如何使用 iptables 和/或 nftables 添加 NAPT/PAT 规则?
思考
主机生成并从wg0
(或任何其他虚拟/物理接口)转发的数据包之间可能存在(源端口)冲突。 IMHO 必须使用 NAPT 来避免这些冲突。
答案1
如果目的地可以将其流量路由到源,则不需要 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 号码可以是上例中的 IP 地址:194.236.50.155-194.236.50.160。我们打开的每个流的源 IP 将从这些 IP 地址中随机分配,单个流将始终对该流中的所有数据包使用相同的 IP 地址。我们还可以指定 SNAT 要使用的一系列端口。然后,所有源端口都将限制在指定的端口内。规则的端口位将如上例所示:1024-32000。这仅在相关规则的匹配中指定了 -p tcp 或 -p udp 时才有效。如果可能的话,iptables 总是会尽量避免更改端口,但如果两个主机尝试使用相同的端口,iptables 会将其中一个映射到另一个端口。如果没有指定端口范围,则如果需要,所有低于 512 的源端口都将映射到其他低于 512 的端口。源端口 512 和 1023 之间的端口将映射到低于 1024 的端口。所有其他端口将映射到 1024 或更高端口。如前所述,iptables 将始终尝试维护实际建立连接的工作站使用的源端口。请注意,这与目标端口无关,因此如果客户端尝试与防火墙外的 HTTP 服务器建立联系,它将不会被映射到 FTP 控制端口。
https://www.frozentux.net/iptables-tutorial/iptables-tutorial.html#SNATTARGET
请注意,如果您的设备想要通过给定的目标端口访问远程服务器,则操作系统很可能已经分配了超过 1024 的随机源端口。通过端口 443 访问远程 HTTPS 服务器,并不涉及源端口是否为 443。
答案2
您对 和 的区分有些错误。SNAT/MASQUERADE
和之间NAPT/PAT
没有区别。
在 Linux 中,有两种类型的动态 NAT 规则,它们都称为“NAPT”:
- 源 NAT,其目的是保持目标地址不变,只改变来源地址。有时将要还可以更改源端口。例如,如果连接跟踪表已经包含此特定(协议、源地址、源端口、目标地址、目标端口)元组(src-addr 和 src-port 在转换之后),为了能够区分哪个是哪个,新的转换必须使用另一个 src 端口(因为这是唯一的自由度),因此“NAPT”将不可避免地发生。SNAT 类型规则的示例是
SNAT
和MASQUERADE
。它们之间的区别在于,使用 SNAT 时,您需要指定在规则中转换到哪个地址(可能还要使用哪个端口范围),而使用 MASQUERADE 时,它会根据数据包要从哪个接口发出来自行做出选择。POSTROUTING
在完成大多数其他处理(包括数据包的路由)之后,它们都将安装到链中。这种类型的规则用于允许多台计算机隐藏在单个出口 IP 地址后面,例如,用于 LAN 访问 Internet 等。如果您打算通过 VPN 访问 Internet,这也将包括任何 VPN 用户。 - 目标 NAT,它保留源地址不变,只更新目的地地址,以及(如果您配置了)目标端口,因此这也是“NAPT”规则。这种类型的规则有、,
DNAT
可能还有其他一些,我不记得全部了;这些规则都安装在链中,因为路由决策通常应该在规则的影响下进行更改。最初发往机器本身(将其地址作为目的地)并要经过遍历并到达某个本地进程的数据包正在被翻译,并且在经过链之后,它将被进一步转发到其他系统。反之亦然。去哪里,INPUT 还是 FORWARD,是我们必须使用规则更改的路由决策。这种类型的规则用于从 Internet 访问某些内部系统。REDIRECT
CLUSTERIP
PREROUTING
INPUT
FORWARD
顺便说一下,有时候两个都规则可能用于单个数据包(和连接)。这是特殊情况,但如果您需要来自某个外部系统的数据包(因此必须在 PREROUTING 中使用 DNAT)显示为来自某个内部地址(为此在 POSTROUTING 中使用 SNAT),则很有用。
在 Linux 中,还有静态 NAT 类型的规则,NETMAP
这种规则非常特殊,很少使用。我怀疑您是在谈论它,也不知道您是否见过任何提及此类规则的指南。
Linux 使完全没有区别私有 (RFC1918) 地址和公共地址之间。您可以根据需要对公共子网进行 NAT(但这会浪费地址)。您可以保留私有 IP 而不进行转换(但这通常会导致它们无法连接到 Internet)。
VPN 只不过是机器中的附加网络接口,应该这样对待。因此,如果您有公共地址,则可以使用它们作为 VPN。例如,我可能有一些由 VPN 路由器路由到的 /29 子网,并设置 OpenVPN,因此整个公共子网将是我的 VPN 网络!虽然 OpenVPN 示例看起来很虚假,但 WireGuard 是很多更有可能被这样配置。例如,新的命名空间解决方案允许 wireguard 成为系统中唯一的接口。如果系统需要直接拥有公共 IP(我不会讨论此要求可能来自的任何原因),那么您最终不可避免地会在 VPN 内使用公共 IP!最有可能的是,它们没有任何 NAT。