问题:从 Web 应用服务器到主服务器的请求应代理回 Web 应用服务器。因此,如果我从 Web 应用服务器向应用程序的域(或主服务器的公共 IP)执行请求,我希望获得一个实际的 Web 应用,就像我从互联网执行请求时获得的那样。
当请求来自外部时,一切正常。
来自 Internet 的对端口 80、443 的请求被代理到具有 Web 应用程序的服务器。防火墙现在如下所示:
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A PREROUTING -p tcp -i eth1 --dport 80 -j DNAT --to-destination 20.20.20.21:80
iptables -t nat -A PREROUTING -p tcp --dport 80 -s 20.20.20.21 -d 10.10.10.10 -j DNAT --to-destination 20.20.20.21:80
iptables -A FORWARD -p tcp -d 20.20.20.21 --dport 80 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
据我了解,我需要向 iptables 添加一条规则,以便从 20.20.20.21 到 10.10.10.10 的请求也代理到 10.10.10.10。
如果我是对的,请告诉我如何做到这一点,或者如何解决这个问题。
答案1
你正在做一些奇怪的事情。你可以做你想做的事,但你可能有一个XY问题,即这不是您需要解决的根本问题,但您正在尝试修复其他问题的错误解决方案。
我认为第三条规则就是你尝试解决这个问题。
您的第三条规则有效,它将一个数据包转换(src=20.20.20.21:x dst=10.10.10.10:80)
成一个数据包(src=20.20.20.21:x dst=20.20.20.21:80)
,然后将其路由到新的目的地。
当数据包到达 20.20.20.21 时,它会被立即丢弃,因为反向路径过滤器认为这是欺骗。我们假设它仍然被接受,但我们会回复给谁?数据包是(src=20.20.20.21:x dst=20.20.20.21:80)
,所以回复将是(src=20.20.20.21:80 dst=20.20.20.21:x)
。即使创建了,这样的回复数据包也永远不会离开 Web 框到达 NAT 框并被转换回来。
决议是翻译目的地和源对于这些数据包,因此 20.20.20.21 将看不到它是来自自身的数据包。必须更改数据包,以便回复将被路由回 NAT 框。可以使用以下附加规则来完成:
iptables -t nat -A POSTROUTING -s 20.20.20.21 -d 20.20.20.21 --dport 80 -j SNAT --to-source 10.10.10.10
笔记:
- 它正在进行 SNAT,因此位于 POSTROUTING 链中
- 它通过已经用 DNAT 转换的目标地址匹配数据包(您的第三条规则 - 它仍然是需要的!)
- 源地址被改为 NAT 盒的某个地址。20.20.20.20 代替 10.10.10.10 也同样有效。
20.20.20.21 会将此视为新数据包 (src=10.10.10.10:x dst=20.20.20.21:80),因此它会接受,并且回复将正确到达 NAT 盒。然后 NAT 将替换两个地址并将转换后的数据包返回到 Web 服务器盒。因此通信将成功。
正如我所说,这是一种非常奇怪的情况。虽然这可行,但要避免。不寻常的防火墙规则,难以理解,设计效率低下。
为什么 20.20.20.21 必须与本身通过它不拥有的地址,通过另一个系统?DNS 问题?您有一些hostname
,而某些(外部)DNS 服务器回答 10.10.10.10?那么你最好让内部 DNS 服务器只为本地网络回答 20.20.20.21,或者让 20.20.20.21 永远不做这样的 DNS 查询,而“只知道”hostname
由 20.20.20.21 提供服务,方法是在其文件中添加一行/etc/hosts
。该解决方案很可靠(某个名称由我提供服务?那么该名称属于我);它很容易理解。此外,它将绕过网络硬件并减少系统负载,并且它将运行得更快,因为本地数据包跳过了多层网络堆栈。
最后注意:如果这真的是完整的防火墙,并且过滤器 FORWARD 策略是 ACCEPT(默认),则第四条规则不起作用。无论哪种情况,最好将其删除。即使它不是完整的防火墙,最后一条规则看起来也很奇怪。为了给出更好的建议,我需要查看完整的防火墙(输出iptables-save
)。