iptables(三)網路地址轉換NAT

十五十六發表於2018-08-29

防火牆上的網路地址轉換有3類

  • SNAT 源地址轉換
  • DNAT 目的地址轉換
  • 埠對映

SNAT

源地址轉換,讓本地網路中的主機通過某一特定地址訪問外部網路,具體實現一般都在POSTROUTING鏈上,因為如果資料包是發給本機的。如果在PREROUTING鏈上做,不就是相當於浪費功夫嗎嗎,因為最後也是要發給自己,結果在發給自己之前還做了一層轉換,所以有點浪費資源了。綜合來說在POSTROUTING上做最合適。

為什麼要進行源地址轉換呢。我們想象一個場景,我們只有一個公網IP但是這時候我們有很多主機需要上網,我們內網的主機上網肯定需要公網IP才能上網。這時候我們只有一個公網IP,就可以進行SNAT轉換,吧訪問網際網路的資料包都發給那個擁有公網ip的閘道器。閘道器進行SNAT轉換,將源地址轉換為公網IP地址。公網上資料包響應請求的時候發給閘道器。由閘道器再把目標地址轉換回來。這樣有2個好處。第一.保證了內網主機的安全。第二,解決了ipv4地址緊缺的問題。

常用的幾個選項

--to-source [ipaddr[-ipaddr]][:port[-port]] ##表示要指定的新的源IP,這裡可以是多個地址
--random ##如果上面是多個地址,這個選項可以用來表示隨機選一個地址當作源地址
MASQUERADE 如果這裡的閘道器地址會一直變化。也就是將要指定的新的源IP一直變化的話,這裡可以使用這個選項。具體例子
##iptables -t nat -A POSTROUTING -s 192.168.253.0/24 -j MASQUERADE

原理圖

這裡寫圖片描述

實現

實現也比較簡單我們準備3臺機器,網路拓撲圖也就和原理圖一樣。
閘道器(閘道器有2個ip)

  • 192.168.253.128
  • 192.168.0.104

內網IP

  • 192.168.253.129

外網IP

  • 192.168.0.105

第一步,設定好網路環境。

閘道器:開啟核心轉發功能

sysctl  net.ipv4.ip_forward=1

第二步

內網主機:增加一條路由,將去192.168.0.0網段的都傳送給192.168.253.128這個閘道器

ip route add 192.168.0.0/24  via 192.168.253.128 dev eth0

第三步

外網主機:設定一下外網的路由條目,吧192.168.253.0網段的資料包。傳送給192.168.0.104(閘道器)處理

ip route add 192.168.253.0/24 via 192.168.0.104 dev ens33

第四步

測試一下
現在我們在內網ping一下外網看能不能通
這裡寫圖片描述
這裡表示成功了。

第五步

網路環境配置好了。我們現在正式來做snat
在閘道器設定,將源地址為192.168.253.0網段的資料包做snat轉換,將源地址改為192.168.253.104

iptables -t nat -A POSTROUTING -s 192.168.253.0/24 -j SNAT --to-source 192.168.0.104

有一點,如果這裡的閘道器的IP是動態IP不是一個固定的外網ip則需要使用下面這條命令

iptables -t nat -A POSTROUTING -s 192.168.253.0/24 -j MASQUERADE

第六步

我們現在外網主機上安裝httpd服務

yum install httpd -y
echo "hello nat" > /var/www/html/index.html ##製作一個測試頁
systemctl  start httpd ##啟動服務

然後我們在外網這臺主機上抓包
這裡寫圖片描述
這裡可以看到請求的ip已經變成閘道器的ip192.168.0.104了

我們也可以再驗證一下,我們在閘道器上,清空防火牆規則
然後再用內網訪問一次,同時在外網抓包
這裡寫圖片描述
清空規則之後,這裡的源ip已經變成了192.168.253.129也就是內網IP了。說明確實是那條命令生效了

DNAT

DNAT 的全稱為Destination Network Address Translation目的地址轉換,原理和SNAT類似,只是DNAT修改的是目的地址。而SNAT修改的是源地址。
還有就是DNAT一般在PREROUTING鏈上修改。為什麼呢。我們可以這樣想。如果本地主機正好也開啟了一個和服務端提供服務相同的埠,這時候,我們再去訪問閘道器,閘道器將會將請求送到自己的使用者空間,這樣後端的伺服器就沒有收到請求。而客戶端得到的也不是他想要的東西。所以綜合考慮在PREROUTING會比較好。

那DNAT主要是為了解決什麼樣的問題呢?我們想象這樣一個場景。假設我們不是客戶端了。我們現在是服務端,要提供web服務。當使用者來連線的時候,如果直接訪問我們的真實伺服器。這是不是不太好。相當於直接暴露在公網,有一些黑客很容易就攻擊你。而如果我們告訴使用者一個ip,讓使用者來連線這個ip。再由這個閘道器或者說防火牆進行DNAT,轉發給後端。這樣一來,至少有2個好處。第一,保證了後端主機的一定安全,因為沒有直接暴露在公網。第二,如果躲在閘道器後面的伺服器不止一臺。我們還可以做一些負載均衡,讓網站更健壯。(但是這種直接配置iptables來完成負載均衡的方法,一般不這麼用了。)

常用的幾個選項

--to-destination [ipaddr[-ipaddr]][:port[-port]] ##將要進行變換的DST地址。可以是多個
--random ##如果上面的地址有多個,則隨機選一個指定。

實現

實驗環境:
閘道器(閘道器有2個ip)

  • 192.168.253.128
  • 192.168.0.104

使用者客戶端

  • 192.168.253.129

後端真實伺服器IP

  • 192.168.0.105

內容:環境還是差不多但是角色變了,我們這裡用使用者客戶端去訪問閘道器。由閘道器進行目的地址轉換。
剛才的那些轉發路由條目已經設定好了 ,我們只需要清空閘道器的規則,重新寫一條規則就可以了

iptables  -t nat -F  ##清空nat表所有規則
iptables  -t nat -X  ##刪除nat表中所有自定義的空鏈
iptables -t nat -A PREROUTING -d 192.168.253.128 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.105

然後我們測試一下,在客戶端訪問閘道器192.168.253.128
這裡寫圖片描述
這個就比較明顯了。我們訪問的閘道器,但是收到了192.168.0.105這臺伺服器上的起始頁資訊。所以可以看出是成功了

埠對映

埠對映,顧名思義,就是修改埠。
實現比較簡單直接簡單說一下,試驗環境就是上面的網路環境。實驗內容:我們訪問閘道器192.168.253.128的80埠。然後轉發到後端192.168.0.105的8080埠。
閘道器:我們先清空閘道器的nat表

iptables  -t nat -F  ##清空nat表所有規則
iptables  -t nat -X  ##刪除nat表中所有自定義的空鏈
iptables -t nat -A PREROUTING -d 192.168.253.128 -p tcp --dport 80 -j DNAT --to-destination 192.168.0.105:8080

後端伺服器:將httpd埠換到8080埠
修改配置檔案/etc/httpd/conf/httpd.conf

Listen 8080##設定為8080

重啟httpd服務

systemctl  restart httpd

然後看一下8080埠起了沒
這裡寫圖片描述

再用客戶端訪問一次
這裡寫圖片描述
訪問成功。這裡想說明的一點這個訪問成功不是因為快取,我們可以換一個起始頁再測試

echo "i am 8080" > /var/www/html/index.html 

再用客戶端訪問一次。
這裡寫圖片描述

相關文章