iptables将目标REDIRECT放在没有IP的网桥上

我有一个像这样的中间人设置:

A <—> B <—> C

其中A,B和C是计算机,箭头表示以太网连接。

A具有IP 10.0.0.10,C具有IP 10.0.0.9

都有一个255.255.255.0的networking掩码

我正在尝试在B上使用没有configurationIP的linux网桥来实现一个bump-in-the-wire防火墙,如下所示:

brctl addbr br brctl addif chlep1 brctl addif chlep2 ifconfig br 0.0.0.0 up 

为了从A到CI上configurationIptables的连接,就像这样

 sysctl net.bridge.bridge-nf-call-arptables=1 sysctl net.bridge.bridge-nf-call-ip6tables=1 sysctl net.bridge.bridge-nf-call-iptables=1 iptables -t nat -I PREROUTING -p tcp -s 10.0.0.10 -d 10.0.0.9 -j REDIRECT --to-ports 40000 iptables -t nat -A PREROUTING -p tcp -s 10.0.0.10 -d 10.0.0.9 -j LOG iptables -t filter -A INPUT -p tcp -s 10.0.0.10 -j LOG iptables -t filter -A FORWARD -p tcp -s 10.0.0.10 -j LOG 

我在C和B上打开了一个监听套接字

 python Python 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import socket >>> sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM,0) >>> sk.bind(('0.0.0.0',40000)) >>> sk.listen(1) >>> conn, addr = sk.accept() 

然后在AI跑了

 python Python 2.7.5 (default, Nov 6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import socket >>> sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM,0) >>> sk.connect(('10.0.0.9',40000)) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/socket.py", line 224, in meth return getattr(self._sock,name)(*args) socket.error: [Errno 110] Connection timed out >>> 

检查Iptables在BI接收上的规则数据包数量

 [root@ace ~]# iptables -t nat -vL Chain PREROUTING (policy ACCEPT 269 packets, 64867 bytes) pkts bytes target prot opt in out source destination 4 240 REDIRECT tcp -- any any 10.0.0.10 10.0.0.9 redir ports 40000 0 0 LOG tcp -- any any 10.0.0.10 10.0.0.9 LOG level warning Chain INPUT (policy ACCEPT 22 packets, 3425 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 1 packets, 76 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 2 packets, 160 bytes) pkts bytes target prot opt in out source destination [root@ace ~]# [root@ace ~]# [root@ace ~]# [root@ace ~]# [root@ace ~]# iptables -t filter -vL Chain INPUT (policy ACCEPT 456 packets, 28706 bytes) pkts bytes target prot opt in out source destination 0 0 LOG tcp -- any any 10.0.0.10 anywhere LOG level warning Chain FORWARD (policy ACCEPT 8 packets, 672 bytes) pkts bytes target prot opt in out source destination 0 0 LOG tcp -- any any 10.0.0.10 anywhere LOG level warning Chain OUTPUT (policy ACCEPT 240 packets, 19382 bytes) pkts bytes target prot opt in out source destination 

dmesg是空的。

为什么我不劫持连接? 注意:我能够劫持连接,如果我configuration一个IP地址桥,我宁愿避免

一些内核挖掘后发现这个。

实际的iptables REDIRECTing代码是在一个名为nf_nat_redirect_ipv4的内核netfilter钩子中实现的 ,在这个钩子中我们find了这个相对简单的代码

 ... /* Local packets: make them go to loopback */ if (hooknum == NF_INET_LOCAL_OUT) { newdst = htonl(0x7F000001); } else { struct in_device *indev; struct in_ifaddr *ifa; newdst = 0; rcu_read_lock(); indev = __in_dev_get_rcu(skb->dev); if (indev && indev->ifa_list) { ifa = indev->ifa_list; newdst = ifa->ifa_local; } rcu_read_unlock(); if (!newdst) return NF_DROP; } ... 

让我们把这个分开

 ... if (hooknum == NF_INET_LOCAL_OUT) { newdst = htonl(0x7F000001); } ... 

如果我们的REDIRECT来自OUTPUT链,则数据包的目标地址改变为回送地址('127.0.0.1')

 ... else { struct in_device *indev; struct in_ifaddr *ifa; newdst = 0; rcu_read_lock(); indev = __in_dev_get_rcu(skb->dev); if (indev && indev->ifa_list) { ifa = indev->ifa_list; newdst = ifa->ifa_local; } rcu_read_unlock(); ... 

如果我们来自另一个链(只有PREROUTING,因为我们已经处理了OUTPUT),我们将数据包的目标地址设置为本地设备的地址,我们的将是0

  ... if (!newdst) return NF_DROP; } ... 

一个零地址被认为是一个错误值,我们的数据包可悲地下降:(