Linux Stateless無狀態NAT-使用TC來配置

來源:互聯網
上載者:User
如果想在Linux上配置NAT,那麼大家眾所一言的就是使用iptables的NAT表來配置,iptables提供了靈活豐富的配置來配置SNAT和DNAT,然而我們知道iptables的NAT依賴了ip_conntrack,也就是說,凡是一個命中了NAT表規則的流就會有一條串連追蹤產生,由於ip_conntrack追蹤了所有的資料包,因此當有大量串連經過了本地裝置時,ip_conntrack空間將被撐滿,這個在接入區特別容易重現,在骨幹網反而不容易重現,然而骨幹網卻又幾乎不可能使用Linux。
        如果Linux支援無狀態的NAT就好了,這樣就不怕conntrack爆滿了,也不會因為conntrack尋找而深深影響效率。然而如此的無狀態NAT也有自己的缺點,那就是你必須為返迴流量顯式配置NAT規則,這樣配置規則就整整增加了一倍,畢竟是無狀態的嘛,NAT工作在無狀態的IP層,而IP層是單向的。iptables正是依賴了ip_conntrack才能自動的轉換返回包的地址資訊的,因為ip_conntrack根據五元素追蹤了每一個IP流。
        幸運的是,Linux一直都實現了無狀態的NAT,只是其很少被人瞭解罷了。在Linux 2.4核心上,使用iproute2可以實現無狀態NAT,只是在2.6核心上其實現被取消了,這是因為Linux的路由模組是基於目的地址hash或者trie tree的,然而對於同一目的地址而言,其作為負載平衡或者其它目的的多個表項卻是線性尋找的,NAT的實現就是採用多個這樣的表項來完成的,這樣在大量NAT規則存在的情況下,就會增加尋找時間而影響效率,因此自2.6.24開始,Linux使用TC來實現無狀態的NAT,雖然這樣的實現有點變態,然而卻很好的藉助了TC固有的高效的查詢匹配方式。
        本文不準備詳述Linux的TC機制,僅僅解析其配置NAT的方法。具體來講,NAT分為SNAT和DNAT,如果應用在網路介面即網卡上而不是應用在協議棧的Netfilter鏈上的話,SNAT將綁定在egress方向,而DNAT將綁定在ingress方向。需要注意的是,由於基於TC的NAT是無狀態的,因此當你配置了ingress的DNAT之後,必須在相反的egress方向顯式配置SNAT,你的配置量因此將增加一倍。以下我們先來配置ingress上的DNAT規則,效果是將訪問原生一個網卡上的一個IP裝換為該網卡上的另一個IP地址。
        IP地址規劃:eth2上的兩個IP:192.168.40.249/24  12.12.12.5/24
        和往常一樣,首先建立一個規則隊列,也就是qdisc:
tc qdisc add dev eth2 ingress handle ffff

然後建立一個filter:

tc filter add dev eth2 parent ffff: protocol ip prio 10 u32 match ip dst 192.168.40.249/32 action nat ingress 192.168.40.249/32 12.12.12.5

這兒不得不說一下這個filter,首先filter並不是對每一種qdisc都管用的,它只對特定的隊列管用,比如HTB隊列,而對某一些隊列則沒有作用,這個可以從man tc文檔中得到具體詳情。另外,我們這裡僅僅基於IP地址進行了過濾,如果要涉及到協議以及其源或者目的連接埠進行過濾,那麼請使用fmark,這個可以使用iptables的mangle表來完成,而該表是不依賴ip_conntrack的。最後,針對這個filter,唯一的解釋那就是其action子語句,該子語句說的是在ingress方向上將匹配結果的目的地址從192.168.40.249修改為12.12.12.5。
        接下來我們來配置反方向的egress規則:首先建立一個qdisc:

tc qdisc add dev eth2 root handle 10: htb

然而配置一個和上面類似的filter:

tc filter add dev eth2 parent 10: protocol ip prio 10 u32 match ip src 12.12.12.5/32 action nat egress 12.12.12.5/32 192.168.40.249

該語句說的是,在egress方向上,將源地址從12.12.12.5裝換為192.168.40.249這個地址。可以看出,該egress規則和上述的ingress規則是相反的。
        需要指出的是,使用TC配置的無狀態NAT,它和iptables是完全不同的理念,它基於網卡介面以及其方向,而不是基於協議棧實現的N個HOOK點,因此使用TC配置的無狀態NAT並沒有本機發出包和Forward包之間的區別,一切都需要你自己在介面上顯式的進行配置才可以。比如雖然在ingress上將目的地址配置成了12.12.12.5,TC並看不到這個地址到底是誰的,是原生?還是其它網路的?TC並不知道,一切都由最終的路由來決定。反過來在配置egress的返回規則時,為何要在eth2這個裝置上進行配置,這完全取決於你的路由,這是和iptables一致的,也就是說,SNAT必須在路由後完成,而DNAT則必須在路有前來完成。和iptables不同的是,TC配置的無狀態NAT並沒有區分OUTPUT和PREROUTING(這並不是一種模式,而是Linux協議棧的實現理念-一切都由callback來決定來決定的),而是統一於ingress和egress,這對於習慣於Cisco IOS或者VRP平台的傢伙來講,無疑更加習慣一些。
        測試一下上述配置的正確性十分簡單,但是千萬別用tcpdump來抓包確認,因為tcpdump基於pcap,而它只是抓取混雜模式下的“未DNAT轉換前的目的IP地址以及已經SNAT之後的源IP地址”,想瞭解這一點,那就看看Linux的PACKET_ALL的實現,它在資料從網卡讀出還未做任何處理則進入了pcap,而對於外發包則是在資料馬上就進入網卡的時候才進入pcap。
        本文主要介紹了使用TC配置NAT的一般原理和步驟,如果習慣了這個配置,你可以就會拋棄一些被你抱怨已久的iptables nat方案了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.