濮阳杆衣贸易有限公司

主頁 > 知識庫 > 詳解Linux下iptables中的DNAT與SNAT設置

詳解Linux下iptables中的DNAT與SNAT設置

熱門標簽:小語股票電銷機器人 柯城手機地圖如何做地圖標注 杭州電銷機器人有效果嗎 襄陽地圖標注店 萊蕪移動外呼系統(tǒng) 金華呼叫中心外呼系統(tǒng)廠家 軟件電話機器人 申請400電話流程好嗎 高德地圖標注在電腦上

DNAT(Destination Network Address Translation,目的地址轉換) 通常被叫做目的映謝。而SNAT(Source Network Address Translation,源地址轉換)通常被叫做源映謝。
這是我們在設置Linux網(wǎng)關或者防火墻時經(jīng)常要用來的兩種方式。以前對這兩個都解釋得不太清楚,現(xiàn)在我在這里解釋一下。
首先,我們要了解一下IP包的結構,如下圖所示:

在任何一個IP數(shù)據(jù)包中,都會有Source IP Address與Destination IP Address這兩個字段,數(shù)據(jù)包所經(jīng)過的路由器也是根據(jù)這兩個字段是判定數(shù)據(jù)包是由什么地方發(fā)過來的,它要將數(shù)據(jù)包發(fā)到什么地方去。而iptables的DNAT與SNAT就是根據(jù)這個原理,對Source IP Address與Destination IP Address進行修改。
然后,我們再看看數(shù)據(jù)包在iptables中要經(jīng)過的鏈(chain):

圖中正菱形的區(qū)域是對數(shù)據(jù)包進行判定轉發(fā)的地方。在這里,系統(tǒng)會根據(jù)IP數(shù)據(jù)包中的destination ip address中的IP地址對數(shù)據(jù)包進行分發(fā)。如果destination ip adress是本機地址,數(shù)據(jù)將會被轉交給INPUT鏈。如果不是本機地址,則交給FORWARD鏈檢測。
這也就是說,我們要做的DNAT要在進入這個菱形轉發(fā)區(qū)域之前,也就是在PREROUTING鏈中做,比如我們要把訪問202.103.96.112的訪問轉發(fā)到192.168.0.112上:
iptables -t nat -A PREROUTING -d 202.103.96.112 -j DNAT --to-destination 192.168.0.112
這個轉換過程當中,其實就是將已經(jīng)達到這臺Linux網(wǎng)關(防火墻)上的數(shù)據(jù)包上的destination ip address從202.103.96.112修改為192.168.0.112然后交給系統(tǒng)路由進行轉發(fā)。
而SNAT自然是要在數(shù)據(jù)包流出這臺機器之前的最后一個鏈也就是POSTROUTING鏈來進行操作
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 58.20.51.66
這個語句就是告訴系統(tǒng)把即將要流出本機的數(shù)據(jù)的source ip address修改成為58.20.51.66。這樣,數(shù)據(jù)包在達到目的機器以后,目的機器會將包返回到58.20.51.66也就是本機。如果不做這個操作,那么你的數(shù)據(jù)包在傳遞的過程中,reply的包肯定會丟失。

注意,DNAT target只能用在nat表的PREOUTING 和 OUTPUT 鏈中,或者是被這兩條鏈調用的鏈里。但還要注意的是,包含DNAT target的連不能被除此之外的其他鏈調用,如POSTROUTING。

復制代碼
代碼如下:

Table 6-16. DNAT target
Option --to-destination
Example iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10

    Explanation指定要寫入IP頭的地址,這也是包要被轉發(fā)到的地方。上面的例子就是把所有發(fā)往地址15.45.23.67的包都轉發(fā)到一段LAN使用的私有地址中,即192.168.1.1到192.168.1.10。如前所述,在這種情況下,每個流都會被隨機分配一個要轉發(fā)到的地址,但同一個流總是使用同一個地址。我們也可以只指定一個IP地址作為參數(shù),這樣所有包都被轉發(fā)到同一臺機子。我們還可以在地址后指定一個或一個范圍的端口。比如:--to-destination 192.168.1.1:80或192.168.1.1:80-100。SNAT的語法和這個target的一樣,只是目的不同罷了。要注意,只有先用--protocol指定了TCP或UDP協(xié)議,才能使用端口。
    因為DNAT要做很多工作,所以我要再啰嗦一點。我們通過一個例子來大致理解一下它是如何工作的。比如,我想通過Internet連接發(fā)布我們的網(wǎng)站,但是HTTP server在我們的內網(wǎng)里,而且我們對外只有一個合法的IP,就是防火墻那個對外的IP——$INET_IP。防火墻還有一個內網(wǎng)的IP——$LAN_IP,HTTP server的IP是%HTTP_IP(當然這是內網(wǎng)的了)。為了完成我們的設想,要做的第一件事就是把下面這個簡單的規(guī)則加入到nat表的PREROUTING鏈中:

