天天看點

在Linux上實作一個可用的stateless雙向靜态NAT子產品

關于Linux上如何配置NAT的資料已經不少,可謂鋪天蓋地!本文與此無關。本文提供一種iptables之外的方式。

iptables? 不!why?因為iptables配置的NAT是stateful的,它的實作依賴一個叫做conntrack的子產品,什麼是 conntrack?Oh,NO!這可是我的專長,但我不想在本文中說它,認識我的人都知道,我扯這個話題我能扯上12個小時...都還扯不完。也許你不 知道什麼是stateful NAT,但是如果你是一個有心人,或者說是一個技術還算精湛的Linux網絡管理者或者愛好者,你肯定在配置NAT的時候遇到過這樣那樣的問題,比如“在 一個連接配接已經建立的時候再配置NAT為何不能及時生效”,“為什麼iptables配置NAT之後資料隻能從一個方向主動發往另一個方向”之類的。這就是 state在作怪,你知道的,IP是無state的,但是NAT加入了第四層的邏輯之後就有了state,這就是stateful NAT,也就是iptables -t nat ..配置出來的NAT固有的性質,你改變不了。起碼我在iptables最新的版本中看到的NAT還是stateful的。有的時候..    

       有的時候,你可能,你必須...

       你必須配置一種stateless的NAT,雙向的,靜态的。這個問題,唉..

       這個問題折騰了我半年,2013年的前9個月,一個讓我歡喜讓我憂的三個季度,我的精力幾乎全部撲在了一件事上,從寒冬到40+攝氏度的高溫,從早上6點 半出發去上班到半夜10點多還呆在機房...要不是大前天收拾書架時發現了一張當時還沒有報帳掉的120元的例行加班打車票,我本來不想寫這個子產品了。 120塊不算什麼,但借此機會回憶往事,順便補上殘缺的那一部分,算是給自己報帳了,而且價值遠大于120元。我得承認,那三個季度裡并不是 stateless NAT顯得最為重要,我之是以在一年後的今天把它拿出來,是因為其它的問題都被我當時就overcome了,不管花多久,曾經有過72小時驚魂解決 conntrack confirm問題,有過由于混亂急躁和陌生女人一起吃烤肉被老婆詐出真相...但是就這個stateless NAT始終沒有解決,沒有解決,這是why?

       我做的是一個産品而不是個人試驗,我所在的是一個公司的團隊而不是幹私活兒,所有使用的技術必須經過技術預研,確定可行性,更重要的是,要保證所有人處在 一樣的節奏,也許是并行,大的旋律卻始終是個一,這是在玩卡農啊。我不能加入一些個人色彩,比如個人的突發奇想(日後我坦白,這一點我做的不好!),如果 非要加入,那麼必須有下面這麼一個過程:

把上司,團隊所有人拉進來開會,教育訓練,確定任何研發人員和技術負責人都對使用的技術了如指掌不留死角。

但是哪有這個時間?!人性是脆弱的,不管人生多麼堅強。任何人都可能突然哪天挂了,由于不可抗原因去别的城市或者國家了,和根本不熟識的同僚由于接開水打了一架離職了...如果你做的東西也是以而離去了,對于一個公司而言,說明你根本沒來過。......有點扯遠了。

       是以,即便當時我已經可以實作stateless NAT(當時我采用了路由target的方式,也許我之前的blog有寫過),我也不能拿來用,我隻能找機會,找一個閑暇的午後,一個沒有緊急任務的下 午,讓所有與此相關的人都了解了這個技術,然後用與不用就是一個需求問題了,最好的辦法除了代碼還是代碼,對于程式員而言,說1G個字元都是瞎掰,沒有能 跑起來的代碼都是扯淡,就算代碼狠爛也無所謂,正因為如此現實主義的性格,我喜歡這個職業,不發狠話,不長篇闊論,不打架,不煽動,隻要代碼能跑起來,僅 此而已。

       對了,stateless NAT在Linux 2.4已經有好的實作了,就是使用tc/policy routing來完成,但是2.6核心下已經很難做到了。作者基于解耦合的考慮将這個子產品留給了真正想實作它的人,也許我算一個。我之是以做如此多别人看 來沒有意義的事,因為我想表達一個理念,那就是“開發運維”和“運維開發”的理念,這類人一定是将來最炙手可熱的人。當我面對無數次Cisco認證工程師 的責難後,我的第一個想法不是罵他們或打他們(沒人家詞彙豐富且[注意:此處不能用‘或’,要用‘且’]打不過人家就尴尬了,即便這些都不是問題,不還有 法律的嗎...),我的第一個想法就是,在Linux上能不能實作相同的功能,目的不是爆他們的菊花,而是讓他覺得我可以爆他。幸運的是,我都做到了,每 當此刻,我回到家裡都會寫幾個子產品然而測試,就像公司的技術預研一樣。然後就呈現給朋友們,有興趣的都可以去測試,這種事沒錢賺,也得不到肯定,沒用到 git,也不是神馬GPL開源,就是特殊的朋友圈分享,我十分讨厭分類,我十分喜歡随便。然後,然後,正如小小的話,我編碼,寫了一堆爛代碼,Linux 上基于Netfilter實作的一個雙向,靜态的,無狀态的NAT,代碼不複雜,隻有幾百行,但是....

        但是,問題有二:

1.這個子產品初級,但是可用,這是我自我肯定的一面;

2.這個子產品有大量可疑改進的空間,我自我否定。

代碼如下:

Makefile:

我不看好應用相關的私活兒并不代表我不喜歡,并不代表我不會。工作畢竟已經很累了,幹嘛還要繼續累啊。工作之餘,要搞點别的,别的是什麼呢?stateless NAT...這是很多人都不涉足的,我感歎,我悲哀,微斯人,吾誰與歸?

 本文轉自 dog250 51CTO部落格,原文連結:http://blog.51cto.com/dog250/1592083

繼續閱讀