Iptables 最佳實踐 !

大雄45發表於2020-11-21
導讀 考慮一種網路拓撲應用情景,一個內部區域網中有多臺伺服器提供不同的服務,如web服務、FTP服務、ssh、telnet等,透過伺服器(或閘道器、防火牆)連線外部網路,如果外部網路上的主機需要訪問這些伺服器,則需要在閘道器上實現轉發。

再轉述成另一種應用場合,多臺裝置連線到一臺伺服器,伺服器有2個網路卡,分別連線內外網。外網無法直接訪問裝置上的資料、服務。在伺服器上實現轉發後,則可達到目的。

網路拓撲如下:
Iptables 最佳實踐 !Iptables 最佳實踐 !
比如,可以透過伺服器的8081埠訪問1號裝置的web服務,8082埠訪問2號裝置web,這樣可以在外部網路對內網裝置進行引數配置、調整。類似地,透過2321訪問1號裝置的telnet服務,2322訪問2號裝置telnet,以方便登陸裝置系統,進行裝置狀態監控,日誌處理,等等。

本文將直接引用此網路拓撲圖中的名稱及IP地址。實際使用配置根據實際情況修改。另外說明一下,不必拘泥於本文給出的名稱。像拓撲圖中的“裝置”,可以使用一臺安裝 的伺服器替換。其它的類似。

一、原理

在 使用iptables實現防火牆、資料轉發等功能。iptables有不同的表(tables),每個tables有不同的鏈(chain),每條chain有一個或多個規則(rule)。本文利用NAT(network address translation,網路地址轉換)表來實現資料包的轉發。iptables 要用-t來指定表,如果沒有指明,則使用系統預設的表“filter”。所以使用NAT的時候,就要用“-t nat”選項了。
NAT表有三條預設的鏈,它們分別是PREROUTING、POSTROUTING和OUTPUT。

先給出NAT結構,如下圖:
Iptables 最佳實踐 !Iptables 最佳實踐 !
PREROUTING:在資料包傳入時,就進到PREROUTIING鏈。該鏈執行的是修改資料包內的目的IP地址,即DNAT(變更目的IP地址)。PREROUTING只能進行DNAT。因為進行了DNAT,才能在路由表中做判斷,決定送到本地或其它網口。

POSTROUTING:相對的,在POSTROUTING鏈後,就傳出資料包,該鏈是整個NAT結構的最末端。執行的是修改資料包的源IP地址,即SNAT。POSTROUTING只能進行SNAT。

OUTPUT:定義對本地產生的資料包的目的NAT規則。

每個資料包都會依次經過三個不同的機制,首先是PREROUTING(DNAT),再到路由表,最後到POSTROUTING(SNAT)。下面給出資料包流方向:
Iptables 最佳實踐 !Iptables 最佳實踐 !
文中的網路拓撲圖所示的資料包,是從eth0入,eth1出。但是,無論從eth0到eth1,還是從eth1到eth0,均遵守上述的原理。就是說,SNAT和DNAT並沒有規定只能在某一個網口(某一側)。

順便給出netfilter的完整結構圖:
Iptables 最佳實踐 !Iptables 最佳實踐 !

二、實現

出於安全考慮,Linux系統預設是禁止資料包轉發的。所謂轉發即當主機擁有多於一塊的網路卡時,其中一塊收到資料包,根據資料包的目的ip地址將包發往本機另一網路卡,該網路卡根據路由表繼續傳送資料包。這通常就是路由器所要實現的功能。

配置Linux系統的ip轉發功能,首先保證硬體連通,然後開啟系統的轉發功能

cat /proc/sys/net/ipv4/ip_forward,該檔案內容為0,表示禁止資料包轉發,1表示允許,將其修改為1。可使用命令echo "1" > /proc/sys/net/ipv4/ip_forward 修改檔案內容,重啟網路服務或主機後效果不再。若要其自動執行,可將命令echo "1" > /proc/sys/net/ipv4/ip_forward 寫入指令碼/etc/rc.d/rc.local 或者在/etc/sysconfig/network指令碼中新增 FORWARD_IPV4="YES"

但在我的系統中沒有這兩個檔案,因此可以修改/etc/sysctl.conf檔案,將net.ipv4.ip_forward=1的註釋取消即可

根據拓撲圖,一一實現不同IP、不同埠的對映,如下命令為一種示例形式:

# 第一臺裝置的telnet服務

iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2321 -j DNAT --to 100.100.100.101:23 iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.101 -p tcp --dport 23 -j SNAT --to 100.100.100.44

# 第二臺裝置的telnet服務

iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2322 -j DNAT --to 100.100.100.102:23 iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.102 -p tcp --dport 23 -j SNAT --to 100.100.100.44

# 第一臺裝置的web服務

iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 8081 -j DNAT --to 100.100.100.101:80 iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.101 -p tcp --dport 80 -j SNAT --to 100.100.100.44

# 第二臺裝置的web服務

iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 8082 -j DNAT --to 100.100.100.102:80 iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.102 -p tcp --dport 80 -j SNAT --to 100.100.100.44

以第一臺裝置轉發命令為例,用白話解釋一下。

第一條是PREROUTING鏈,只能進行DNAT,該命令對從eth0進入且目的IP為172.18.44.44(注:可以用-s指明資料包來源地址,但這時無法知道來源IP是多少,雖然可以用網段的做法,但用-d則指定必須一定唯一的是本機的eth0地址,相對好一點),埠號為2321的資料包進行目的地址更改,更改為100.100.100.101,埠為23,亦即此包的目的地為第一臺裝置的telnet服務。

