日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

ebtables之BROUTING和PREROUTING的redirect的区别

發(fā)布時間:2023/11/29 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ebtables之BROUTING和PREROUTING的redirect的区别 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
ebtables和iptables實用工具都使用了Netfilter框架,這是它們一致的一方面,然而對于這兩者還真有一些需要聯(lián)動的地方。很多人不明白ebtales的broute表的redirect和nat表PREROUTING的redirect的區(qū)別,其實只要記住兩點即可,那就是對于相同點,它們都將數(shù)據(jù)包導(dǎo)向了本地的IP層;對于不同點,broute表的redirect將數(shù)據(jù)包的接收設(shè)備設(shè)置成了實際接收數(shù)據(jù)的物理網(wǎng)卡,而nat表將數(shù)據(jù)包的接收設(shè)備設(shè)置成了橋設(shè)備,這個可以在Linux協(xié)議棧的源代碼中看個究竟。對于broute表的redirect,可以在br_handle_frame這個handle_bridge調(diào)用的回調(diào)函數(shù)中看到以下的語句:
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這個回調(diào)函數(shù)ebt_broute:
static 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 */ } 它進(jìn)入了我們都熟悉xxx_do_table函數(shù),這也就是常規(guī)的Netfilter規(guī)則查找操作,最終在找到匹配規(guī)則時,進(jìn)入redirect這個target。如果沒有broute表的規(guī)則,則會進(jìn)入NF_HOOK這個HOOK,其間將會遍NF_BR_BROUTING所有的規(guī)則,如果有target為redirect的規(guī)則命中,則也會進(jìn)入redirect這個target,這個target是什么呢?是ebt_redirect_tg這個函數(shù):
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地址復(fù)制到數(shù)據(jù)包的目的MAC地址。 memcpy(eth_hdr(skb)->h_dest, par->in->br_port->br->dev->dev_addr, ETH_ALEN); else //如果是broute表的BROUTING,則將實際接收數(shù)據(jù)包的物理網(wǎng)卡的MAC地址復(fù)制到數(shù)據(jù)包的目的MAC地址。 memcpy(eth_hdr(skb)->h_dest, par->in->dev_addr, ETH_ALEN); //本機(jī)可以接收該數(shù)據(jù)包 skb->pkt_type = PACKET_HOST; //一般返回DROP return info->target; } 從br_handle_frame可以看出,一旦broute表的匹配規(guī)則返回了DROP,則handle_bridge直接返回這個skb,不再向下執(zhí)行,這意味著skb將在handle_bridge返回后沿著netif_receive_skb繼續(xù)走下去,而如果沒有匹配的broute表規(guī)則,則可能在nat表的PREROUTING鏈中命中,然后在執(zhí)行了ebt_redirect_tg之后會調(diào)用br_handle_frame_finish繼續(xù)下去,在br_handle_frame_finish中,由于目的MAC地址已經(jīng)改成了本機(jī)網(wǎng)卡的MAC地址,因此會調(diào)用br_pass_frame_up將數(shù)據(jù)包向協(xié)議棧的上層發(fā)送:
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,這樣在接下來經(jīng)過LOCAL_IN之后再次調(diào)用netif_receive_skb之后,在netif_receive_skb中就不會再次進(jìn)入handle_bridge的 處理邏](我家小小按下的...)輯了。 skb->dev = brdev; NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL, netif_receive_skb); } 注意,在broute表中的redrect之后,數(shù)據(jù)包的接收設(shè)備是實際的物理網(wǎng)卡ethX,目的MAC成了物理網(wǎng)卡ethX的MAC地址,而在nat的PREROUTING的redirect之后,數(shù)據(jù)包的接收設(shè)備是網(wǎng)橋設(shè)備,目的MAC地址成了網(wǎng)橋設(shè)備的MAC地址,知道了這個之后,我們再看一下一個和iptables的nat表的redirect的問題。
??? 設(shè)想一個配置,本機(jī)S的eth0的IP地址為1.1.1.254/24,其上開啟tcp的88端口,和本機(jī)直連的一臺主機(jī)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上執(zhí)行
route add -host 2.2.2.2 gw 1.1.1.254 telnet 2.2.2.2 1234 結(jié)果呢?不通!連syn-ack都沒有收到,然而在S上刪除REDIRECT規(guī)則而執(zhí)行以下規(guī)則則是可以的:
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有什么區(qū)別嗎?如果你不明白這兩者有什么區(qū)別,那么如果你知道SNAT和MASQUERADE的區(qū)別也不錯,起碼能幫助你理解。DNAT和SNAT能指定任
意的源地址一樣,可以指定任意的目的地址,那么REDIRECT則和MASQUERADE也類似,它只是內(nèi)核根據(jù)自己的策略而選擇出的一個目的地址,正如MASQUERADE也是內(nèi)
核根據(jù)RFC的建議以及自己的策略選擇出的一個源地址一樣。那么如何來選擇REDIRECT的目的地址呢?看一下iptables的man手冊就知道了:
REDIRECT

This 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”這一句。內(nèi)核中的REDIRECT規(guī)則是如何做到這點的呢?這還要看一下代碼才知道:
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); //取出接收設(shè)備的IP地址 if (indev && (ifa = indev->ifa_list)) newdst = ifa->ifa_local; rcu_read_unlock(); //如果接收設(shè)備沒有IP地址,則丟棄數(shù)據(jù)包 if (!newdst) return NF_DROP; } ... return nf_nat_setup_info(ct, &newrange, IP_NAT_MANIP_DST); } 這下我們就一切都明白了,既然broute表的redirect將接收設(shè)備設(shè)置為實際的物理網(wǎng)卡,而此網(wǎng)卡的IP地址已經(jīng)被刪除,那么上述函數(shù)的newdst當(dāng)然不存在了,因此數(shù)據(jù)包就被DROP掉了,到此為止,問題就很清晰了。可見ebtables的redirect方式直接影響到了iptables的redirect,為了讓iptables的redirect在使用bridge時仍然隨時可行,則必須為使能broute redirect的網(wǎng)卡上設(shè)置IP地址,為了不使路由沖突,考慮127.0.0.2...
注:broute表的意義

為何會有這樣的問題?broute是原因。所謂的broute則是bridge or router,類似早先安裝寬帶時運營商送的那種貓,能作為橋設(shè)備也能作為路由器。如果作為路由器,根本不存在橋設(shè)備這一說,因此將接收設(shè)備設(shè)置為實際的物理網(wǎng)卡也是理所當(dāng)然的啦。



?本文轉(zhuǎn)自 dog250 51CTO博客,原文鏈接:http://blog.51cto.com/dog250/1269005

總結(jié)

以上是生活随笔為你收集整理的ebtables之BROUTING和PREROUTING的redirect的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。