Linux主機上通過iptables實現NAT功能

     

實驗:如下模型,node1爲內網主機,IP地址爲192.168.10.2node3爲外網主機,IP地址爲10.72.37.177(假設此地址爲公網地址),node3上提供web serverFTP Server的功能;內網主機node2主機有2塊網卡,地址分別爲eth0:192.168.10.1eth2:10.72.37.91(假設此地址爲公網地址);

現要求在node2上通過iptables配置實現SNAT功能,並做如下限制:

1、node1可以訪問node3提供的web服務和ftp服務

2node1只可以ping連接、ssh連接node3

                             wKiom1QsE5GB2XE1AAFXJY6jNHA568.jpg

SNAT實現的過程:

node1node2都是內網主機處於同一網段,所以node1是默認直接可以pingnode2主機上eth1的地址192.168.10.1;將node1主機的網關指向192.168.10.1後,node1就可以直接pingnode2eth0上的外網地址10.72.37.91

但此時內網主機node1肯定是無法ping通外網主機node3的地址,此時開啓node2主機的路由轉發功能,即可實現將node1的請求報文,經由node2轉發送到node3主機上,但是node3響應此報文時,發現源地址爲192.168.10.1,與自己不在同一網段內,便會交由網關去轉發,而node3的網關默認也是無法識別此網絡,所以響應報文也就無法返回到node2

所以即可以配置,node2node1的請求報文轉發出去之前,將請求報文的源地址由192.168.10.2轉換爲10.72.37.91後再送至node3主機上,此過程中node2同時會自動生成一張NAT會話表,記錄下經由node2被轉發的每一條記錄;

node3封裝響應報文時,發現源地址爲10.72.37.91,所以響應報文的目標地址就會是10.72.37.91,響應報文即會被返回給node2,此時node2上就會查詢NAT會話表,自動再做目標地址轉換,將響應報文送至node1,此即實現了內網主機node1與外網主機node3通信了;iptablesSNAT即是實現此功能;

此過程中報文在node1node2node3之間傳輸路徑如下圖:

wKiom1QsqGKA14pVAAGcETpfZPQ779.jpg