復制代碼
代碼如下:

iptables -t nat -A PREROUTING --dst$INET_IP -p tcp --dport 80 -j DNAT / --to-destination $HTTP_IP

    現(xiàn)在,所有從Internet來的、到防火墻的80端口去的包都會被轉發(fā)(或稱作被DNAT)到在內網(wǎng)的HTTP服務器上。如果你在Internet上試驗一下,一切正常吧。再從內網(wǎng)里試驗一下,完全不能用吧。這其實是路由的問題。下面我們來好好分析這個問題。為了容易閱讀,我們把在外網(wǎng)上訪問我們服務器的那臺機子的IP地址記為$EXT_BOX。
    包從地址為$EXT_BOX的機子出發(fā),去往地址為$INET_IP的機子。
    包到達防火墻。
    防火墻DNAT(也就是轉發(fā))這個包,而且包會經(jīng)過很多其他的鏈檢驗及處理。
    包離開防火墻向$HTTP_IP前進。
    包到達HTTP服務器,服務器就會通過防火墻給以回應,當然,這要求把防火墻作為HTTP到達$EXT_BOX的網(wǎng)關。一般情況下,防火墻就是HTTP服務器的缺省網(wǎng)關。
    防火墻再對返回包做Un-DNAT(就是照著DNAT的步驟反過來做一遍),這樣就好像是防火墻自己回復了那個來自外網(wǎng)的請求包。
    返回包好像沒經(jīng)過這么復雜的處理、沒事一樣回到$EXT_BOX。
    現(xiàn)在,我們來考慮和HTTP服務器在同一個內網(wǎng)(這里是指所有機子不需要經(jīng)過路由器而可以直接互相訪問的網(wǎng)絡,不是那種把服務器和客戶機又分在不同子網(wǎng)的情況)的客戶訪問它時會發(fā)生什么。我們假設客戶機的IP為$LAN_BOX,其他設置同上。
    包離開$LAN_BOX,去往$INET_IP。
    包到達防火墻。
    包被DNAT,而且還會經(jīng)過其他的處理。但是包沒有經(jīng)過SNAT的處理,所以包還是使用它自己的源地址,就是$LAN_BOX(譯者注:這就是IP傳輸包的特點,只根據(jù)目的地的不同而改變目的地址,但不因傳輸過程要經(jīng)過很多路由器而隨著路由器改變其源地址,除非你單獨進行源地址的改變。其實這一步的處理和對外來包的處理是一樣的,只不過內網(wǎng)包的問題就在于此,所以這里交代一下原因)。
    包離開防火墻,到達HTTP服務器。
    HTTP服務器試圖回復這個包。它在路由數(shù)據(jù)庫中看到包是來自同一個網(wǎng)絡的一臺機子,因此它會把回復包直接發(fā)送到請求包的源地址(現(xiàn)在是回復包的目的地址),也就是$LAN_BOX。
    回復包到達客戶機,但它會很困惑,因為這個包不是來自它訪問的那臺機子。這樣,它就會把這個包扔掉而去等待“真正”的回復包。
    針對這個問題有個簡單的解決辦法,因為這些包都要進入防火墻,而且它們都去往需要做DNAT才能到達的那個地址,所以我們只要對這些包做SNAT操作即可。比如,我們來考慮上面的例子,如果對那些進入防火墻而且是去往地址為$HTTP_IP、端口為80的包做SNAT操作,那么這些包就好像是從$LAN_IP來的了。這樣,HTTP服務器就會把回復包發(fā)給防火墻,而防火墻會再對包做Un-DNAT操作,并把包發(fā)送到客戶機。解決問題的規(guī)則如下:
    iptables -t -nat -A POSTROUTING -p tcp --dst$HTTP_IP --dport 80 -j SNAT / --to-source $LAN_IP
    要記住,按運行的順序POSTROUTING鏈是所有鏈中最后一個,因此包到達這條鏈時,已經(jīng)被做過DNAT操作了,所以我們在規(guī)則里要基于內網(wǎng)的地址$HTTP_IP(包的目的地)來匹配包。
    警告:我們剛才寫的這條規(guī)則會對日志產(chǎn)生很大影響,這種影響應該說是很不好的,因為來自Internet包在防火墻內先后經(jīng)過了DNAT和SNAT處理,才能到達HTTP服務器(上面的例子),所以HTTP服務器就認為包是防火墻發(fā)來的,而不知道真正的源頭是其他的IP。這樣, 當它記錄服務情況時,所有訪問記錄的源地址都是防火墻的IP而不是真正的訪問源。我們如果想根據(jù)這些記錄來了解訪問情況就不可能了。因此上面提供的“簡單辦法”并不是一個明智的選擇,但它確實可以解決“能夠訪問”的問題,只是沒有考慮到日志而已。
    其他的服務也有類似的問題。比如,你在LAN內建立了SMTP服務器,那你就要設置防火墻以便能轉發(fā)SMTP的數(shù)據(jù)流。這樣你就創(chuàng)建了一個開放SMTP的中繼服務器,隨之而來的就是日志的問題了。
    一定要注意,這里所說的問題只是針對沒有建立DMZ或類似結構的網(wǎng)絡,并且內網(wǎng)的用戶訪問的是服務器的外網(wǎng)地址而言的。(譯者注:因為如果建立的DMZ,或者服務器和客戶機又被分在不同的子網(wǎng)里,那就不需要這么麻煩了。因為所有訪問的源頭都不在服務器所在的網(wǎng)里,所以就沒有必要做SNAT去改變包的源地址了,從而記錄也就不是問題了。如果內網(wǎng)客戶是直接訪問服務器的內網(wǎng)地址那就更沒事了)
    比較好的解決辦法是為你的LAN在內網(wǎng)建立一臺單獨的DNS服務器(譯者注:這樣,內網(wǎng)客戶使用網(wǎng)站名訪問HTTP服務器時,DNS就可以把他解析成內網(wǎng)地址。客戶機就可以直接去訪問HTTP服務器的內網(wǎng)地址了,從而避免了通過防火墻的操作,而且包的源地址也可以被HTTP服務器的日志使用,也就沒有上面說的日志問題了。),或者干脆建立DMZ得了(這是最好的辦法,但你要有錢哦,因為用的設備多啊)。
    對上面的例子應該考慮再全面些,現(xiàn)在還有一個問題沒解決,就是防火墻自己要訪問HTTP服務器時會發(fā)生什么,能正常訪問嗎?你覺得呢:)很可惜,現(xiàn)在的配置還是不行,仔細想想就明白了。我們這里討論的基礎都是假設機子訪問的是HTTP服務器的外網(wǎng)地址,那客戶機就會看到頁面內容,不過這不是它想看到的(它想要的在DNAT上了),如果沒有HTTP服務,客戶就只能收到錯誤信息了。前面給出的規(guī)則之所以不起作用是因為從防火墻發(fā)出的請求包不會經(jīng)過那兩條鏈。還記得防火墻自己發(fā)出的包經(jīng)過哪些鏈吧:) 我們要在nat表的OUTPUT鏈中添加下面的規(guī)則:

