關(guān)于iptables iptables提供的NAT的分析與應(yīng)用 為什么要進(jìn)行NAT?一個(gè)很好的例子:假設(shè)我們只有一臺(tái)服務(wù)器具有外網(wǎng)IP,其他服務(wù)器都只具有內(nèi)網(wǎng)IP,那么這些內(nèi)網(wǎng)服務(wù)器外網(wǎng)無法訪問到。那么我們可以將具有外網(wǎng)IP的那臺(tái)服務(wù)器作為一個(gè)路由中轉(zhuǎn),將請(qǐng)求轉(zhuǎn)發(fā)到內(nèi)網(wǎng)的機(jī)器上來。如何轉(zhuǎn)發(fā)呢?大家都知道IP報(bào)文中有兩個(gè)重要的地址屬性:源地址與目的地址。IP報(bào)文傳遞過程中需要經(jīng)過哪臺(tái)機(jī)器,是由這兩個(gè)地址所決定的。 首先有個(gè)問題要明確。首先,客戶端對(duì)某臺(tái)服務(wù)器訪問時(shí),可能會(huì)需要多個(gè)路由的轉(zhuǎn)發(fā)才能到達(dá),但是這樣的轉(zhuǎn)發(fā)并沒有改變IP報(bào)文的源地址和目的地址,路由器是通過改變目的MAC地址來決定下一個(gè)轉(zhuǎn)發(fā)的位置的。NAT(Network Address Translation)包含DNAT和SNAT,即目的地址轉(zhuǎn)換與源地址轉(zhuǎn)換。DNAT可以實(shí)現(xiàn)當(dāng)IP報(bào)文到達(dá)某臺(tái)主機(jī)時(shí),通過改變目的地址,將該IP報(bào)文再轉(zhuǎn)發(fā)到其他主機(jī)上。當(dāng)遇到第一個(gè)IP報(bào)文被轉(zhuǎn)發(fā)后,后面的數(shù)據(jù)流會(huì)自動(dòng)轉(zhuǎn)發(fā)。而SNAT與DNAT相似,只是改變的是源地址。下圖展示了iptables的結(jié)構(gòu)流程圖。 ip報(bào)文在通過iptables過程中,首先要經(jīng)過PREROUTING階段,然后通過過濾、處理、判斷該報(bào)文是否需要被轉(zhuǎn)發(fā)或是在本機(jī)進(jìn)行處理,之后會(huì)到達(dá)POSTROUTING階段,進(jìn)而完成iptables的處理(其他階段的處理細(xì)節(jié)可以參考上一節(jié)給出的鏈接)。因此,DNAT需要在PREROUTING階段進(jìn)行而SNAT必須在POSTROUTING階段進(jìn)行。 命令格式: DNAT:iptables -t nat -A PREROUTING --dst $INET_IP -p tcp --dport 80 -j DNAT \ --to-destination $HTTP_IP 將匹配$INET_IP:80的IP報(bào)文的目的地址更改為$HTTP_IP SNAT:iptables -t nat -A POSTROUTING -p tcp --dst $HTTP_IP --dport 80 -j SNAT \ --to-source $LAN_IP 將匹配$HTTP_IP:80的IP報(bào)文源地址更改為$LAN_IP 接下來重點(diǎn)提及一下de-DNAT(反向目的地址轉(zhuǎn)換)以及de-SNAT(反向源地址轉(zhuǎn)換),網(wǎng)上的信息比較少,本人通過參考Where the de-SNAT actually takes place?了解到,de-DNAT和de-SNAT發(fā)生的位置與DNAT和SNAT正好相反。也就是說DNAT發(fā)生在PREROUTING階段,而de-DNAT發(fā)生在POSTROUTING階段,都是是將地址進(jìn)行對(duì)換的過程,前者改變的目的地址,而后者其實(shí)改變的是源地址(該源地址是DNAT操作前的目的地址)。這就解釋了為什么客戶端發(fā)出的IP報(bào)文通過iptables改變目的地址后,還可以得到正確的回復(fù)。 舉一個(gè)例子:
在上圖的模型中。client為外網(wǎng)的一個(gè)客戶端,Router具有外網(wǎng)IP-Router_WAN_IP和內(nèi)網(wǎng)Router_LAN_IP,一系列Server與Router在同一個(gè)內(nèi)網(wǎng),但是只有內(nèi)網(wǎng)IP。我們用Router機(jī)器做地址轉(zhuǎn)換,將client發(fā)送的請(qǐng)求轉(zhuǎn)發(fā)到具有Server_IP的內(nèi)網(wǎng)機(jī)器上。 1、client發(fā)出對(duì)Router的請(qǐng)求,IP報(bào)文的地址<Client_IP , Router_WAN_IP>, 當(dāng)該報(bào)文到達(dá)Router上的iptables,首先進(jìn)入PREROUTING階段,如果配置了DNAT且地址匹配成功,會(huì)將該報(bào)文的目的地址進(jìn)行更改為內(nèi)網(wǎng)Server_IP,報(bào)文地址格式<Client_IP , Server_IP>。 在以上步驟中,我們似乎沒有進(jìn)行SNAT的操作,也實(shí)現(xiàn)了基本設(shè)想。但是如果Client也處于與其他機(jī)器一起的內(nèi)網(wǎng)環(huán)境的話,就出現(xiàn)了問題。因?yàn)樵谏厦娴牟襟E3中,新的報(bào)文Client_IP是可以直接到達(dá)的,那么該報(bào)文就不會(huì)經(jīng)過Router,而直接轉(zhuǎn)發(fā)給了Client。但是,這時(shí)候Client接受到報(bào)文之后,發(fā)現(xiàn)與其請(qǐng)求的目的地址不一致(因?yàn)镃lient最初請(qǐng)求的是Router的地址),因此Client會(huì)把這個(gè)報(bào)文丟掉。因此,我們就必須要讓從Server回來的報(bào)文首先經(jīng)過Router,我們需要改變從Router出來的IP報(bào)文的源地址。使用SNAT可以實(shí)現(xiàn)源地址的轉(zhuǎn)換。這樣就把從Router出來的報(bào)文轉(zhuǎn)換為<Router_LAN_IP ,Server_IP>,再經(jīng)過Server回復(fù),產(chǎn)生新的報(bào)文地址<Server_IP , Router_LAN_IP>。該報(bào)文會(huì)發(fā)送到Router,iptables會(huì)進(jìn)行反向DNAT和反向SNAT,將報(bào)文地址改為<Router_WAN_IP ,Client_IP>,最后返回到Client。 但是上面會(huì)產(chǎn)生一個(gè)問題,就是Server接收到的報(bào)文的源地址都是Router,而無法得知最初的Client地址,對(duì)于某些功能需求,這是很不好的。在參考鏈接中,有相關(guān)的解決辦法講述,這里不做贅述。 總結(jié): 最近在做一個(gè)東西,所以學(xué)習(xí)了iptables,個(gè)人覺得iptables是非常強(qiáng)大的。本文是個(gè)人對(duì)用iptables進(jìn)行NAT的一些思考與理解,由于對(duì)iptables了解尚淺且個(gè)人能力有限,本文內(nèi)容僅供參考,還請(qǐng)批評(píng)指正。 |
|