實驗:如下模型,node1爲內網主機,IP地址爲192.168.10.2;node3爲外網主機,IP地址爲10.72.37.177(假設此地址爲公網地址),node3上提供web server和FTP Server的功能;內網主機node2主機有2塊網卡,地址分別爲eth0:192.168.10.1和eth2:10.72.37.91(假設此地址爲公網地址);
現要求在node2上通過iptables配置實現SNAT功能,並做如下限制:
1、node1可以訪問node3提供的web服務和ftp服務
2、node1只可以ping連接、ssh連接node3
SNAT實現的過程:
node1與node2都是內網主機處於同一網段,所以node1是默認直接可以ping通node2主機上eth1的地址192.168.10.1;將node1主機的網關指向192.168.10.1後,node1就可以直接ping通node2的eth0上的外網地址10.72.37.91;
但此時內網主機node1肯定是無法ping通外網主機node3的地址,此時開啓node2主機的路由轉發功能,即可實現將node1的請求報文,經由node2轉發送到node3主機上,但是node3響應此報文時,發現源地址爲192.168.10.1,與自己不在同一網段內,便會交由網關去轉發,而node3的網關默認也是無法識別此網絡,所以響應報文也就無法返回到node2;
所以即可以配置,node2把node1的請求報文轉發出去之前,將請求報文的源地址由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通信了;iptables的SNAT即是實現此功能;
此過程中報文在node1、node2和node3之間傳輸路徑如下圖:
一個請求報文經由node2主機路由判斷後,需要被轉發出去的話,此請求報文則會經過node2主機上netfilter的鏈的順序爲PREROUTING--> FORWARD-->OUTROUTING,所以SNAT的規則需配置在OUTROUTING鏈上,而filter的規則就需要在FORWARD鏈上配置了(此路徑中只有在FORWARD鏈上有filter功能表,PREROUTING和OUTROUTING鏈上不做filter);
總結:爲了實現node1可以與node3通信需做的配置有:
1、node1主機的默認網關指向node2的eth1的地址
1、node2主機上的開啓路由轉發功能
2、node2主機上配置SNAT功能
配置過程:
node1上:
#ping 192.168.10.1 ##是可以直接ping通的
#route add default gw192.168.10.1 ##添加路由指向192.168.10.1
#ping 10.72.37.91 ##即可ping通node2主機上的另一個地址
node2上:
#sysctl -wnet.ipv4.ip_forward=1 ##開啓node2主機上的路由轉發功能
node1上:
#ping 10.72.37.177 ##此時,node1上暫且是無法ping通node3的,但是此時ping的請求包是已經可以發送到node3的
node3上:
#iptables -t filter -A INPUT -j LOG ##在node3主機的INPUT鏈上添加LOG功能
#tail /var/log/messages ##即可看到,已記錄到來自192.168.10.2即node1的ICMP請求報文
… … 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即可以ping通node3,而在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 ##測試連接node3的web服務
#tail /var/log/nginx/access.log ##node3上查看訪問日誌中,客戶端源地址的已是被轉換後的10.72.37.91
按照要求node1只可以向node3發起ping、shh、web訪問請求,所以在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鏈實現了訪問控制。