第二條是POSTROUTING鏈,只能進行SNAT,即對先前已經DNAT過的資料包修改源IP地址。這樣,這個資料包達到第一臺裝置時,源IP地址、目的IP地址,均為100.100.100.0/24網段了。

上述命令的SNAT有些冗餘,可以做簡化,命令如下:
# 第一臺裝置的telnet、web服務

iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2321 -j DNAT --to 100.100.100.101:23 iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 8081 -j DNAT --to 100.100.100.101:80

# 第二臺裝置的telnet、web服務

iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2322 -j DNAT --to 100.100.100.102:23 iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 8082 -j DNAT --to 100.100.100.102:80

# 源IP地址SNAT

iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.0/24 -j SNAT --to 100.100.100.44

實際中使用的命令可能還有變化(簡化),本文不再展示。

三、測試

為了保證文中所述的正確性,本節列出操作結果,以及實驗過程的資訊。伺服器(閘道器)上的路由表如下:

root@latelee:test# route Kernel IP routing table Destination   Gateway    Genmask      Flags Metric Ref  Use Iface 100.100.100.0   *       255.255.255.0   U     0     0    0  eth1 172.18.0.0      *       255.255.0.0     U     0     0    0  eth0

可以看到伺服器上有2個網路卡,網段都不相同。iptables的NAT表如下:

root@latelee:~# iptables -L -t nat Chain PREROUTING (policy ACCEPT) target     prot opt source               destination          DNAT       tcp  --  anywhere             172.18.44.44         tcp dpt:2324 to:100.100.100.101:23 Chain INPUT (policy ACCEPT) target     prot opt source               destination          Chain OUTPUT (policy ACCEPT) target     prot opt source               destination          Chain POSTROUTING (policy ACCEPT) target     prot opt source               destination          SNAT       all  --  anywhere             100.100.100.0/24     to:100.100.100.44

可以看到,PREROUTING和POSTROUTING各有一條規則,這些規則由上文命令所產生。對應的,在第一號裝置上檢視路由資訊,如下:

root@latelee:~# route Kernel IP routing table Destination    Gateway         Genmask        Flags Metric Ref   Use Iface 100.100.100.0   *              255.255.255.0   U     0     0     0 eth0 172.18.0.0      *              255.255.0.0     U     0     0     0 eth1 default       100.100.100.44   0.0.0.0         UG    0     0     0 eth0

可以看到這臺裝置有2個網路卡,預設閘道器為伺服器的IP地址。但是,其中一個網路卡eth1竟然和PC所在網段相同!如果沒有進行源IP地址修改(偽裝),會匹配到eth1這個網口,無法匹配eth0。

在外網的PC上對裝置進行telnet,裝置抓包資訊如下:

IP 100.100.100.44.32253 > 100.100.100.101.2323: Flags [P.], seq 1:4, ack 16, win 256, length 3 IP 100.100.100.101.2323 > 100.100.100.44.32253: Flags [P.], seq 16:19, ack 4, win 2190, length 3 IP 100.100.100.44.32253 > 100.100.100.101.2323: Flags [P.], seq 4:25, ack 19, win 256, length 21 IP 100.100.100.101.2323 > 100.100.100.44.32253: Flags [P.], seq 19:34, ack 25, win 2190, length 15

可見,所有包的IP段都相同。在伺服器上對內網eth1進行抓包,由於進行了DNAT和SNAT,此網路卡資料包IP地址還是100.100.100.0/24網段,如下:

IP 100.100.100.44.32253 > 100.100.100.101.telnet: Flags [.], ack 1, win 256, length 0 IP 100.100.100.101.telnet > 100.100.100.44.32253: Flags [P.], seq 1:16, ack 1, win 2190, length 15 IP 100.100.100.44.32253 > 100.100.100.101.telnet: Flags [P.], seq 1:4, ack 16, win 256, length 3 IP 100.100.100.101.telnet > 100.100.100.44.32253: Flags [P.], seq 16:19, ack 4, win 2190, length 3

但是,在伺服器eth0抓包,將會是172.18.0.0/16的網段資料包:

IP 172.18.44.142.32253 > 172.18.44.44.2324: Flags [P.], seq 18:20, ack 154, win 255, length 2 IP 172.18.44.44.2324 > 172.18.44.142.32253: Flags [P.], seq 154:156, ack 20, win 2190, length 2 IP 172.18.44.44.2324 > 172.18.44.142.32253: Flags [F.], seq 156, ack 20, win 2190, length 0 IP 172.18.44.142.32253 > 172.18.44.44.2324: Flags [.], ack 157, win 255, length 0 IP 172.18.44.142.32253 > 172.18.44.44.2324: Flags [F.], seq 20, ack 157, win 255, length 0 IP 172.18.44.44.2324 > 172.18.44.142.32253: Flags [.], ack 21, win 2190, length 0

從抓包分析,本文所用命令已經能正確進行DNAT和SNAT了。

四、其它

建議在使用iptabls指令時,使用root使用者進行操作,否則容易失敗

儲存iptables配置方法:

iptables-save > /etc/iptables.up.rules

配置iptables開機載入

iptables-save > /etc/iptables.up.rules echo -e '#!/bin/bash\n/sbin/iptables-restore < /etc/iptables.up.rules' > /etc/network/if-pre-up.d/iptables chmod +x /etc/network/if-pre-up.d/iptables

本地測試指令

iptables -t nat -A PREROUTING -i wlan0 -d 192.168.11.100 -p tcp --dport 8081 -j DNAT --to 192.168.10.101:80 iptables -t nat -A POSTROUTING -o eth0 -d 192.168.10.101 -p tcp --dport 80 -j SNAT --to 192.168.10.52

原文來自:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2735851/,如需轉載,請註明出處,否則將追究法律責任。