1. 程式人生 > 實用技巧 >防火牆原理詳解之iptables的使用

防火牆原理詳解之iptables的使用

防火牆簡介

防火牆可以分為硬體防火牆和軟體防火牆,硬體防火牆是由廠商設計好的,這種型別的防火牆的作業系統的主要功能就是實現資料包的過濾,由於它將這種功能軟體整合在ASIC晶片裡,因此,這種防火牆的過濾效果要比軟體防火牆的好。不管是哪種型別的防火牆,他們的"防火"原理都是一樣的。根據資料包的包頭資訊與核心中的定義好的規則進行比對,如果包頭資訊和規則匹配,則執行相應的動作。否則,繼續比對下一條規則;如果包頭資訊與任何一條規則都不匹配,則執行預設策略(或者叫做預設規則也行)。


iptables和netfilter的聯絡?

很多人一提到防火牆立馬就想到了是iptables,其實iptables並不是防火牆,他只是一個軟體或者說是一個工具,這個軟體可以編寫某些規則,將寫好的規則儲存到netfilter的規則資料庫中。因此,真正起到"防火"的功能是netfilter,並不是iptables。netfilter是核心中的一個框架,這個框架裡面包含了4個表和5個鏈,這些鏈又包含了很多的規則。而資料包要比對的規則就是這個鏈中所定義的規則。

因此,可以用一句話來概括iptables和netfilter的關係:

iptables將寫好的規則儲存在netfilter的某些表的某些鏈中,進而才起到防火牆的功能


在netfilter中,真正起到防火牆功能的就是裡面的4個表和5個鏈(chain),每一個鏈作用在不通的地方,這些鏈的作用分別如下:

PREROUTING:可見理解成路由前,因此這個鏈作用在路由決策前,一般用在目標地址轉換上。

INPUT:這個鏈用於過濾或允許外地主機訪問到本地linux主機資源

OUTPUT:這個鏈用於過濾或允許本地linux主機訪問外地主機資源

FORWORD:這個鏈主要用於轉發資料報文,因此本地路由功能必須開啟。在linux系統內,路由功能是相對於主機而言的,並不是根據網絡卡來決定的。因此某個主機上面的任意兩個網絡卡之間的通訊都不需要開啟路由功能。

POSTROUTING:可以理解成路由後,因此這個鏈作用在路由決策後,一般用在源地址轉換上。


在netfilter中有4個表,每一個表又包含著相應的鏈(chain),這些表和這些鏈的對於關係如下:

這裡的4個表分別是:

filter:這個表主要用來過濾資料報文的和轉發資料報文的。因此,這個表包含著3個鏈(chain),分別是INPUT、OUTPUT、FORWORD

nat:這個表主要用來做地址轉換的。因此,這個表主要包含著3個鏈,分別是PREROUTING、POSTROUTING、OUTPUT

mangle:這個表主要是用來對特定的資料包進行修改的。這個表包含著5個鏈,分別是PREROUTING、INPUT、OUTPUT、POSTROUTING。雖然這個表包含的鏈比較多,但是基本上我們用不到。

raw:這個表的作用是為了不讓iptables做資料包的連結跟蹤,提高效能。這個表包含著2個鏈,分別是PREROUTING、OUTPUT。這個表也用的不多。


在這些表當中,raw表的優先順序最高,其次是mangle表,接著是nat表,最後才是filter表

因此,他們的優先順序順序應該是這樣的:

raw---->mangle--->nat--->filter

因此,當一個數據包進入到防火牆時,它會依次根據這些表中的相關鏈中的規則對資料包進行匹配,允許則通過,拒絕則丟棄。反之,出防火牆時,也是根據這個順序進行規則匹配的,允許則通過,拒絕則丟棄。


iptables的語法格式及其語法如下:

iptables [-t TABLE] COMMAND CHAIN [CHAIN_NUMBER] 匹配標準 -j 執行動作


