一個關於Linux Bridge配置的吐嘈

來源:互聯網
上載者:User

話說有些事情十分適合在放假前的一天折騰一天,但絕對不適合在你準備去吃飯前多看一眼...我上周就碰到了這麼一件揪心的事,最終以低血糖收場,十分狼狽地四處覓食,卻覓到了一包超級辣的雞爪,吃完後感覺癥狀加重了,於是向鄰座的同事乞討了巧克力糖,唉...這一切起源於我在準備吃午飯前一頭紮進了一個技術問題,本以為能靠配置搞定,最終卻還是不得不以修改The Fxxxing code告終!事情起源於公司的一個禁令:禁止上外網!
       禁止工作時間上外網,碰到問題就只能拖著,多麼奇葩的行政管理原則。事實上,想在工作期間上外網一般有三個辦法:
1.如果看直播之類的,可以躲在廁所裡蹲著看,沒人知道你在看什麼,代價就是3G流量和麻醉狀態的腿和腳;
2.填一張簽報單,說明自己上網的理由,比如查資料之類很籠統但卻沒有漏洞的理由,然後找領導簽字,一般都會獲批准的,然後你就可以在查資料之餘順便看看新聞,天氣預報之類的;
3.原自公司網路管理的漏洞,僅僅封掉了熟知連接埠,有些連接埠卻開著,如果你在家裡開一台Linux機器,那麼就可以通過家裡的機器上網了。
以上3點中,第1點基本不可能了,因為自公司搬家以後,廁所就一點訊號都沒有了,別說上網,萬一沒帶紙都是很麻煩的事,第二點大家都會做,也確實這麼做了,結果公司禁令的最大效果就是各種列印,各種簽字,各種跑,但是技術人員不滿足於這種非技術的解決方式,於是一定要嘗試一下第3種方式。
       一般而言,家用網路的拓撲都是在最外面有一個無線路由器,然后里面幾個裝置,PC,各種PAD,手機之類的,PC逐漸不再流行了,是守舊的思想在促使很多人一定要買或者組裝高大上的PC,就像10年前很多人鐘情於目前幾乎已經絕跡的大型主機一樣。在這個後終端時代,買一塊可以載有Linux的小板子也許是個不錯的主意,它耗電少,無噪音,小型,隨便塞在哪裡都可以,長期開機也無所謂,它是做家庭上網代理的最好選擇了。同事買了一塊這樣的小板子,據說很不錯。現在想在公司的時候也能通過家裡的那個小裝置上網,需要做些什麼呢?很顯然,造一個IPIP或者GRE隧道是不錯的選擇,可是如果想加密的話,就必然要用某種VPN技術,那麼首選的是OpenVPN,因為相比IPSec而言,我們有現成的配置。然而OpenVPN參數太多,也麻煩,於是想到了用simpletun,一個幾乎僅僅是用來學習的,超級小的,根本稱不上項目的小東西,雖然它沒有加密功能,但是為它加入一個base64編碼支援還是容易的...於是就選擇用simpletun建立隧道。
       simpletun本身一點問題都沒有,很簡單就把隧道建立了,家裡的作為服務端,公司的作為用戶端,因為公司防火牆只讓主動出不讓主動進。那麼還有什麼問題嗎?問題來了。用tun模式還是tap模式呢?我比較傾向於tap模式,因為這樣就可以把家裡的區域網路bridge到公司了,公司的機器和家裡的小裝置以及家裡的路由器在一個網段,多好!但是這需要做兩個額外的工作:
1.把家裡小裝置的物理網卡eth0和simpletun啟動的虛擬網卡tap0用brctl命令做成一個橋接器,然後讓這個橋接器接管原來eth0上的IP地址,
2.如果公司的機器串連家裡的小裝置成功,那麼其simpletun的虛擬網卡地址也要配置成和家裡區域網路同一個網段的。
以上第2個問題很好解決,難的是第1個。要知道,對家裡小裝置的操作是遠程SSH上去的,資料包通過家裡路由器的公網IP串連,之後被路由器DNAT到小裝置的eth0的IP地址,這就意味著在橋接器設定期間,必須保證這個IP地址的連通性,但是目前的Linux Bridge機制是不能支援的。
       通觀上述過程,其實和虛擬網卡沒有關係,於是可以把整個問題轉化為:設eth0上有一個IP,為ip,如何找一個辦法,使這個ip在下列過程中始終保持連通性,該過程為,將eth0加入一個新建立的橋接器。整個問題中,關鍵的操作有兩點,如下所示:
