Linux 2.4 nat how-to

來源:互聯網
上載者:User

Linux 2.4 NAT HOWTO 簡體中文版
Rusty Russell, mailing list netfilter@lists.samba.org
$Revision: 1.3 $ $Date: 2002/06/05 13:21:56 $
簡體中文:洋鬼鬼·NetSnake
感謝 網中人netmanforever@yahoo.com 提供的繁體參照
此文檔說明如何進行偽裝、透明代理、連接埠轉寄,和基於Linux 2.4核心其他類型的 網路位址轉譯(Network

Address Translations)。
1. 簡介
2. 官方網站及列表
2.1 什麼是NAT?
2.2 我為什麼需要NAT?
3. NAT的兩種類型
4. 從2.0和2.2核心的快速轉換
4.1 我只想偽裝!救命!
4.2 關於ipmasqadm
5. NAT可以控制什麼
5.1 用iptables做簡單的選擇
5.2 關於應當挑選哪些包來拆分(mangle)的要點
6. 說說如何拆分包吧
6.1 源地址NAT
6.1.1 偽裝
6.2 目的地址NAT
6.2.1 重新導向
6.3 深層次的映射
6.3.1 一個範圍內多地址的選擇
6.3.2 建立空的NAT映射
6.3.3 標準NAT行為
6.3.4 內部源連接埠映射
6.3.5 如果NAT失敗會怎樣?
6.3.6 多重新對應,重疊和衝突
6.3.7 修改本地產生的串連的目標地址
7. 特定的協議
8. 關於NAT的警告
9. 源地址NAT和選路
10. 同一網路內的目標地址NAT
11. 感謝
1. 簡介
歡迎,親愛的讀者。
你將要深入迷人的(有時是令人厭煩的)NAT世界:網路位址轉譯,這篇HOWTO可以成為你的Linux2.4核心及其以後

的準確指南。
在Linux2.4(核心版本),引入了一個叫“netfilter”的部分,專門用於拆分(mangling) (IP)包的。他上一