其中-t TABLE指定要編輯的表名,如果此處不寫,預設表為filter表


COMMAND表示要執行的命令,這些命令包括這幾大類:

管理規則類命令:

-A:表示附加一條規則,新增在鏈的尾部

-I:表示插入一天規則,預設插在鏈的首部

-D:表示要刪除指定鏈中的某條規則

-R:修改某條鏈的某個規則


管理鏈類命令

-F [CHAIN]:flush,表示清空指定鏈的所有規則,如果省略CHAIN,則表示清空指定表中的所有規則(除預設規則之外),預設清空的是filter表

-P:修改指定鏈的預設規則(或者叫預設策略)

-N:自定義一個新的空鏈

-X:刪除一個自定義的空鏈

-E:重新命名自定義的鏈

-Z:將指定鏈中所有規則的計數器置零


檢視規則類命令

-L:顯示指定表中的所有規則,不加表名則顯示所有表中的所有規則,-L還有子選項:

-n:以數字格式顯示主機地址和埠號

-v:顯示鏈及其規則的詳細資訊

-vv:顯示鏈及其規則的更佳的詳細資訊(不是-w哦,是兩個v)

-x:顯示規則中的計數器的精確值

--line-numbers:顯示規則號碼


CHAIN:指定鏈名

CHAIN_NUMBER:表示指定鏈的第幾條規則


匹配條件有通用匹配條件和擴充套件匹配條件,其中擴充套件匹配包含隱式擴充套件匹配和顯式擴充套件匹配。

隱含擴充套件:不用特別指明由哪個模組進行的擴充套件,因為此時使用-p {tcp|udp|icmp}即可

顯式擴充套件:必須指明由哪個模組進行的擴充套件,在iptables中使用-m選項可完成此功能

通用匹配條件有:

-s SIP:根據源ip進行匹配

-d DIP:根據目標ip進行匹配

-p {tcp|udp|icmp}:根據指定協議來進行匹配

-i interface:根據資料包入向介面來進行匹配,可用於定義標準的鏈有:PREROUTING,INPUT,FORWARD

-o interface:根據資料包出介面進行匹配,可用於標準定義的鏈:OUTPUT,POSTROUTING,FORWARD


擴充套件匹配條件:

隱式擴充套件匹配條件:

(1)、tcp協議隱式擴充套件

-p tcp --sport PORT[-PORT]:對tcp的源埠做匹配。

-ptcp --dport PORT[-PORT]:對tcp的目標埠做匹配。多個連續的埠可以使用PORT-PORT的形式給出。

-p tcp --tcp-flags mask comp:只檢查mask指定的標誌位,是逗號分隔的標誌位列表;comp:此列表中出現的標記位必須為1,comp中沒出現,而mask中出現的,必須為0;

例如:只檢查tcp三次握手中的第一次:

-p tcp --tcp-flags SYN,ACK,FIN,RST SYN

-p tcp --syn:只檢查tcp三次握手中的第一次,和上面的作用一樣

(2)、icmp隱式擴充套件

-p icmp --icmp-type {0|8}:根據icmp的報文型別進行匹配。其中0表示響應報文型別,8表示請求報文型別

(3)、udp隱式擴充套件

-p udp --sport PORT[-PORT]:根據udp源埠進行匹配

-p udp --dport PORT[-PORT]:根據目標埠進行匹配


顯式擴充套件匹配:必須加上選項-m

state:狀態擴充套件:是結合ip_conntrack這個模組來追蹤會話的

-m state--state NEW:根據新請求(第一次請求)進行匹配

-m state --state ESTABLISHED:根據已建立的連線進行匹配

-m state --state RELATED:根據相關聯的連線進行匹配,多用於開放ftp服務

-m state --state INVALID:根據非法連線進行匹配

使用狀態擴充套件還要裝載ip_conntrack_ftp和ip_nat_ftp模組