1.橋接器起來的那一刻;
2.把eth0加入到橋接器的那一刻;
有一點是毋庸置疑的,那就是只要你把eth0加入到橋接器,如果eth0收到資料包,核心會認為該資料包是橋接器接收的而不再是eth0接收的,包括ARP Reply在內,於是系統的arp表中本來擁有的路由器的arp項:
192.168.1.1 00:11:22:33:44:55 eth0
就會變成:
192.168.1.1 00:11:22:33:44:55 br0 或者 192.168.1.1 (incomplete)  br0(如果br0還沒有up的情況下)
要想資料通訊能完成,路由結果項的鄰居dev欄位必須和arp表項的鄰居dev欄位一致,這也是二層,三層之間的一個一致性渠道。換句話說,要想保持IP的連通性,必須要在將eth0加入橋接器的那一刻同時改變路由,而這是不可能的,因為brctl addif操作只完成一件事,即將eth0加入br0!
       如果換一個思路,即先將路由生效,然後再加eth0到br0呢?同樣的問題,路由項的dev改變為br0了,然而此時arp項的dev還是eth0!總之就是路由項的dev和arp項的dev在橋接器的操作序列中總是會有一個操作導致其不一致,而這一刻的不一致將導致斷網,後續的操作將無法完成,就算是一旦不一致了,只能靠另一個配置使其一致,它自己並不會收斂成一致狀態。
       其本質原因有兩點:1.brctl以及route操作都是原子的,二者互不牽連;2.橋接器沒有一個中間過渡狀態。解決這個問題就是要麼將brctl和route關聯起來,要麼引入一個中間狀態。想想就知道,關聯brctl和route肯定是不好的,畢竟我們這個需求不是一個普遍的需求,也有很多辦法可以解決它,比如設定一個開機if-up指令碼,或者寫一個批處理後台執行。之所以這麼較真兒非要來個online作業是因為我一直都以為自己能解決所有的網路問題...於是就決定用第二種方式,引入一個中間狀態,將多個互不相關的觸發機制合并為單一的觸發,比如雖然調用了addif將eth0加入了br0,調用ifconfig為br0設定了IP地址,但是在那個單一的觸發動作沒有執行前,一切都不生效。顯而易見的做法是,如果br0沒有up,則即使eth0加入了br0還依然使用eth0進行資料通訊。找到要修改的代碼很容易,因為Linux橋接器的代碼本身就很容易,修改net/bridge/br_input.c的br_handle_frame函數:

struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb){        const unsigned char *dest = eth_hdr(skb)->h_dest;        int (*rhook)(struct sk_buff *skb);////////加入以下代碼    int flags = p->br->dev->flags;        if (!(flags & IFF_UP)) {                return skb;        }////////.....}
然後載入修改後的模組後執行以下序列:
1.新增橋接器
brctl addbr br0
2.關閉STP(可選)
brctl stp br0 off
3.設定一個掩碼稍長的IP,暫時設定為down狀態
ifconfig br0 192.168.1.100/25 down
4.加入eth0到br0
brctl addif br0 eth0
5.開啟br0
ifconfig br0 up
6.清除eth0的IP
ifconfig eth0 0.0.0.0
值得一提的是上面第3個步驟,Linux中如果不同語義的相同路由是添加到一個list的尾部的,因此如果兩塊網卡配置相同的IP地址,則誰先up誰的鏈路路由在前面優先被匹配,設定掩碼稍長的IP地址是為了讓br0的網段比eth0的網段更加精確,但要注意,預設閘道一定不能被25位元遮罩和br0的IP劈開到不同的網段,比如預設閘道是192.168.1.128後面的地址就不能,因為它已經和192.168.1.100不在一個網段了,如果實在想使用稍長掩碼的IP地址,你就要增加一個force onlink的路由。其實可以用metric來做到上面的說的而不用稍長掩碼的IP地址,也可以修改Linux核心的路由部分,將fn_hash_insert中的某處list_add_tail改為list_add_head(此處不說了,感興趣的自行修改)...
       事情就這樣解決了,但是卻無法落實!什麼叫落實呢?就是說形成一個通用的方案,我想如果我把修改後的bridge機制提交給kernel maillist,肯定會有很多人罵的,更有可能的是根本沒人搭理我...從代碼風格上,這種寫入程式碼方式不可取,從實際效果來看,你不能保證使用bridge的人一定就同意你的邏輯,因此做成可選的選項就比較好,怎麼個可選法呢?模組參數當然是其一,但是還有更好的方法。
       行文至此,有一個疑問,為何不用ebtables的broute表呢?比如你設定一條:
ebtables -t broute -A BROUTING -j DROP
這條命令的效果和上面修改代碼的效果一樣,可是問題又來了,當你執行brctl addif br0 eth0的時候,就會斷網,因為此時你需要刪掉那個規則,然而已經沒有機會刪除了,因為你再也連不上去了。實際上,這也是單一觸發的問題,每次操作僅僅觸發一個動作,和上面討論的問題實質是一樣的。之所以在本文快要結束的時候引入一個新的問題,是為了展示一個更好的方案。我們來看看上面的ebtable命令缺了什麼,缺乏的正是一個match,即對br0狀態的判斷,它才會一股腦地將全部的資料都DROP到上層,如果它成為以下這樣子的話:
ebtables -t broute -A BROUTING -i br0 -state --dev-state up -j DROP
那豈不就完美了,絲毫不用改現有的Linux Bridge邏輯,需要做的僅僅是增加一個ebtables的match模組,這種模組化的東西本來就是讓擴充的,至於怎麼擴充,就看ebtables有沒有iptables靈活了,好像是沒有,因此我也就在此作罷了。
       這明顯不是什麼吐嘈,純粹是自己比較無聊而寫的一篇技術指南。隨便吧!讓人吐嘈的不是這篇文章所表達的內容,而是我對資訊記錄的極大不滿,因此,真正的吐嘈這才真正開始。
       我越發覺得使用智能手機是多麼危險的一件事,昨晚被老婆查手機,查完後怒了,不是針對老婆,而是針對沒天理的APP,我曾經去過哪裡,在那個地方待了多長時間,通過坑爹的iPhone隱私都可以查到,通過另一個APP,就可以查到曾經所有的通話記錄,簡訊,都上過哪些網站,而最令人氣憤的是,你刪除的東西可能不是真的被刪除,依然留在機器的某個角落,比如/var/cache/...我說一個具體的困境吧,如果你用iPhone下載了新浪微博,用一個帳號登入了,然後退出,這個帳號就永遠存在於你的手機了,下次,你只要輸入帳號的第一位,就會自動補全,好吧,你找不到任何地方可以刪除這個登入資訊,那麼怎麼辦?直接將程式刪除,然後重新下載,這下清靜了,不能自動補全了,看似清除了登入資訊,好吧,是的,真的清除了,這個時候不要登入,等待,等待,然後突然收到一條那個登入過帳號的特別關注好友的一條新微博,天啊,我還沒登入呐,怎麼就知道那條微博要推給我啊...以上是一個真實的事實,我故意這麼測試過。
       也有問題,我把一個不宜公開的基友拉到了朋友圈黑名單,然後再把他刪除,可是他的更新我還是可以看到。諸如此類的還有很多,感興趣的自己去玩吧。別跟我說技術不成熟導致的問題,在我看來技術永遠都不可能成熟!技術至上的觀點多麼天真,對於只懂技術或者對生活中的其它事情不關心不理解的人,一不小心就被他人引入一個萬劫不複的深淵,深不知深究此事是多麼的無聊,其實很簡單,你自己做一個壞東西讓別人折騰去唄,都別人玩兒又不犯法。你要知道,所有的好點子都不是技術人員搞出來的,都TMD是小丑引申的。留聲機剛發明的初衷並不是記錄音樂,甚至覺得記錄音樂是褻瀆了這個該死卻又偉大的發明,可是事實呢?
       當你走在街上,大量的網路攝影機指著你,就像有狙擊手在暗處瞄準你卻不開槍給你帶來的感覺一樣,因為一旦他開槍,一瞬間你就不會有任何感覺了。在貨梯旁邊的樓道吸煙的時候,可能保安正盯著你看你在通過手機看什麼內容,如果你看的是禁網,他們也會受惠。銀行的流水帳單會告訴別人你在什麼時間什麼地點在哪家店消費了多少錢,如果你狡辯說你在穆斯林商場的經緯度地點買了一斤豬肉,那你肯定在說謊,因為你根本不知道註冊的資訊有哪些;門戶網站,iPhone,公司的NAS,它們都會記錄你的資訊,你也不知道這些資訊最終會被如何處理,最簡單的辦法就是TMD少進行資訊交流,雖然我不會上公司不讓上的網站,但我也同時拒絕了使用google查閱正規的技術內容,我拒絕使用互連網,僅此而已,雖然我不會去東莞,也不會跟陌生女人通話,但我還是刪除了所有的通訊錄和APP,我拒絕使用智能手機,僅此而已。
       閉上眼睛,在廁所撒尿和在人民廣場馬路中心撒尿,對於沒有心智的人而言是一樣,可是處在時刻被監控狀態的網民,實質上和閉上眼睛在廣場中心撒尿沒有什麼兩樣。對於少數技術人員而言,總是可以在撒尿的時候罩上一塊簡單的屏障,甚至直接睜著眼撒尿即可,同時還向四周豎起了中指,但對於大多數技術人員而言,為了撒尿,卻只知道自己憋著尿蓋一座廁所,如果你想如廁,旁邊商場裡就有啊。無知導致滯後...

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.