从 LAN 内部访问 DNAT 网络服务器

whi*_*ark 13 linux nat iptables

我有一个带有路由器的小型网络,它与 Internet、服务器和本地网络中的一些工作站保持连接。

网络地图

服务器旨在从 Internet 访问,并且在路由器 iptables 中设置了几个 DNAT 条目,如下所示:

-A PREROUTING -i ppp0 -p tcp -m multiport --dports 22,25,80,443 -j DNAT --to-destination 192.168.2.10
Run Code Online (Sandbox Code Playgroud)

外部数据包通过ppp0接口到达路由器,内部数据包来自br-lan,实际上包括交换机和 WLAN 适配器。问题是,虽然外部访问工作正常,但尝试通过 DNS 解析的外部 IP(分配给ppp0)从 LAN 内部访问服务器失败。

我能够发明的唯一解决方案是向路由器添加/etc/hosts指向内部 IP 的静态条目,但由于没有通配符(并且我至少为该系统分配了三个顶级域,不包括数十个子域),这相当脆而且容易失败。你能提出更好的建议吗?

我只找到了这个问题,这不是很有帮助。

如果这是相关的,路由器运行带有 dnsmasq 的 OpenWRT 10.03 Kamikaze。

Ste*_*day 18

我删除了我原来的答案,因为我并不完全相信它是正确的。从那以后,我有一些时间来设置一个小的虚拟机虚拟网络来模拟有问题的网络。这是对我有用的防火墙规则集(iptables-save格式,nat仅适用于表格):

-A PREROUTING -d 89.179.245.232/32 -p tcp -m multiport --dports 22,25,80,443 -j DNAT --to-destination 192.168.2.10
-A POSTROUTING -s 192.168.2.0/24 -o ppp0 -j MASQUERADE
-A POSTROUTING -s 192.168.2.0/24 -d 192.168.2.10/32 -p tcp -m multiport --dports 22,25,80,443 -j MASQUERADE
Run Code Online (Sandbox Code Playgroud)

第一条POSTROUTING规则是与 LAN 共享 Internet 连接的简单方法。我把它留在那里是为了完整性。

PREROUTING规则和第二条POSTROUTING规则共同建立了适当的 NAT,以便通过外部 IP 地址连接到服务器,无论连接是来自外部还是来自 LAN 内部。当 LAN 上的客户端通过外部 IP 地址连接到服务器时,服务器将连接视为来自路由器的内部 IP 地址 (192.168.2.1)。

有趣的是,事实证明,第二个 POSTROUTING 规则有几个变体也有效。如果目标更改为-j SNAT --to-source 192.168.2.1,效果(不出所料)与以下相同MASQUERADE:服务器将来自本地 LAN 客户端的连接视为源自路由器的内部IP 地址。另一方面,如果目标更改为-j SNAT --to-source 89.179.245.232,则 NAT 仍然有效,但这次服务器将本地 LAN 客户端的连接视为源自路由器的外部IP 地址 (89.179.245.232)。

最后,请注意您的原始PREROUTING/DNAT规则-i ppp0不起作用,因为该规则永远不会匹配来自 LAN 客户端的数据包(因为这些数据包不会通过ppp0接口进入路由器)。可以通过PREROUTING为内部 LAN 客户端添加第二条规则来使其工作,但这会显得不够优雅 (IMO),并且仍需要明确引用外部 IP 地址。

现在,即使在详细地布置了“发夹式 NAT”(或“NAT 环回”或“NAT 反射”,或任何人喜欢称之为)解决方案之后,我仍然相信水平分割 DNS 解决方案—— - 外部客户端解析为外部 IP,内部客户端解析为内部 IP---将是更可取的路由。为什么?因为了解 DNS 工作原理的人多于了解 NAT 工作原理的人,而且构建良好系统的很大一部分是选择使用可维护的部分。与神秘的 NAT 设置(当然,IMO)相比,DNS 设置更容易被理解并因此得到正确维护。


小智 6

我很惊讶,在将近 8 年之后,没有人解释如何使用 OpenWRT 中默认使用的 UCI 配置系统以正确的方式做到这一点。

Steven Monday 的回答是正确的,但它iptables直接使用命令,这是比 UCI 配置系统更低的层,如果可能的话,大多数 OpenWRT 用户最好不要接触它。

从 UCI 中的另一台内部主机通过公共 IP/端口组合访问内部服务器的正确方法是启用reflection文件中每个特定 DNAT 目标下的配置选项/etc/config/firewall此处记录此行为。

例如:

config redirect option target 'DNAT' option src 'wan' option dest 'lan' option proto 'tcp' option src_dport '44322' option dest_ip '192.168.5.22' option dest_port '443' option name 'apache HTTPS server' option reflection '1'

注意:根据指示的 OpenWRT 文档,reflection默认启用。在我的测试中,情况并非如此。