假设我有两个物理接口 eth1 和 eth2。
eth1已分配192.168.0.1
eth2已分配192.168.0.2
一个本地进程侦听 192.168.0.2,另一个本地进程从 192.168.0.1 连接。
ip包是否经过iptable的OUTPUT和INPUT链,或者是否存在某种短路?它是否经过FORWARD链?
答案1
交通按照既定路线行驶。
那么如何知道会是哪一个呢?通过检查路线。这里是从属于主机的地址到属于主机的地址。这总是会导致选择lo
(环回)接口,因为在这种情况下不需要涉及任何 NIC 硬件:
如果客户端确实先绑定到 192.168.0.1(很少这样做):
$ ip route get from 192.168.0.1 to 192.168.0.2
local 192.168.0.2 from 192.168.0.1 dev lo uid 1000
cache <local>
通常会发生这种情况(但总体结果相同):
$ ip route get to 192.168.0.2
local 192.168.0.2 dev lo src 192.168.0.2 uid 1000
cache <local>
强调这个结果的结论:这样的流量绝不使用eth0
或eth1
但将使用lo
.
了解 Netfilter 如何(从而iptables)沿着网络堆栈(这里是路由堆栈部分)工作:
经过简·恩格尔哈特- 自己的作品,起源静止无功发生器 巴布亚新几内亚,抄送-SA 3.0,关联
本地应用程序将发出一个数据包:这就是过滤器/输出链。它还遍历其他链(其他 OUTPUT,然后是 POSTROUTING 链),但我们只关注过滤表。该数据包被环回:这是接口的特殊属性lo
。它到达时就像路由堆栈中的新数据包一样,因此遵循 PREROUTING 处理(但 PREROUTING 链不与过滤器表挂钩)得到路由决策:它是本地目标数据包,因此也遵循 INPUT 分支。数据包到达目标应用程序。
基于标准Linux状态防火墙iptables至少使用以下规则(我使用-I
+数字来强制规则的顺序,通常-A
使用):
iptables -I INPUT 1 -m conntrack --ctstate established,related -j ACCEPT
iptables -I INPUT 2 -i lo -j ACCEPT
然后通常其策略设置为 DROP:
iptables -P INPUT DROP
第二条规则虽然可能被认为是某种环境的安全弱点,但它经常存在并且是必需的,因为许多希望能够通过环回接口进行通信的应用程序可能会在没有它的情况下失败。
因此,任何需要阻止此类使用的规则都应插入到第二条规则之前。此外,任何基于接口而不是该接口上的地址的规则都将无法解决本地情况。
因此,如果删除第二条规则:
iptables -D INPUT -i lo -j ACCEPT
然后例如允许与 OP 示例一起使用的 HTTP 服务例外:
错误(与OP的情况不匹配):
iptables -I INPUT 2 -i eth2 -p tcp --dport 80 -j ACCEPT
可接受:
iptables -I INPUT 2 -d 192.168.0.2 -p tcp --dport 80 -j ACCEPT
也可以接受(并且通常这样做):
iptables -I INPUT 2 -i lo -j ACCEPT iptables -I INPUT 3 -i eth2 -p tcp --dport 80 -j ACCEPT
请注意,它并不完全等效。例如,来自侧面的客户端eth1
无法使用情况 3 访问 HTTP 服务,而使用情况 2 可以访问它。同样,如果侦听服务侦听 INADDR_ANY (0.0.0.0) 而不仅仅是 192.168.0.2,则访问 127.0 .0.1 在情况 2 中不起作用,但在情况 3 中起作用。