在设置我们的OpenStack环境时,遇到了阻止实例联系在主机上运行的服务器的问题。 元数据服务(暴露HTTP API)在主机上的端口8775上运行,OpenStacknetworking代码添加以下DNAT规则,通过端口80上的特殊地址授予访问权限:
-A PREROUTING -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j DNAT --to-destination 127.0.0.1:8775
实例通过本地桥接设备连接到主机,并将169.254.169.254分配给lo 。
虽然这条规则成功地匹配来自试图访问http://169.254.168.254/的访客实例的数据包,但是他们从未到达侦听服务。
用一个基本上等效的REDIRECT来replace这个DNAT规则会使所有事情都正常工作:
-A PREROUTING -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8775
我试图理解为什么REDIRECT工作和DNAT失败。 从iptables文档中不清楚DNAT规则是否适用于本地目的地stream量。 我希望这里有人可以提供一个权威的答案,理想的文件备份,或者可以build议什么可能是我的configuration错误,阻止DNAT规则按预期工作。
你正在试图做的是被内核明确的拒绝 。
您不能将数据包从非127/8地址发送到127/8。 内核将它们过滤掉,并将它们视为“火星人”。
这可能是因为rp_filter默认打开。 可能禁用它可能会改变这种行为(尽pipe这将禁用一些潜在的重要安全保护)。
使用REDIRECT,你不会改变IP,这就是为什么它可以工作。 换句话说,如果你打算使用DNAT,你可以把它发送到127.0.0.0/8 之外的任何地方 。
根据netfilter NAT HOWTO的说法:
有一种称为redirect的目的地NAT的特殊情况:这是一个简单的方便,正好相当于对input接口的地址做DNAT。
它稍微更智能,因为它selectDNAT目标地址作为接收数据包的设备的地址。 在你的情况下,它将DNAT数据包到桥设备的地址,而不是127.0.0.1。