ebtables之BROUTING和PREROUTING的redirect的區別

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_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 */ }
它進入了我們都熟悉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手冊就知道了:
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”這一句。內核中的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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/393111.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/393111.shtml
英文地址,請注明出處:http://en.pswp.cn/news/393111.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LVS的四種模式的實現

LVS 是四層負載均衡,也就是說建立在 OSI 模型的第四層——傳輸層之上,傳輸層上有我們熟悉的 TCP/UDP,LVS 支持 TCP/UDP 的負載均衡。LVS 的轉發主要通過修改 IP 地址(NAT 模式,分為源地址修改 SNAT 和目標地址修改 DNA…

MyISAM與InnoDB兩者之間區別與選擇,詳細總結,性能對比

1、MyISAM:默認表類型,它是基于傳統的ISAM類型,ISAM是Indexed Sequential Access Method (有索引的順序訪問方法) 的縮寫,它是存儲記錄和文件的標準方法。不是事務安全的,而且不支持外鍵,如果執行大量的sel…

leetcode557. 反轉字符串中的單詞 III

給定一個字符串,你需要反轉字符串中每個單詞的字符順序,同時仍保留空格和單詞的初始順序。 示例: 輸入:“Let’s take LeetCode contest” 輸出:“s’teL ekat edoCteeL tsetnoc” 代碼 class Solution {public St…

linux命令數據盤分多個區,pvmove命令 – 移動物理盤區

pvmove命令的作用是可以將源物理卷上的物理盤區移動到一個或多個其他的目標物理卷。使用pvmove命令時可以指定一個源日志或卷。在這種情況下,只有邏輯卷使用的區才會被移動到目標物理卷上的空閑或指定的區。如果沒有指定的物理卷,則使用卷組的默認規則分…

spanning-tree extend system-id

spanning-tree extend system-id 在交換機上啟用extended-system ID 特征使其支持 1024 MAC 地址, 在全局模式下使用 spanning-tree extend system-id命令.禁用時前面加 no。 spanning-tree extend system-id no spanning-tree extend system-id 命令用法 在不提供 1024 MAC 地…

leetcode841. 鑰匙和房間(bfs)

有 N 個房間,開始時你位于 0 號房間。每個房間有不同的號碼:0,1,2,…,N-1,并且房間里可能有一些鑰匙能使你進入下一個房間。 在形式上,對于每個房間 i 都有一個鑰匙列表 rooms[i]&a…

Codeforces 235C Cyclical Quest (后綴自動機)

題目鏈接: https://codeforces.com/contest/235/problem/C 題解: 對大串建后綴自動機 對詢問串復制拆環。這里一定要注意是復制一個循環節不是復制整個串!循環節是要整除的那種 然后要做的實際上是在大串上跑,每經過一個點求出當前的最長公共子串&#x…

泛型型協變逆變_Java泛型類型簡介:協變和逆變

泛型型協變逆變by Fabian Terh由Fabian Terh Java泛型類型簡介:協變和逆變 (An introduction to generic types in Java: covariance and contravariance) 種類 (Types) Java is a statically typed language, which means you must first declare a variable and …

安卓系統換成linux系統軟件,將舊安卓手機打造成“簡易linux”機器,并部署AdGuardHome...

從原教程的安裝Linux Deploy 完成后,在配置 Linux下載鏡像的一些東西時有些許出入。首先,我是用的下載源地址是 http://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports 清華的源挺好用的。 其他有出入的配置如圖(記得把源地址改清華的,華中科大…

let與expr命令的用法與實戰案例

let命令的用法 格式: let 賦值表達式 【注】let賦值表達式功能等同于:(賦值表達式) 例子:給自變量i加8 12345678[rootXCN ~]# i2 [rootXCN ~]# let ii8 [rootXCN ~]# echo $i 10[rootXCN ~]# ii8 #去掉let定義 [root…

在使用ToolBar + AppBarLayout,實現上劃隱藏Toolbar功能,遇到了一個坑。

問題:Android5.0以下版本Toolbar不顯示沉浸式狀態欄,沒有這個問題,但是5.0以上版本,就出現了莫名其妙的陰影問題,很是頭疼。 分享一下我的解決方案: 在AppBarLayout中加一個屬性: app:elevation…

leetcode1476. 子矩形查詢

請你實現一個類 SubrectangleQueries ,它的構造函數的參數是一個 rows x cols 的矩形(這里用整數矩陣表示),并支持以下兩種操作: updateSubrectangle(int row1, int col1, int row2, int col2, int newValue) 用 new…

msbuild構建步驟_如何按照以下步驟構建最終的AI聊天機器人

msbuild構建步驟by Paul Pinard保羅皮納德(Paul Pinard) 如何按照以下步驟構建最終的AI聊天機器人 (How to build the ultimate AI chatbot by following these steps) 快速指南,可幫助您避免常見的陷阱 (A quick guide that helps you avoid common pitfalls) Bui…

第一章:最小可行區塊鏈

概覽區塊數據結構區塊哈希創世塊創建區塊保存區塊鏈驗證區塊完整性選擇最長鏈節點間通信操作節點架構運行測試小結概覽 區塊鏈的基礎概念非常簡單, 說白了就是一個維護著一個持續增長的有序數據記錄列表的這么一個分布式數據庫。在此章節中我們將實現一個簡單的玩具版的區塊鏈。…

Oracle Controlfile控制文件中記錄的信息片段sections

初學Oracle的朋友肯定對Controlfile控制文件中到底記錄了何種的信息記錄而感到好奇,實際上我們可以通過一個視圖v$controlfile_record_section來了解控制文件的信息片段: SQL> select type, record_size, records_total from v$controlfile_record_s…

linux 怎么禁止遍歷目錄,linux下遍歷目錄功能實現

/*編譯:dir:dir.cgcc -o $ $<*/#include #include #include #include #include int do_search_dir(char *path);int do_check_dir(char *fullpath, char* truefullpath);void usage(char *apps);int count 0;intmain(int argc,char **argv){char fullpath[…

leetcode面試題 16.26. 計算器(棧)

給定一個包含正整數、加()、減(-)、乘(*)、除(/)的算數表達式(括號除外)&#xff0c;計算其結果。 表達式僅包含非負整數&#xff0c;&#xff0c; - &#xff0c;*&#xff0c;/ 四種運算符和空格 。 整數除法僅保留整數部分。 示例 1: 輸入: “32*2” 輸出: 7 代碼 clas…

團隊項目電梯會議視頻

http://v.youku.com/v_show/id_XMjcyMjI3Mjk2NA.html?spma2hzp.8244740.userfeed.5!2~5~5~5!3~5~A轉載于:https://www.cnblogs.com/jingxiaopu/p/6749776.html

arduino服務器_如何使用Arduino檢查Web服務器的響應狀態

arduino服務器by Harshita Arora通過Harshita Arora 如何使用Arduino檢查Web服務器的響應狀態 (How to use Arduino to check your web server’s response status) Last year, I created Crypto Price Tracker (an app which was acquired by Redwood City Ventures this yea…

leetcode486. 預測贏家(dp)

給定一個表示分數的非負整數數組。 玩家 1 從數組任意一端拿取一個分數&#xff0c;隨后玩家 2 繼續從剩余數組任意一端拿取分數&#xff0c;然后玩家 1 拿&#xff0c;…… 。每次一個玩家只能拿取一個分數&#xff0c;分數被拿取之后不再可取。直到沒有剩余分數可取時游戲結束…