iptables:允许从本地网络内部转发到 WAN 接口的端口

iptables:允许从本地网络内部转发到 WAN 接口的端口

我知道这个问题已经存在十几种形式,但大多数是关于商业 wifi 路由器等的。

我有一个 Ubuntu 20.04LTS 盒子,上面有一堆接口设置为防火墙/NAT 盒,其中一个接口是 WAN 接口。

我在 WAN 接口(enp4s0f0)上有许多到不同内部主机的端口转发,规则如下(顺便说一下,下面所有规则都在“nat”链上):

-A PREROUTING -i enp4s0f0 -p tcp -m tcp --dport 8181 -j DNAT --to-destination 10.0.0.50:22

(将端口 8181 处的传入 WAN 连接转发到主机 10.0.0.50,ssh 端口)

但是,如果我在内部主机上,我也希望能够到达此端口转发,而无需明确转到其他内部主机,例如,我有一个已经指向 WAN IP 的 DNS。“开箱即用”这不起作用(我猜是因为 WAN if 的明确接口规范),所以我尝试向 iptables 添加内容,但我添加的两个额外规则似乎都不起作用:

  1. -A PREROUTING -d -p tcp --dport 8181 -j DNAT --到目的地 10.0.0.50:22

  2. -A PREROUTING -i enp3s0f0 -p tcp --dport 8181 -j DNAT --to-destination 10.0.0.50:22

(enp3s0f0是内网LAN接口)

我想我在这里错过了一些简单的魔法。

如果有一条“捕获所有”规则,让所有来自内部 LAN 并发往 WAN 接口的数据包都到达那里,那就太好了WAN=>LAN 端口转发规则生效,那么每当我添加 WAN 端口转发时,我就不必担心设置新的匹配的额外规则。

更新:也许我原来的端口转发规则应该更改,现在明确指定 WAN eth 接口名称。我从许多教程中获得了此设置,它对外部客户端来说运行良好。

答案1

这个问题的通常答案是“您需要 NAT 环回/NAT 发夹”。

正如一些答案中提到的,环回 NAT 的实际问题是来源此类“环回端口转发”连接的 IP 地址(即客户端的 LAN 地址)被视为目标服务器的本地地址(位于同一个 LAN 中),这会导致直接向客户端发送回复,而不是通过路由器。

那么“发夹弯”解决方法的作用是对源地址也进行 NAT。这不仅仅是对 DNAT 规则的修改,而是一个完全独立的源地址转换需要应用于相同数据包的规则。(不过,您也需要放宽-iDNAT 规则的匹配。)

-A POSTROUTING -o enp3s0f0 -s 10.0.0.0/24 -j MASQUERADE
[或者]
-A POSTROUTING -o enp3s0f0 -m conntrack --ctstate DNAT -j MASQUERADE

(如果我没记错的话,iptables 不允许-i在 POSTROUTING 中匹配,尽管这在这里很有用。)

如果您的客户端和服务器位于不同的 LAN 子网(例如不同的 VLAN 或只是外部路由器上的不同以太网接口),则 SNAT 解决方法是不必要的,因为无论如何,它们之间的流量总是会通过路由器。


更详细地:

  1. 客户端发送请求“客户端→WANip”。该请求发往路由器的 MAC。
  2. 路由器将其 DNAT 变为“客户端→服务器”并将其转发到服务器。
  3. 服务器收到“客户端→服务器”请求,然后发送“服务器→客户端”回复。该回复直接发送到客户端的 MAC,绕过路由器,因此 DNAT 不会被撤销。
  4. 客户端收到回复“服务器→客户端”,该回复与任何已知连接都不匹配 - 客户端原本期望收到“WANip→客户端” - 因此客户端丢弃收到的回复。

使用 SNAT 解决方法:

  1. 客户端发送请求“客户端→WANip”。该请求发往路由器的 MAC。
  2. 路由器将其 DNAT 为“客户端→服务器”,然后此外SNAT 使其看起来像“路由器→服务器”,然后将其转发到服务器。
  3. 服务器收到“路由器→服务器”请求,并发送“服务器→路由器”回复。该回复将发送到路由器的 MAC。
  4. 路由器收到“服务器→路由器”的答复,将其取消 SNAT 变为“服务器→客户端”,取消 DNAT 变为“WANip→客户端”,然后转发给客户端。
  5. 客户端收到与原始请求匹配的回复“WANip→client”。

相关内容