前言
在前面的文章中,我們曾經簡單的介紹過Linux內核中防火牆的基本概念,以及四表五鏈的相關知識,可參看 LINUX 防火牆介紹。 並且也介紹瞭如何在Linux環境中搭建一個能夠過濾協議和端口的簡單網絡防火牆,可以參看Linux實現網絡防火牆(一)。
在實際生產應用中,防火牆的功能紛繁複雜,就像我們之前介紹的四表五鏈,以及數據包的流向,在實際應用中都是有着關鍵性的作用的。今天要介紹的SNAT和DNAT就是構建防火牆規則中幾個個重要應用。其中DNAT在LVS集羣應用中也有着很重要的作用,這一點我們以後再說。
什麼是SNAT和DNAT呢
NAT(Network Address Translation),又稱作網絡地址轉換,顧名思義,就是在網絡數據的傳輸過程中,對網絡地址進行轉換以達到網絡數據傳輸的目的。相關詳細的解釋可以參考(網絡地址轉換–維基百科)。
SNAT(源地址轉換)和DNAT(目標地址轉換) 是在防火牆中,對NAT的兩種應用方式。前面我們介紹過,防火牆中有四個表,一種一個表就是nat表,這個nat表就是用來對包地址進行管理的。
SNAT
SNAT 只的是在網絡傳輸過程中,將源地址進行轉換。我們都知道,在訪問互聯網的過程中,網絡是以數據包的形式進行傳輸的,而數據包中包含了目標地址和源地址,這樣,就能夠保證我們請求的服務器在處理數據之後,數據還能夠返回。SNAT就是將數據包中源目標地址進行了轉換。
IPV4地址數量,有限,但是全球各地卻有着大量的計算機能夠進入到互聯網訪問資源,這裏使用的就是SNAT地址轉換。
在一個公司內部搭建了局域網,局域網內的用戶想要訪問互聯網就需要使用SNAT技術進行地址轉換,同時由於源地址發生了變化,也相對的提升了局域網內主機的安全。
SNAT 的網絡拓撲結構如下所示。備註,圖中所注的IP地址爲筆者實驗環境的IP地址,只爲增加理解,順便進行下面的實驗,實際生產中,IP地址應該會有所不同。
環境說明
擔任角色 | 系統環境 | 主機名 | 地址 | 功能描述 |
---|---|---|---|---|
WEB服務器 | CentOS 7 | web | 172.18.3.77 | 提供web服務 |
Linux防火牆 | CentOS 7 | iptables | 172.18.2.77 192.168.2.77 | 定義防火牆規則 |
局域網用戶 | CentOS 6 | lan | 192.168.2.66 | 訪問互聯網 |
只有在局域網內的主機請求互聯網上的服務時,纔會發生源地址轉換,結合下面的數據流轉過程就會很容易理解。
DNAT
如果我們在局域網內部署了一套WEB服務,但是我們想在互聯網上進行訪問,這時應該如何解決。對於公司來說,可能只有一個ipv4地址鏈接了互聯網。
這時就需要使用到DNAT,也就是目標地址轉換。從下面的網絡拓撲圖中我們可以看到,互聯網上的主機想要訪問局域網內部的網絡服務,具有外部網絡地址的防火牆或者路由來進行。
擔任角色 | 系統環境 | 主機名 | 地址 | 功能描述 |
---|---|---|---|---|
互聯網用戶 | CentOS 7 | web | 172.18.3.77 | 訪問局域網內web服務 |
Linux防火牆 | CentOS 7 | iptables | 172.18.2.77 192.168.2.77 | 定義防火牆規則 |
局域網WEB服務 | CentOS 6 | lan | 192.168.2.66 | 提供web服務 |
如何在防火牆上定義NAT規則?
上面介紹了許多關於SNAT和DNAT的相關概念,那麼在防火牆中應該如何定義NAT規則呢?
在之前的文章中,我們知道NAT表能夠影響的由四個鏈,分別是PREROUTING鏈,INPUT鏈,OUTPUT鏈,POSTROUTING鏈,根據前面的圖示以及我們的分析,可以總結出,SANT的防火牆過濾規則應該定義在POSTROUTING鏈上,而DNAT防火牆的過濾轉發規則應該定義在PREROUTING鏈上,這樣就能夠將網絡請求進行轉發了。
實驗實現SNAT
實驗環境
清除防火牆的過濾規則,關閉SELinux
開啓防火牆的路由轉發功能,確保局域網內用戶能夠ping通互聯網服務。
進行網絡測試
# 清除防火牆過濾規則 [root@iptables ~]#iptables -F # 開啓轉發功能 [root@iptables ~]#echo 1 > /proc/sys/net/ipv4/ip_forward # 局域網內用戶可以ping通互聯網 [root@lan ~]$ping 172.18.3.77 PING 172.18.3.77 (172.18.3.77) 56(84) bytes of data. 64 bytes from 172.18.3.77: icmp_seq=1 ttl=63 time=1.00 ms 64 bytes from 172.18.3.77: icmp_seq=2 ttl=63 time=1.52 ms # 局域網內用戶可以訪問互聯網 [root@lan ~]$curl http://172.18.3.77 www.google.com
實驗過程
首先對192.168.2網段的請求進行SNAT地址轉換,轉換後的源地址變爲172.18.2.77
[root@iptables ~]#iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -j SNAT --to-source 172.18.2.77 # 查看一下nat表的防火牆規則 [root@iptables ~]#iptables -vnL -t nat Chain PREROUTING (policy ACCEPT 1 packets, 229 bytes) pkts bytes target prot opt in out source destination Chain INPUT (policy ACCEPT 1 packets, 229 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 SNAT all -- * * 192.168.2.0/24 0.0.0.0/0 to:172.18.2.77
從局域網內部訪問互聯網的服務,還是可以正常訪問
[root@lan ~]$curl http://172.18.3.77 www.google.com
在互聯網的那臺主機上查看一下最近的訪問記錄,可以看到最近的一條訪問信息是由172.18.2.77訪問而來的,這說明,發生了網絡地址轉換。
[root@web ~]#tail -1 /var/log/httpd/access_log 172.18.2.77 - - [23/Oct/2017:15:46:35 +0800] "GET / HTTP/1.1" 200 15 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.21 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
總結一下SNAT的命令格式
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j SNAT --to-source ExtIP
實驗實現DNAT
實驗環境
清除SNAT實驗裏設置的各種過濾規則。
互聯網的主機,能夠訪問防火牆主機,但是不能夠訪問局域網內的網絡服務,通過防火牆的外網IP也不能夠訪問。
# 直接訪問內網服務不可行 [root@web ~]#curl http://192.168.2.66 curl: (7) Failed to connect to 192.168.2.66: Network is unreachable # 通過防火牆的外網IP訪問也不行 [root@web ~]#curl http://172.18.2.77 curl: (7) Failed connect to 172.18.2.77:80; Connection refused # 可以訪問到防火牆的地址 [root@web ~]#ping 172.18.2.77 PING 172.18.2.77 (172.18.2.77) 56(84) bytes of data. 64 bytes from 172.18.2.77: icmp_seq=1 ttl=64 time=0.857 ms 64 bytes from 172.18.2.77: icmp_seq=2 ttl=64 time=0.642 ms
實驗過程
根據之前,我們的討論,我們應該在nat表的PREROUTING鏈上添加策略,將訪問公網地址(172.18.2.77)的請求轉發到內網地址(192.168.2.66)。
[root@iptables ~]#iptables -t nat -A PREROUTING -d 172.18.2.77 -p tcp --dport 80 -j DNAT --to-destination 192.168.2.66:80 # 查看一下建立好的規則 [root@iptables ~]#iptables -vnL -t natChain PREROUTING (policy ACCEPT 7 packets, 1351 bytes) pkts bytes target prot opt in out source destination 0 0 DNAT tcp -- * * 0.0.0.0/0 172.18.2.77 tcp dpt:80 to:192.168.2.66:80 Chain INPUT (policy ACCEPT 7 packets, 1351 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination
此時,再從互聯網主機通過外網IP訪問局域網內服務的話,就能夠看到不一樣的結果。
[root@web ~]#curl http://172.18.2.77 LAN SERVER
查看局域網內的web服務器的訪問日誌,就可以看到有一條由外網主機訪問到的記錄。
[root@lan ~]$tail -1 /var/log/httpd/access_log 172.18.3.77 - - [25/Sep/2017:07:34:18 +0800] "GET / HTTP/1.1" 200 11 "-" "curl/7.29.0"
至此DNAT的防火牆策略就已經配置完成了。
總結一下DNAT的命令格式
iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --to-destination InterSeverIP[:PORT]
經過上面的配置和學習,我們搭建了簡單的網絡防火牆。實際生產中可以根據自己的實際情況進行更加詳細的設置。
資料參考
本文部分思路和圖示參考自以下博客,在此致敬。
個人博客地址:http://www.pojun.tech/ 歡迎訪問