在iptables中,可以利用ip_conntrack這個模組來追蹤客戶端和伺服器端的連線狀態(包括tcp、udp、icmp連線),它是核心中的一個模組,實時記錄了客戶端和伺服器端的連線狀態,並記錄每一個連線處於哪種狀態。

在/proc/net/ip_conntrack這個檔案中儲存了客戶端和服務端之間的tcp連線資訊

在/proc/sys/net/ipv4/ip_conntrack_max這個檔案中儲存了客戶端和伺服器的最大連線數,預設為65535

在/proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established檔案裡定義了tcp連線的超時時間,預設為5天(432000秒).如果在這個時間內還沒有資料傳輸,則會斷開該連線。並且也會將這個連線的資訊刪除。

對於高併發的伺服器而言,儘量不要啟用ip_conntrack這個模組。避免後續的大量請求被丟棄

對於服務請求不是很多的伺服器而言,可以啟用ip_conntrack這個模組

注意:使用iptables -t nat -L命令時會啟動ip_nat這個模組,而這個模組會依賴於ip_conntrack這個模組。因此,執行該命令,也會啟用ip_conntrack這個模組

可以使用iptstate命令來檢視客戶端和伺服器端的連線狀態資訊

iptstate -t:還可以顯示所有的連線個數


multiport:離散的多埠匹配擴充套件

-m multiport --source-ports PORT1,PORT2...:對源埠進行匹配

-m multiport --destination-ports PORT1,PORT2...:對目標埠進行匹配

-m multiport --ports PORT1,PORT2...:對指定埠進行匹配


iprange:連續的ip地址或地址範圍擴充套件

-m iprange --src-range {IP-IP|NETWORK/MASK}:對指定返回內的源地址匹配

-m iprange --dst-range {IP-IP|NETWORK/MASK}:對指定範圍內的目的地址進行匹陪

這裡的ip範圍可以是連續的ip,例如-m iprange 192.168.1.10-192.168.1.100

也可以是某一個網段內,例如-m iprange 192.168.1.0/24


connlimit:限制每一個客戶端連線數擴充套件

-m connlimit ! --connlimit-above num ACCEPT:允許每個客戶端的最大連線數

在這裡不加!,則後面的動作為DROP或REJECT

!表示取反的意思。在前面的選項當中也可以使用


limit:資料包速率限制擴充套件

-m limit --limit RATE:表示達到最大值時,單位時間內允許通過的請求數

---limit-burst:表示初始時的最大併發數為多少(即請求剛開始時能夠匹配的最大資料包)


string:字串匹配擴充套件

-m string --algo {bm|kmp} :指定匹配演算法

--string ”STRING” :對指定的字串進行匹配


-j 執行動作有:

ACCEPT:表示接受或放行

DROP:表示丟棄

REJECT:表示拒絕

DNAT:表示做目標地址轉換

SNAT:表示做源地址轉換

REDIRECT:表示埠重定向

RETURN:如果應用在主鏈上,則表示執行相應的策略。如果應用於自定義鏈上,則表示將匹配權返回給主鏈。

MASQUERADE:如果上網ip不固定,可以使用該引數。系統會自動將私有源ip轉換成可以上網的公網ip。用傳送資料的網絡卡上的IP來替換源IP,因此,對於那些IP不固定的場合,比如撥號網路或者通過dhcp分配IP的情況下,就得用MASQUERADE。一般由於源地址轉換中。

LOG:表示將資料包相關資訊記錄下來。不影響報文的比對規則

其中子選項--log-prefix "STRING"表示定義日誌字首。用於方便檢視是哪種型別的日誌。

MASK:表示對報文打標記


iptables的規則儲存

預設情況下,當系統重啟後,之前寫的規則如果沒有儲存的話,這些規則就會丟失。使用service iptables save可以將規則儲存起來。且這些規則預設儲存在/etc/sysconfig/iptables裡。

自定義規則儲存檔案

