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