一個請求報文經由node2主機路由判斷後,需要被轉發出去的話,此請求報文則會經過node2主機上netfilter的鏈的順序爲PREROUTING--> FORWARD-->OUTROUTING,所以SNAT的規則需配置在OUTROUTING鏈上,而filter的規則就需要在FORWARD鏈上配置了(此路徑中只有在FORWARD鏈上有filter功能表,PREROUTINGOUTROUTING鏈上不做filter

 

總結:爲了實現node1可以與node3通信需做的配置有:

1node1主機的默認網關指向node2eth1的地址

1node2主機上的開啓路由轉發功能

2node2主機上配置SNAT功能

 

配置過程:

node1上:

#ping 192.168.10.1                                          ##是可以直接ping通的

#route add default gw192.168.10.1              ##添加路由指向192.168.10.1

#ping 10.72.37.91                                             ##即可pingnode2主機上的另一個地址

 

node2上:

#sysctl -wnet.ipv4.ip_forward=1                    ##開啓node2主機上的路由轉發功能

 

node1上:

#ping 10.72.37.177                                            ##此時,node1上暫且是無法pingnode3的,但是此時ping的請求包是已經可以發送到node3

 

node3上:

#iptables -t filter -A INPUT -j LOG                  ##node3主機的INPUT鏈上添加LOG功能

#tail /var/log/messages                                   ##即可看到,已記錄到來自192.168.10.2node1ICMP請求報文

… … kernel: IN=eth0OUT= MAC=1c:6f:65:03:1b:9a:00:0c:29:fa:ea:2d:08:00 SRC=192.168.10.2DST=10.72.37.177 LEN=84 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=ICMP TYPE=8CODE=0 ID=4876 SEQ=9

         ##如果此時在OUTPUT鏈上也記錄LOG的話,也是可以看到SRC=10.72.37.177DST=192.168.10.2的響應報文,只不過是這個響應報文最終無法送達node1

 

node2

#iptables -t nat -APOSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 10.72.37.91

##node2主機上的的POSTROUTING鏈上向NAT表中添加,定義來自192.168.10.0的主機,無論是使用何種協議,無論訪問哪個網絡,通通代理出去,將源地址轉換成10.72.37.91

#iptables -t nat -L POSTROUTING -nv            ##nat表的POSTROUTING鏈上即可看到我們添加的規則

 

    此時,node1即可以pingnode3,而在node3主機上的log中可以看到ICMP的請求報文SRC=10.72.37.91 DST=10.72.37.177和響應報文SRC=10.72.37.177DST=10.72.37.91;注意此時的與node3通信的IP地址已被SANT轉換爲10.72.37.91了;

 

node1

#curl -I http://10.72.37.177                ##測試連接node3web服務

#tail /var/log/nginx/access.log         ##node3上查看訪問日誌中,客戶端源地址的已是被轉換後的10.72.37.91

 

         按照要求node1只可以向node3發起pingshhweb訪問請求,所以在node2上的filter表的FORWARD鏈上添加如下規則:

#iptables -t filter -P FORWARD DROP
#iptables -t filter -I FORWARD 1 -s192.168.10.0/24 -p icmp --icmp-type 8 -j ACCEPT
        ##轉發來自192.168.10.0/24的ICMP協議的請求報文
#iptables -t filter -I FORWARD 1 -s10.72.37.0/24 -p icmp --icmp-type 0 -j ACCEPT
        ##轉發來自10.72.37.0/24的ICMP協議的響應報文
#iptables -t filter-A FORWAORD -s 192.168.10.0/24 -p tcp -m state --state NEW -m multiport --destination-ports 21,22,80 -j ACCEPT
        ##轉發來自192.168.10.0/24的狀態爲NEW,訪問ftp,ssh,web的請求
#iptables -t filter -A FORWARD -m state--state ESTABLISHED,RELATED -j ACCEPT 
         ##轉發所有狀態爲ESTABLISHED和RELATED(for ftp)狀態的請求

 

    node1通過node3上的21端口和ftp server建立命令連接後,因爲ftp server默認是工作在被動模式,所以node1還需訪問node3上的一個大於1024的隨機端口來建立數據連接,即需要node2上將所有所有大於1024的端口都轉發至node3;但是本實驗又要求只允許轉發21,22,80端口;

    此時要求node3主機上需已裝載內核模塊nf_contrack_ftp這個模塊可以監控ftp控制流,能夠事先知道將要建立的ftp數據連接所使用的端口,從而可以允許相應的數據包通過,即使防火牆沒有開放這個端口:

#modprobe nf_contrack_ftp          ##手動裝載此內核模塊

#lsmod | grep ftp                             ##此時即可看到已裝載

    ##或者寫到配置文件/etc/sysconfig/iptables-config,即可不需每次去手動裝載,即使重啓後也會自動裝載,添加一行:IPTABLES_MOUDLES=”nf_contrack_ftp”

 

    假若node3沒有裝載內核模塊nf_conntrack_ftp,在node1上連接node3上的ftp服務時,就會有如下報錯信息:無法建立數據連接到(10.72.37.177) 端口 29814

lftp [email protected]:~> debug

lftp [email protected]:~> ls

---- 正在連接到 10.72.37.177(10.72.37.177) 端口 21

<--- 220 (vsFTPd 2.2.2)

---> FEAT

<--- 211-Features:

<--- EPRT

<--- EPSV

<--- MDTM

<--- PASV

<--- REST STREAM

<--- SIZE

<--- TVFS

<--- UTF8

<--- 211 End

---> OPTS UTF8 ON

<--- 200 Always in UTF8 mode.

---> USER user2

<--- 331 Please specify the password.

---> PASS XXXX

<--- 230 Login successful.     

---> PASV

<--- 227 Entering Passive Mode(10,72,37,177,116,118).

---- 正在建立數據連接到(10.72.37.177) 端口 29814

`ls' at 0 [正在建立數據連接...]

...

    以上,即基於node2主機上的FORWARD鏈實現了網絡防火牆,內網主機通過node2訪問外網時,通過FORWARD鏈實現了訪問控制。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章