民宿网站开发方案,自己做好的网站如何发布,辽宁移动惠生活app官方版,天津企业网站建设哪家好ebtables和iptables实用工具都使用了Netfilter框架#xff0c;这是它们一致的一方面#xff0c;然而对于这两者还真有一些需要联动的地方。很多人不明白ebtales的broute表的redirect和nat表PREROUTING的redirect的区别#xff0c;其实只要记住两点即可#xff0c;那就是对于… ebtables和iptables实用工具都使用了Netfilter框架这是它们一致的一方面然而对于这两者还真有一些需要联动的地方。很多人不明白ebtales的broute表的redirect和nat表PREROUTING的redirect的区别其实只要记住两点即可那就是对于相同点它们都将数据包导向了本地的IP层对于不同点broute表的redirect将数据包的接收设备设置成了实际接收数据的物理网卡而nat表将数据包的接收设备设置成了桥设备这个可以在Linux协议栈的源代码中看个究竟。对于broute表的redirect可以在br_handle_frame这个handle_bridge调用的回调函数中看到以下的语句switch (p-state) { case BR_STATE_FORWARDING: rhook rcu_dereference(br_should_route_hook); if (rhook ! NULL) { if (rhook(skb)) return skb; dest eth_hdr(skb)-h_dest; } /* fall through */ case BR_STATE_LEARNING: if (!compare_ether_addr(p-br-dev-dev_addr, dest)) skb-pkt_type PACKET_HOST; NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb-dev, NULL, br_handle_frame_finish); break; ... 我们看一下br_should_route_hook这个回调函数ebt_broutestatic int ebt_broute(struct sk_buff *skb) { int ret; ret ebt_do_table(NF_BR_BROUTING, skb, skb-dev, NULL, dev_net(skb-dev)-xt.broute_table); if (ret NF_DROP) return 1; /* route it */ return 0; /* bridge it */ } 它进入了我们都熟悉xxx_do_table函数这也就是常规的Netfilter规则查找操作最终在找到匹配规则时进入redirect这个target。如果没有broute表的规则则会进入NF_HOOK这个HOOK其间将会遍NF_BR_BROUTING所有的规则如果有target为redirect的规则命中则也会进入redirect这个target这个target是什么呢?是ebt_redirect_tg这个函数:static unsigned int ebt_redirect_tg(struct sk_buff *skb, const struct xt_target_param *par) { const struct ebt_redirect_info *info par-targinfo; if (!skb_make_writable(skb, 0)) return EBT_DROP; if (par-hooknum ! NF_BR_BROUTING) //如果是NAT的PREROUTING则将桥的MAC地址复制到数据包的目的MAC地址。 memcpy(eth_hdr(skb)-h_dest, par-in-br_port-br-dev-dev_addr, ETH_ALEN); else //如果是broute表的BROUTING则将实际接收数据包的物理网卡的MAC地址复制到数据包的目的MAC地址。 memcpy(eth_hdr(skb)-h_dest, par-in-dev_addr, ETH_ALEN); //本机可以接收该数据包 skb-pkt_type PACKET_HOST; //一般返回DROP return info-target; } 从br_handle_frame可以看出一旦broute表的匹配规则返回了DROP则handle_bridge直接返回这个skb不再向下执行这意味着skb将在handle_bridge返回后沿着netif_receive_skb继续走下去而如果没有匹配的broute表规则则可能在nat表的PREROUTING链中命中然后在执行了ebt_redirect_tg之后会调用br_handle_frame_finish继续下去在br_handle_frame_finish中由于目的MAC地址已经改成了本机网卡的MAC地址因此会调用br_pass_frame_up将数据包向协议栈的上层发送static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb) { struct net_device *indev, *brdev br-dev; brdev-stats.rx_packets; brdev-stats.rx_bytes skb-len; indev skb-dev; //将skb的dev修改成了brX这样在接下来经过LOCAL_IN之后再次调用netif_receive_skb之后在netif_receive_skb中就不会再次进入handle_bridge的 处理逻](我家小小按下的...)辑了。 skb-dev brdev; NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, netif_receive_skb); } 注意在broute表中的redrect之后数据包的接收设备是实际的物理网卡ethX目的MAC成了物理网卡ethX的MAC地址而在nat的PREROUTING的redirect之后数据包的接收设备是网桥设备目的MAC地址成了网桥设备的MAC地址知道了这个之后我们再看一下一个和iptables的nat表的redirect的问题。 设想一个配置本机S的eth0的IP地址为1.1.1.254/24其上开启tcp的88端口和本机直连的一台主机H的IP地址为1.1.1.2/24在S上配置brctl addbr br0 brctl addif eth0 ifconfig br0 1.1.1.254/24 ifcongig eth0 0.0.0.0 #为了防止路由乱掉因此删除eth0的IP地址 iptables -t nat -A PREROUTING -d 2.2.2.2 -p tcp --dport 1234 -j REDIRECT --to-ports 88 在H上执行route add -host 2.2.2.2 gw 1.1.1.254 telnet 2.2.2.2 1234 结果呢不通连syn-ack都没有收到然而在S上删除REDIRECT规则而执行以下规则则是可以的iptables -t nat -A PREROUTING -d 2.2.2.2 -p tcp --dport 1234 -j DNAT --to-destination 1.1.1.254:88 难道DNAT和REDIRECT有什么区别吗如果你不明白这两者有什么区别那么如果你知道SNAT和MASQUERADE的区别也不错起码能帮助你理解。DNAT和SNAT能指定任意的源地址一样可以指定任意的目的地址那么REDIRECT则和MASQUERADE也类似它只是内核根据自己的策略而选择出的一个目的地址正如MASQUERADE也是内核根据RFC的建议以及自己的策略选择出的一个源地址一样。那么如何来选择REDIRECT的目的地址呢看一下iptables的man手册就知道了REDIRECTThis target is only valid in the nat table, in the PREROUTING and OUTPUT chains, and user-defined chains which are only called from those chains. It redirects the packet to the machine itself by changing the destination IP to the primary address of the incoming interface (locally-generated packets are mapped to the 127.0.0.1 address). 特别要注意的是“to the primary address of the incoming interface”这一句。内核中的REDIRECT规则是如何做到这点的呢这还要看一下代码才知道static unsigned int redirect_tg(struct sk_buff *skb, const struct xt_target_param *par) { ... if (par-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); //取出接收设备的IP地址 if (indev (ifa indev-ifa_list)) newdst ifa-ifa_local; rcu_read_unlock(); //如果接收设备没有IP地址则丢弃数据包 if (!newdst) return NF_DROP; } ... return nf_nat_setup_info(ct, newrange, IP_NAT_MANIP_DST); } 这下我们就一切都明白了既然broute表的redirect将接收设备设置为实际的物理网卡而此网卡的IP地址已经被删除那么上述函数的newdst当然不存在了因此数据包就被DROP掉了到此为止问题就很清晰了。可见ebtables的redirect方式直接影响到了iptables的redirect为了让iptables的redirect在使用bridge时仍然随时可行则必须为使能broute redirect的网卡上设置IP地址为了不使路由冲突考虑127.0.0.2...注broute表的意义为何会有这样的问题broute是原因。所谓的broute则是bridge or router类似早先安装宽带时运营商送的那种猫能作为桥设备也能作为路由器。如果作为路由器根本不存在桥设备这一说因此将接收设备设置为实际的物理网卡也是理所当然的啦。 本文转自 dog250 51CTO博客原文链接:http://blog.51cto.com/dog250/1269005