復制代碼
代碼如下:

iptables -t nat -A OUTPUT --dst$INET_IP -p tcp --dport 80 -j DNAT / --to-destination $HTTP_IP

    有了最后這條規(guī)則,一切都正常了。和HTTP服務器不在同一個網(wǎng)的機子能正常訪問服務了,和它在一個網(wǎng)內的機子也可以正常訪問服務了,防火墻本身也可以正常訪問服務了,沒有什么問題了。    我想大家應該能明白這些規(guī)則只是說明了數(shù)據(jù)包是如何恰當?shù)谋籇NAT和SNAT的。除此之外,在filter表中還需要其他的規(guī)則(在FORWARD鏈里),以允許特定的包也能經(jīng)過前面寫的(在POSTROUTING鏈和OUTPUT鏈里的)規(guī)則。千萬不要忘了,那些包在到達FORWARD鏈之前已經(jīng)在PREROUTING鏈里被DNAT過了,也就是說它們的目的地址已經(jīng)被改寫,在寫規(guī)則時要注意這一點。

標簽:海北 河南 景德鎮(zhèn) 威海 鶴壁 天門 欽州 黔南

巨人網(wǎng)絡通訊聲明:本文標題《詳解Linux下iptables中的DNAT與SNAT設置》,本文關鍵詞  詳解,Linux,下,iptables,中的,;如發(fā)現(xiàn)本文內容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《詳解Linux下iptables中的DNAT與SNAT設置》相關的同類信息!
  • 本頁收集關于詳解Linux下iptables中的DNAT與SNAT設置的相關信息資訊供網(wǎng)民參考!
  • 推薦文章
    平塘县| 新沂市| 景德镇市| 武胜县| 靖远县| 五台县| 德格县| 佛冈县| 库尔勒市| 易门县| 通河县| 苗栗市| 凤冈县| 南汇区| 贺州市| 北票市| 纳雍县| 金湖县| 新野县| 凌云县| 教育| 萝北县| 商丘市| 镇安县| 咸宁市| 潜江市| 金堂县| 高清| 遵义市| 林周县| 十堰市| 昭觉县| 徐汇区| 兴隆县| 琼结县| 郧西县| 马尔康县| 榕江县| 陇南市| 河西区| 和平区|