歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 又一個Linux的雙向stateless NAT

又一個Linux的雙向stateless NAT

日期:2017/2/28 14:47:51   编辑:Linux教程

如果看一下iproute2的help,就會發現在route section中有一個nat action,其中via的參數給出了轉換的地址。具體的配置就不說了,只提出兩點,第一,iproute2的stateless nat需要policy routing的參與,第二,它在2.6內核中被去除了;具體信息可以參見文檔。在2.6內核中,內核協議棧將一切的擴展都留給了Netfilter來實現,自己只實現標准的最小集。

為什麼要提到2.4內核的nat route呢?既然已經被掃除了,既然在Netfilter中實現NAT具有哲學意義,既然我自己也基於Netfilter實現了一個雙向的stateless nat(見 http://www.linuxidc.com/Linux/2013-05/84402.htm ),那舊事重提又有什麼意義呢?我對老婆說,我說出的任何話,做出的任何事,背後都有一套可以自圓其說的理論,不管它多麼荒謬,但是可以自圓!因此我現在又想實現一個stateless nat時,也需要一個理論支撐,就是:將NAT塞入路由表中是合理的,因為NAT受影響的就是路由(不管是本地路由還是遠程的路由),直接在路由中做掉會更好。由於PRE/POST-ROUTING的中間點就是路由,何不把NAT統一合並在路由中來呢?雖然這不太符合Netfilter的哲學,然而對於實用主義來說,這太好不過了!2.4內核實現的nat route之所以不好,除了哲學原因之外還有代碼的原因,那段實現代碼太亂了!

如果按照上述的思路來實現nat route,根本不用policy routing,不需要配置ip rule,不需要配置兩條規則,它的流程圖如下,代碼也比較好修改:

可以看出,這個實現使用了遞歸路由查詢這個Linux根本就沒有實現的東西。因此需要修改路由插入的部分代碼,而我使用了幾個flag來識別該條路由是做NAT用的,由於是stateless的雙向NAT,因此當你插入一條NAT路由的時候,另外一個方向的就必須自動生成,比如你插入了一條以下的路由:

ip route add dnat x via y

指示所有的目標是x的都要轉換成y,那麼以下的路由必須自動生成:

ip route add snat y via x

指示所有源地址為y的都要轉換為x。當然以下的這一條不應該手工配置,應該用auto標號指名它是自動生成的。

以上的需要說明是snat,原則上snat是在路由之後進行的,否則可能會做無用功,那流程圖為何在路由前snat呢?這是為了最小化查詢,否則也會做很多無用的查詢,將要對所有的數據包都進行是否需要snat的查詢,這裡用到的一個技巧就是路由查詢是基於最長前綴匹配的,如果有需要snat的,那麼肯定會有一條明細的32位前綴的snat路由,如果沒有,那就說明沒有需要snat的。當然上面的流程圖還可以優化,因為我們認識到,由於是雙向的nat,那麼只要有一個dnat,就會有一個snat,反過來也一樣,都是成對出現的,基於這點是否能做點優化呢?

Copyright © Linux教程網 All Rights Reserved