預設iptables將寫好的規則儲存在/etc/sysconfig/iptables這個檔案裡,使用iptables-save > /etc/sysconfig/iptables.20141031可以將規則儲存至自己定義的檔案裡。這裡的檔案自行定義。

系統重啟後,自定義的規則儲存檔案需要手動載入到記憶體中才會生效。使用命令iptables-restore < /etc/sysconfig/iptables.20141031即可完成此功能。


利用iptables的recent模組來抵禦DOS***

在這裡以ssh服務來說明

步驟如下:

1.利用connlimit模組將單IP的併發設定為3;會誤殺使用NAT上網的使用者,可以根據實際情況增大該值;


2.利用recent和state模組限制單IP在300s內只能與本機建立3個新連線。被限制五分鐘後即可恢復訪問。

iptables規則如下:

iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP

下面對最後兩句做一個說明:

1.第二句是記錄訪問tcp 22埠的新連線,記錄名稱為SSH
--set 記錄資料包的來源IP,如果IP已經存在將更新已經存在的條目

2.第三句是指SSH記錄中的IP,300s內發起達到3次連線則拒絕此IP的連線。
--update 是指每次建立連線都更新列表;
--seconds必須與--rcheck或者--update同時使用
--hitcount必須與--rcheck或者--update同時使用

3.iptables的記錄:儲存在/proc/net/ipt_recent/SSH這個檔案中


NAT:Network Address Transfer

NAT叫做網路地址轉換,NAT分為源地址轉換SNAT和目標地址轉換DNAT

SNAT:源地址轉換,由於某一個區域網內使用的基本都是私有ip地址,而私有ip地址是不能在公網上路由的。因此,當私有ip向外傳送請求時,會先將請求時的源ip轉換成能夠路由的公網ip,並最終與網際網路上的服務進行通訊。不過,當網際網路的服務對本地請求進行響應時,則會自動進行DNAT。SNAT一般用在nat表的POSTROUTING上。

做SNAT需要執行的地址為-j SNAT --to-source SIP

SNAT工作流程如下:

wKioL1RTTleDwMajAAF3rzd01lg194.jpg


DNAT:目標地址轉換,當公網上的某個客戶訪問某個企業的伺服器時,它首先會與該企業的nat伺服器(或邊緣路由器)進行通訊。然後根據寫好的規則,將該請求的目的ip轉換成私有ip地址,在經過路由功能就可以實現和企業伺服器進行通訊(一般為私有ip地址)。不過,當本地伺服器響應服務請求時(一來一回)會自動完成源地址轉換。DNAT一般用在nat表的PREROUTING鏈上。

做SNAT需要執行的地址為-j DNAT --to-destination DIP

DNAT工作流程如下:

wKioL1RTTnzSSPlLAAE4EfH1djE669.jpg


自定義規則鏈

步驟如下:

1、建立一條空鏈

# iptables -N clean_in

2、在該鏈上建立相關規則

# iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP
# iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP

# iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP
# iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP
# iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP

3、將匹配權返回交給主鏈處理。如果目標地址為172.16.100.7報文一條規則都沒匹配,則將由主鏈中的規則來繼續匹配。

# iptables -A clean_in -d 172.16.100.7 -j RETURN

4、主鏈呼叫自定義規則鏈。目標地址為172.16.100.7的報文將與自定義規則鏈中的規則進行匹配。
# iptables -A INPUT -d 172.16.100.7 -j clean_in

自定義規則鏈和主鏈中的規則都是按順序來匹配的,它們之間沒有優先順序,誰在前就最先使用第一條規則進行匹配。

主鏈是netfilter中的5個鏈

說明一下:當某個報文被自定義規則鏈上的規則匹配時,則執行相應的動作;如果報文沒被自定義規則鏈中的任何一條規則匹配,則將返回主鏈,繼續與主鏈上的其他規則進行匹配。



轉載於:https://blog.51cto.com/xslwahaha/1569472