天天看點

Cisco與Linux的NAT

Linux一直以來都使用基于連接配接跟蹤的有狀态NAT,雖然xtables-addons裡面實作了無狀态的靜态NAT,即RAWNAT,和Cisco的NAT實作相比還是不夠靈活,本文給出一個全局意義的解釋,雖然這種解釋對于實際的配置沒有什麼幫助,但是可以幫助你更好地了解Linux和Cisco的系統建構。

Cisco路由器顯式的将inside和outside的概念邦定于實體接口,然後根據資料流的方向來定義NAT規則。使能NAT以後,系統中就會存在一張兩個方向的NAT映射表,該表的表項如何填充取決于NAT是靜态的還是動态的,如果是靜态的,那麼兩個映射表在配置完成後填充,如果是動态的,那麼表項在資料包第一次比對到access-list的時候填充。Cisco的NAT配置如下:

内網出去時的源位址轉換:

ip nat inside source(dynamic,static)/ip nat inside destination(static)

内網出去時的目标位址轉換:

ip nat inside destination(dynamic,static)/ip nat outside source(static)

外網進内網的目标位址轉換:

ip nat outside destination

Linux從内部規定了資料包必須經過的5個HOOK點,在這些HOOK上執行,Linux的接口僅僅是一個match,NAT完全根據邏輯意義的字段進行配置,和實體接口沒有任何關系。Linux的系統中沒有類似Cisco的全局的NAT雙向映射表,Linux的NAT表僅僅是一個target,針對所有match都比對的資料包起作用,協定棧不會針對每一個資料包來查詢NAT表以獲得是否需要NAT的資訊。Linux的NAT配置如下:

内網出去的目标位址轉換:

iptables -t nat -A POSTROUTING $MATCHES -o $outside  -j SNAT --to-source

iptables -t nat -A PREROUTING $MATCHES -i $inside  -j DNAT --to-destination

iptables -t nat -A PREROUTING $MATCHES -i $outside  -j DNAT --to-destination

上述分析可見,Linux的NAT是針對matches在資料包的核心路徑特定方向上做的一個動作,matches是必須的(即使它是空),而Cisco的NAT則是針對不同進出網絡的方向的資料所做的動作,matches被獨立抽出來作為一個access-list隻針對動态NAT有效。

        對于Linux的實作而言,由于IP本身就是一個match,是以沒有辦法直接使用一條iptables規則實作類似Cisco的static nat,iptables的nat的match和target都涉及到了位址本身,也就是說強制執行下面的邏輯:隻要滿足某些情況,就執行某個動作!對于nat而言,執行的動作隻有轉換到轉換後的位址,此時必須需要一個明确的match,否則将針對所有的過路包進行相同的轉換,目前的iptables無法支援變量,也不支援“與”和“或”,是以遠沒有Cisco的nat靈活。

        對于Cisco的實作而言,動态nat和Linux的iptables實作類似,隻是把match剝離出來了,此處的match就是access-list,其動作就是一個pool,這個和iptables的target是一緻的,至于inside和outside,隻是Cisco為接口定義的角色,不是核心。Cisco的static nat可以了解為下面的邏輯:請将源位址A轉換為源位址B,同時反向将目标位址從B轉換為A!這是一個祈使句,而不是Linux iptables的條件句,是以Cisco的static nat是在兩個方向有效的,如果是inside的source nat,由于映射是立即生效的,是以相當于outside的destination nat也添加了,而對于Cisco的動态nat,則必須限定資料的發起方向了。

        最後我們來看一下Cisco和Linux的NAT圖示:

a.Cisco NAT:

Cisco與Linux的NAT

b.Linux NAT:

Cisco與Linux的NAT

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

繼續閱讀