層提供NAT,是完全依靠以前的核心製作的。
(譯者註:mangle實在找不出什麼合適的翻譯,抱歉)
(C) 2000 Paul `Rusty' Russell. Licensed under the GNU GPL.

--------------------------------------------------------------------------------
 
2、 官方網站及列表位置
這裡有三個官方網站:
o Thanks to Filewatcher http://netfilter.filewatcher.org.
o Thanks to The Samba Team and SGI http://netfilter.samba.org.
o Thanks to Harald Welte http://netfilter.gnumonks.org.
你可以通過以下網站訪問全部相關網站。
http://www.netfilter.org and http://www.iptables.org
以下是netfilter官方郵件清單
http://www.netfilter.org/contact.html#list.

--------------------------------------------------------------------------------
 
2、1 什麼是網路位址轉譯(Network Address Translation)?
通常,,網路中的(IP)包從他們的源(地址)出發(比如你家的電腦),到他們的目的地(比如

www.gnumonks.org),會經過很多不同的串連(links):例如我所在澳大利亞就有19個。這些串連不會真去修改你

的包:他們只是照原樣傳出去。
(譯者註:這裡的links應當認為是所有網路節點,包括主機、路由器等。通常,路由器並不是原樣傳送包,它至少

會修改其中一點:TTL)
如果這些串連有一個做NAT,那麼它(們)就會修改通過它們的包的源或者目標(地址)。正如你猜象的那樣,這並

非系統設計成那樣的,而是NAT做了一些事情。通常進行NAT的串連(主機、伺服器、路由器)會記住它是如何拆分

包的,而當另一頭響應的包通過時,它會對響應的包做相反的拆分,所以世界仍在運轉。
(譯者註:這一段的mangle應該想象為修改更合適)

--------------------------------------------------------------------------------
 
2、2 我為什麼要NAT?
在完美的世界裡,你不需要。同時,主要的理由是:
用數據機串連Internet
在你撥接時,大部分ISP只會給你一個IP地址,你可以發送你想發送的任何源地址包,但是只有響應這個(ISP

給你的)地址的包才會返回。如果這種情況下你想有多台不同的機器上網(比如一個家用網路),你就需要NAT。 
這是現在NAT用得最多的功能,Linux世界的"masquerading"(偽裝)非常出名,我稱之為SNAT(SNAT即Source NAT

,源地址轉換),因為你改變了第一個包的源地址。
(譯者:關於IP資料報的第一個包等內容,請參見各TCP/IP書籍)
多(重)伺服器
有時你想改變進入網路中的包的目標地址(路由)。經常的,這是因為(就像上面的例子),你只有一個IP地址,

但是你希望大家可以通過到那個“真實”的IP地址進入內部。如果你重寫了進入包的目標地址,這樣就沒問題了。

這種NAT在以前的Linux版本中被稱為連接埠轉寄。
一個常見的變種是負載平衡,在一組機器上做映射。如果你要進行嚴格的比例限制, 可能需要參考Linux Virtual

Server。http://linuxvirtualserver.org
透明代理
有時你可能想要經過你的Linux的包被送往原生一個程式。這就需要用到透明代理了:代理是位於你的網路和外部

世界之間的一個程式,協助二者進行通訊。之所以稱為透明,是你的網路根本不知道他在和代理交談,當然直到代

理沒有正常工作。
Squid可以配置為幹這項工作,在以前Linux版本中它被稱作重新導向或者透明代理。

--------------------------------------------------------------------------------
 
3、 NAT的兩種類型
我把NAT分為兩種不同的類型:源NAT(SNAT)和目標NAT(DNAT)。(譯者註:以下不再翻譯SNAT和DNAT,直接用Source

NAT和Destination NAT)
Source NAT是指修改第一個包的源地址:也就是說,改變串連的來源地。Source NAT會在包送出之前的最後一刻做

好post-routing(動作),偽裝是SNAT的一種特殊形式。
Destination NAT 是指修改第一個包的目標地址:也就是說,改變串連的目的地。Destination NAT 總是在包進入

以後(馬上)進行before routing(動作)。連接埠轉寄、負載平衡和透明代理都屬於DNAT。

--------------------------------------------------------------------------------
 
4、 從2.0和2.2核心的快速轉換
如果你還在為從2.0(ipfwadm)到2.2(ipchains)的轉換手忙腳亂的話,很抱歉。不過這也算是個喜憂半參的訊息


首先,你可以輕鬆的使用ipchains和ipfwadm,就像從前一樣。不過你需要安裝最新發行的netfilter中的

“ipchains.o”或者“ipfwadm.o”核心模組。它們是互斥的(你會被警告),而且不能和任何其他netfilter模組

結合。
一旦這其中某個模組被載入,你可以像以前一樣使用ipchains和ipfwadm,不過仍有以下區別:
用ipchains -M -S,或者用ipfwadm -M -s設定偽裝逾時不再有效。因為逾時已經轉移到新的NAT構架中,所以這不

能做任何事。
在詳細的偽裝列表中,init_seq、delta和previous_delat欄位始終為零。
歸零和列表計數器的 -Z -L不再有效:計數器不能被歸零。
這類向後相容的部分可能和大部分串連都不能有效配合:不要在你的公司網關中使用
開發人員們還要注意:
無論是否使用偽裝,現在可以綁定61000 - 65095之間的連接埠。以前的偽裝代碼佔用了這部分連接埠,因此不能使用。
尚未成文的“getsockname”,透明代理程式可以用來發現那些已不再工作的串連的真實目的地址。
尚未成文的“bind-to-foreign-address”同樣還未啟用:這個用於完整透明代理的設想。

--------------------------------------------------------------------------------
 
4、1 我只想偽裝!救命!
這是絕大部分人想要的。如果你用PPP撥接來動態得到IP (如果你不知道,那應該就是的)你可能只想告訴你

的機器,所有來自內部網路的包,要看上去同PPP串連伺服器上的包一樣。
# 裝載NAT模組(這取代了其他的)
modprobe iptable_nat
# 在NAT表中(-t nat),路由後 POSTROUTING 加入一條規則(-A) 
# 所有由ppp0送出的包(-o ppp0) 會被偽裝( -j MASQUERADE)。
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# 開啟IP轉寄
echo 1 > /proc/sys/net/ipv4/ip_forward
注意這時你沒有做任何的包過濾:如果需要,參見 the Packet Filtering HOWTO。

--------------------------------------------------------------------------------
 
4、2 那麼ipmasqadm呢?
這個完全取決於使用者,所以我不擔心向後相容的問題。你可以簡單的使用“iptables -t nat”做連接埠轉寄。例如,

在Linux2.2你要做:
# 在2.2核心,把指向1.2.3.4 8080連接埠的TCP包轉到192.168.1.1的80連接埠
ipmasqadm portfw -a -P tcp -L 1.2.3.4 8080 -R 192.168.1.1 80
現在你可以這樣:
# 2.4核心,在NAT(-t nat)表中加入一條規則,在路由之前(-A PREROUTING)指向
 
# 1.2.3.4(-d 1.2.3.4)8080連接埠(--dport 8080)的TCP包(-p tcp)目標地址(-j DNAT)
# 被重新導向到 192.168.1.1的80連接埠(--to 192.168.1.1:80)。
iptables -A PREROUTING -t nat -p tcp -d 1.2.3.4 --dport 8080 -j DNAT --to 192.168.1.1:80

--------------------------------------------------------------------------------
 
5、NAT可以控制什麼
你需要建立NAT規則,以告訴核心哪些串連將被改變和如何改變。要做到這一點,我們要用到一個用處很多的

iptables工具,並告訴它用指定的“-t nat”選項修改NAT表。 
NAT規則表包含三個稱為“鏈”的列表:每個規則都按順序檢查包,直到有一個匹配。其中兩個被稱為PREROUTING(

用於Destination NAT,當包進入時檢查),POSTROUTING(用於Source NAT,包離開時檢查),第三個叫OUTPUT,

這裡可以忽略。
如果我有足夠的藝術天分的話,下面的見圖會準確的說明上述概念:
 
          _____                                     _____
            /     /                                   /     /
          PREROUTING -->[Routing ]----------------->POSTROUTING----->
            /D-NAT/     [Decision]                    /S-NAT/
                            |                            ^
                            |                            |
                            |                            |
                            |                            |
                            |                            |
                            |                            |
                            |                            |
                            --------> Local Process ------
 
上述每一點,當我們查看串連(中)的包時,如果是一個新的串連,我們查看 NAT表中相對應的鏈,看看需要做些

什麼。其結果就會作為對這個串連後面所有包 的反應。
(譯者註:此處的串連是指一個HTTP會話之類的串連,而非物理上的線路、節點)

--------------------------------------------------------------------------------
 
5、1 用iptables做簡單的選擇
下面列出了iptables的一些標準選項。所有雙橫杠(--)的選項都是可以縮寫的。只要iptables可以將它們與其他

選項區分開來就夠了。如果你的核心是以模組方式支援iptables的,你需要先用命令:insmod ip_tables來載入

ip_tables.o
這是最重要的選項表格選擇,“-t”。對所有NAT操作,你都需要使用'-t nat'以指定NAT表。其次重要的是'-A',

添加一個新的規則到鏈的末尾(例如'-A POSTROUTING'到POSTROUTING鏈),或者'-I'從最開始插入一個規則(例如

'-I PREROUTING')。
你可以指定你想要進行NAT的包的源(地址)('-s' 或者'--source')和目的(地址)('-d' 或 '--destination'

)。這兩個選項可以跟單個IP地址(例如192.168.1.1),一個名字(例如www.gnumonks.org),或者一個網路地址

(例如192.168.1.0/24或192.168.1.0/255.255.255.0[譯者:這二者是等價的,只是表示方法不同])。
你可以指定進入或送出的匹配介面。不過能否指定取決於你想要寫入規則的那個鏈:PREROUTING鏈你只能選擇進入

介面,POSTROUTING你只能選擇送出介面。如果用錯了,iptables會給出一個錯誤。

--------------------------------------------------------------------------------
 
5、2 關於應當挑選哪些包來拆分(mangle)的要點
我上面說了你可以指定源地址和目標地址。如果忽略源地址選項,那麼所有源地址都會被匹配,同樣,如果忽略目

標地址,所有目標地址都將被匹配。
你還可以標出一個指定的協議('-p'或'--protocol'),諸如TCP或者UDP;那麼只有這類協議的包會被匹配。這麼

做的主要原因是指定了協議,就可以增加額外的選項:指定'--source-port'源連接埠和'--destination-port'目的端

口選項(可縮寫為'-sport'和'-dport')。
這些選項讓你可以只匹配那些特定源連接埠及目標連接埠的包。這些對於重新導向Web請求(TCP 80或8080連接埠)而不影響

其他包非常有用。
這些選項必須跟在'-p'選項後面(這可能會對載入該協議的串連庫有一定影響)。你可以使用連接埠號碼,或者來

自/etc/serverices檔案的(連接埠)名。
所有這些你可以對一個包作出的不同選擇都詳細的列在那詳細得可怕的使用手冊中了(man iptables)。(譯者注

:參見iptables man page中文版)

--------------------------------------------------------------------------------
 
6、說說如何拆分包吧
現在我們知道如何選擇我們想要拆分的包了。為完成我們的規則,我們需要準確的告訴核心我們想要它如何做。

--------------------------------------------------------------------------------
 
6、1 Source NAT
你想要進行Source NAT,改變串連的源地址。這在POSTROUIING鏈中完成,就在它將送出去的最後一刻。這是一個重

要的細節,所有Linux本機上的其他任何東西(路由、包過濾)都會看見那個尚未改變的包。也意味著'-o'(送出接

口)選項可用了。
用指定'-j SNAT'來進行Source NAT,'--to-source'選項指定一個或一段IP地址,(加上)一個或一段可選的連接埠

號(只能用於UDP和TCP協議)。
# 改變源地址為1.2.3.4
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4
 
# 改變源地址為1.2.3.4、1.2.3.5或者1.2.3.6
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6
 
# 改變源地址為1.2.3.4,連接埠1-1023
# iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023

--------------------------------------------------------------------------------
 
6、1、1 偽裝
Source NAT的一個特例被稱作偽裝。它只能被用於動態分配IP地址的情況。例如標準撥號服務(靜態IP地址請用

SNAT)。
你無需為IP偽裝明確指定源地址。它會使用包送出的那個介面(地址)作為源地址。不過更重要的是,如果那個線

路關閉了的話,串連(無論如何都會丟失了)會被忘掉,意味著啟用新的IP後返回的包就會有點問題了(指那些響

應掉線前發出的包的包)。
# 偽裝所有由ppp0送出的東西
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

--------------------------------------------------------------------------------
 
6、2 Destination NAT
用於PREROUTING鏈,包剛剛進入的時候。意味著本機上的任何東西看見的都是“真正”的目的地(譯者註:即已修

改過的目的地址)。也意味著'-i'(進入介面)可用了。
用指定'-j DNAT'來進行Destination NAT,'--to-destination'選項指定定一個或一段IP地址,(加上)一個或一

段可選的連接埠號碼(只能用於UDP和TCP協議)。 
# 改變目標地址為5.6.7.8
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8
# 改變目標地址為5.6.7.8、5.6.7.9或5.6.7.10
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8-5.6.7.10
# 改變Web傳送的目標地址為5.6.7.8,8080連接埠
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to 5.6.7.8:8080

--------------------------------------------------------------------------------
 
6、2、1 重新導向
Destination NAT的一個特例被稱為重新導向。它相當於對進入介面進行DNAT的簡單方便的一種形式。
# 發送進入的80連接埠的Web傳輸到我們的Squid(透明)代理
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j REDIRECT --to-port 3128
注意Squid需要被配置為透明代理。

--------------------------------------------------------------------------------
 
6、3 深層次的映射
還有一些可能大部分人不會用到的NAT的細節。

--------------------------------------------------------------------------------
 
6、3、1 一個範圍內多地址的選擇
如果指定了IP地址的範圍,那麼機器會選擇當前使用最少的那個IP地址。這就實現了最儉樸的負載平衡。

--------------------------------------------------------------------------------
 
6、3、2 建立空的NAT映射。
你可以使用 '-j ACCEPT' 目標讓串連通過,不需要NAT參與。

--------------------------------------------------------------------------------
 
6、3、3 標準NAT行為
預設行為是根據使用者給定的內在約束規則,對串連作最小的改動。也就是除非必要 不要進行連接埠重新對應。

--------------------------------------------------------------------------------
 
6、3、4 內部源連接埠映射
如果其他的串連覆蓋了一個串連,即使這個串連不需要使用NAT,源地址轉換仍會發生。考慮IP偽裝,這種情況就非

常普遍。
1、一個從192.168.1.1 1024連接埠到www.netscape.com 80連接埠的Web串連已建立
2、它被偽裝成IP偽裝伺服器的IP地址(1.2.3.4)
3、IP偽裝伺服器試圖建立一個從www.netscape.com 80連接埠到1.2.3.4 1024連接埠的Web串連(它自己的外部介面IP地

址)
4、NAT代碼會修改第二個串連的源地址到1025,這樣兩個(串連)就不會衝突了。
當這種內部源地址映射發生時,連接埠分為三級:
512以下的連接埠
512至1023之間的連接埠
1024以上的連接埠
內部連接埠映射決不會被映射到(除此之外的)其他種類。

--------------------------------------------------------------------------------
 
6、3、5 如果NAT失敗會怎樣?
如果無法按照使用者請求的那樣,為串連建一個單獨的映射,(包)會被刪除。這也適用於那些無法被歸為任何串連

的包,因為它們是畸形的,或者是主機記憶體溢出了。

--------------------------------------------------------------------------------
 
6、3、6 多重新對應,重疊和衝突
你的NAT規則可以把包映射到相同的範圍。NAT代碼聰明到可以避免它們的衝突。因此,兩條規則把192.168.1.1和

192.168.1.2的源地址映射都映射到1.2.3.4是沒有問題的。
而且,你可以映射到真實的、已在使用的IP地址,只要那些地址也通過這個伺服器。所以如果你分配到一個網路

(1.2.3.0/24),但有一個內部網路使用了這些地址,另一個使用的是私人地址192.168.1.0/24,你可以簡單的NAT

192.168.1.0/24的源地址 到1.2.3.0網路,不必擔心衝突。
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to 1.2.3.0/24
相同的邏輯也適用於NAT伺服器本身的地址。這就是得以偽裝工作的原因(由偽裝後的包和來自本身的“真實”的包

共用一個介面地址)。
甚至,你可以映射相同的包到許多不同的目標,它們會被共用。例如,如果你不希望映射任何東西到1.2.3.5,你可

以這樣做:
# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT --to 1.2.3.0-1.2.3.4 --to 1.2.3.6

-1.2.3.254

--------------------------------------------------------------------------------
 
6、3、7 修改本地產生的串連的目標地址
NAT代碼允許你插入DNAT規則到OUTPUT鏈,不過這在2.4中尚未完全支援(可以使用,但必須用新的配置選項,某些

測試中的代碼。所以除非有人在瘋狂的寫這部分代碼,我不相信它會很快實現)。
當前的限制是你只能修改目標地址到本機(例如'-j DNAT --to 127.0.0.1'), 不能到任何其他機器,否則相應可

能不能夠被正確轉換。

--------------------------------------------------------------------------------
 
7、 特定的協議
有些協議不希望被NAT。這些協議,兩種延伸必須指明:一個是協議的串連跟蹤,一個是真實NAT。
在發布的netfilter中,有可用的FTP模組:ip_conntrack_ftp.o和ip_nat_ftp.o。如果你載入了任一種模組到你的

核心(或者編譯進去),那麼任何關於FTP串連的NAT都是可行的。如果沒有,那麼只能使用被動FTP(passive ftp

),而且如果做了一些Source NAT,它(指FTP)也許不能可靠的工作。

--------------------------------------------------------------------------------
 
8、 關於NAT的警告
如果你對串連做NAT,所有雙向傳送的包(進入和送出網路的)必須通過NAT伺服器,否則NAT伺服器的工作可能不可

靠。特別是,串連跟蹤代碼重組了分區,也就意味著不光是串連跟蹤不能可靠工作,甚至所有包都無法通過,因為

分區被丟棄。

--------------------------------------------------------------------------------
 
9、 Source NAT 和路由
如果你要做SNAT,你必須注意所有機器被SNAT的包的回應都將發送到NAT伺服器。例如,如果你映射了一些送出的包

的源地址為1.2.3.4,那麼外部的路由器必須知道發送回應包的地址到NAT伺服器。可以這樣做:
1、如果你對本機地址做SNAT(路由等所有事情都正常),你不需要做任何事。
2、如果你在本地LAN上做SNAT到未用地址(例如,你映射為1.2.3.99,你的1.2.3.0/24網路中未用的IP),你的NAT

伺服器需要像那個地址(99)一樣正確響應ARP請求。最簡單的辦法是建立一個IP別名,例如:
# ip address add 1.2.3.99 dev eth0
3、如果你對完全不同的地址做SNAT,你必須保證被SNAT的包到達的機器會返回NAT伺服器。如果NAT伺服器是它們的

預設閘道,那麼就已經行了,否則你需要發布一個路由(如果運行了路由協議)或者對每個機器手工添加路由。

--------------------------------------------------------------------------------
 
10、 同一個網路內的Destination NAT。
如果你要對同一個網路做連接埠轉寄,你需要確認所有以後的包和回應包都通過NAT伺服器(這樣它們才能被修改)。

NAT代碼現在(自2.4.0-test6),會屏蔽掉同組的被NAT的包送出的ICMP重新導向,不過收到的伺服器會繼續嘗試直接

響應客戶。(不會理解這個回應)
經典的情況是,內部人員試圖訪問你的“公用”Web伺服器,而它實際上從公用地址(1.2.3.4)被DNAT到內部機器

(192.168.1.1),例如:
# iptables -t nat -A PREROUTING -d 1.2.3.4 -p tcp --dport 80 -j DNAT --to 192.168.1.1
一種辦法是運行一台內部DNS伺服器,它知道你的公用(外部)Web伺服器的真實的(內部)IP地址,並轉寄所有其

他請求到外部DNS伺服器。也就是說你的Web伺服器能夠記錄真實的內部IP地址。
另一種辦法是讓NAT伺服器映射那些串連的源地址到它自己,讓伺服器通過它發出響應。例如,我們可以這樣做(假

設NAT伺服器內部IP地址是192.168.1.250):
# iptables -t nat -A POSTROUTING -d 192.168.1.1 -s 192.168.1.0/24 -p tcp --dport 80 -j SNAT --to

192.168.1.250
因為PREROUTING規則會首先運行,對內部Web伺服器來說,包的去向早已確定。我們可以確定好源IP地址。

--------------------------------------------------------------------------------
 
11. Thanks
Thanks first to WatchGuard, and David Bonn, who believed in the netfilter idea enough to support me

while I worked on it. And to everyone else who put up with my ranting as I learnt about the ugliness

of NAT, especially those who read my diary.
首先感謝在我工作期間相信netfilter設想並支援我的WatchGuard和David Bonn。以及所有對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.