iptables 防火墻(一)- 四表/五鏈、數(shù)據(jù)包匹配流程、編寫 iptables 規(guī)則

以下文章來源于杰哥的IT之旅 ,作者JackTian



1.Linux 防火墻基礎(chǔ)
Linux防火墻主要工作在網(wǎng)絡(luò)層,針對(duì) TCP/IP 數(shù)據(jù)包實(shí)施過濾和限制,典型的包過濾防火墻,基于內(nèi)核編碼實(shí)現(xiàn),具有非常穩(wěn)定的性能和高效率。

iptables:用來管理 Linux 防火墻的命令程序,位于/sbin/iptables目錄下,屬于用戶空間的防火墻管理體系。

netfilter:Linux 內(nèi)核中實(shí)現(xiàn)包過濾防火墻的內(nèi)部結(jié)構(gòu),一般不以程序或文件的形式存在,屬于內(nèi)核空間的防火墻管理體系。

iptables 的作用:為包過濾機(jī)制的實(shí)現(xiàn)提供規(guī)則,通過各種不同的規(guī)則,來告訴netfilter對(duì)來自某些源以及前往某些目的或具有某些協(xié)議特征的數(shù)據(jù)包是如何進(jìn)行處理的。

2.iptables 的表、鏈結(jié)構(gòu)
每個(gè)規(guī)則表,其實(shí)就相當(dāng)于一個(gè)內(nèi)核空間的容器,按照規(guī)則集的不同用途進(jìn)行劃分為默認(rèn)的四個(gè)表,在每個(gè)規(guī)則表中包含不同的規(guī)則鏈,處理數(shù)據(jù)包的不同時(shí)機(jī)分為五種鏈,決定是否過濾或處理數(shù)據(jù)包的各種規(guī)則并按照先后順序存放在各規(guī)則鏈中。

規(guī)則的作用:對(duì)數(shù)據(jù)包進(jìn)行過濾或處理;

鏈的作用:容納多種防火墻規(guī)則;



規(guī)則表
iptables管理著四個(gè)不同的規(guī)則表,分別由獨(dú)立的內(nèi)核模塊實(shí)現(xiàn)。

filter 表:用來對(duì)數(shù)據(jù)包進(jìn)行過濾,具體的規(guī)則要求決定如何處理一個(gè)數(shù)據(jù)包。

對(duì)應(yīng)的內(nèi)核模塊為:iptable_filter,其表內(nèi)包括三個(gè)鏈:input、forward、output;

nat 表:nat 全稱:network address translation 網(wǎng)絡(luò)地址轉(zhuǎn)換,主要用來修改數(shù)據(jù)包的 IP 地址、端口號(hào)信息。

對(duì)應(yīng)的內(nèi)核模塊為:iptable_nat,其表內(nèi)包括三個(gè)鏈:prerouting、postrouting、output;

mangle 表:主要用來修改數(shù)據(jù)包的服務(wù)類型,生存周期,為數(shù)據(jù)包設(shè)置標(biāo)記,實(shí)現(xiàn)流量整形、策略路由等。

對(duì)應(yīng)的內(nèi)核模塊為:iptable_mangle,其表內(nèi)包括五個(gè)鏈:prerouting、postrouting、input、output、forward;

raw 表:主要用來決定是否對(duì)數(shù)據(jù)包進(jìn)行狀態(tài)跟蹤。

對(duì)應(yīng)的內(nèi)核模塊為:iptable_raw,其表內(nèi)包括兩個(gè)鏈:output、prerouting;

規(guī)則鏈
input 鏈:當(dāng)收到訪問防火墻本機(jī)地址的數(shù)據(jù)包時(shí),將應(yīng)用此鏈中的規(guī)則;

output 鏈:當(dāng)防火墻本機(jī)向外發(fā)送數(shù)據(jù)包時(shí),將應(yīng)用此鏈中的規(guī)則;

forward 鏈:當(dāng)收到需要通過防火中轉(zhuǎn)發(fā)給其他地址的數(shù)據(jù)包時(shí),將應(yīng)用此鏈中的規(guī)則;

prerouting 鏈:在對(duì)數(shù)據(jù)包做路由選擇之前,將應(yīng)用此鏈中的規(guī)則;

postrouting 鏈:在對(duì)數(shù)據(jù)包做路由選擇之后,將應(yīng)用此鏈中的規(guī)則;

input 鏈 和 output 鏈主要用在主機(jī)型防火墻,是針對(duì)服務(wù)器本機(jī)進(jìn)行保護(hù)的防火墻;
forward 鏈、prerouting 鏈、postrouting 鏈主要用在網(wǎng)絡(luò)型防火墻,是針對(duì)公司內(nèi)網(wǎng)與 Internet 之間進(jìn)行安全控制。
3.數(shù)據(jù)包過濾的匹配流程


規(guī)則表之間的順序
當(dāng)數(shù)據(jù)包到達(dá)防火墻時(shí),如果對(duì)應(yīng)的鏈內(nèi)有規(guī)則存在,將按照順序依次從raw 表→mangle 表→nat 表→filter 表。

規(guī)則鏈之間的順序
入數(shù)據(jù)流向:如果是外邊的數(shù)據(jù)包到達(dá)防火墻后,要先通過postrouting 鏈:對(duì)數(shù)據(jù)包做路由選擇之后,將應(yīng)用此鏈中的規(guī)則,然后將進(jìn)行路由選擇,確認(rèn)數(shù)據(jù)包的目標(biāo)地址是否是防火墻本機(jī),結(jié)合內(nèi)核傳送給input鏈做處理,確認(rèn)通過之后,便可以交給服務(wù)器端來進(jìn)行響應(yīng)。

轉(zhuǎn)發(fā)數(shù)據(jù)流向:如果是外邊的數(shù)據(jù)包到達(dá)防火墻后,要先通過postrouting 鏈做相關(guān)處理,隨后進(jìn)行路由選擇,數(shù)據(jù)包的目標(biāo)地址是任何其他地址的話,則將通過內(nèi)核傳給forward來進(jìn)行處理是否需要通過或直接丟棄,最后將交給postrouting 鏈來查看是否有需要修改的數(shù)據(jù)包信息來進(jìn)行處理。

出數(shù)據(jù)流向:出流量,其實(shí)就是防火墻本機(jī)向外的地址發(fā)送數(shù)據(jù)包,首先被output 鏈處理,然后選擇路由,然后在postrouting 鏈查看是否修改數(shù)據(jù)包的信息來進(jìn)行處理。

規(guī)則鏈內(nèi)部各條防火墻規(guī)則之間的順序
數(shù)據(jù)包經(jīng)過每條規(guī)則鏈時(shí),將按照第一條規(guī)則、第二條規(guī)則……的順序進(jìn)行匹配和處理。

鏈內(nèi)的過濾原則
將按照從匹配到停止的方式,如找到一條匹配的規(guī)則,將不再執(zhí)行本鏈中后續(xù)的其他規(guī)則;

如果對(duì)比整個(gè)鏈也找不到與數(shù)據(jù)包相匹配的規(guī)則時(shí),將按照該規(guī)則鏈的默認(rèn)策略進(jìn)行處理;

4.編寫防火墻規(guī)則
iptables 的基本語(yǔ)法命令格式
iptables [-t 表名] 管理選項(xiàng) [鏈名] [匹配條件] [-j 控制類型]
表名、鏈名:指定iptables命令所操作的表和鏈,未指定表名時(shí)將默認(rèn)使用filter表;

管理選項(xiàng):表示iptables規(guī)則的操作方式,比如:插入、增加、刪除、查看等;

匹配條件:指定要處理的數(shù)據(jù)包的特征,不符合指定條件的數(shù)據(jù)包不在處理;

控制類型:指數(shù)據(jù)包的處理方式,比如:允許、拒絕、丟棄等;

iptables 防火墻最常用的控制類型
accept:允許數(shù)據(jù)包;

drop:丟棄數(shù)據(jù)包,且不給任何回應(yīng)信息;

reject:拒絕數(shù)據(jù)包,必要時(shí)會(huì)給數(shù)據(jù)發(fā)送端一個(gè)響應(yīng)信息;

log:在/var/log/messages文件中記錄日志信息,然后將數(shù)據(jù)包傳遞給下一個(gè)地址;

iptables 防火墻的最常用基本操作
iptables 命令的常用管理選項(xiàng)

-A:在指定鏈的末尾添加一條新的規(guī)則
-D:刪除指定鏈中的某一條規(guī)則,可刪除指定序號(hào)或具體內(nèi)容
-I:在指定鏈中插入一條新規(guī)則,未指定序號(hào)時(shí)默認(rèn)作為第一條規(guī)則
-R:修改、替換指定鏈中的某一條規(guī)則,可指定規(guī)則序號(hào)或具體內(nèi)容
-L:列出指定鏈中所有的規(guī)則,未指定鏈名,則列出表中的所有鏈
-F:清空指定鏈中所有的規(guī)則,未指定鏈名,則清空表中的所有鏈
-P:設(shè)置指定鏈的默認(rèn)策略
-n:使用數(shù)字形式顯示輸出結(jié)果
-v:查看規(guī)則列表時(shí)顯示詳細(xì)的信息
-h:查看命令幫助信息
--line-numbers:查看規(guī)則列表時(shí),同時(shí)顯示規(guī)則在鏈中的順序好
添加新的規(guī)則
添加新的防火墻規(guī)則時(shí),可使用管理選項(xiàng)-A:用來追加規(guī)則-l:用來插入規(guī)則;

在filter 表 INPUT 鏈的末尾添加一條規(guī)則,可使用-p協(xié)議名來做匹配條件;

# iptables -t filter -A INPUT -p tcp -j ACCEPT
使用管理選項(xiàng)-I,允許同時(shí)制定添加規(guī)則的順序號(hào),未指定序號(hào)時(shí)默認(rèn)作為第一條規(guī)則;

添加兩條規(guī)則分別位于filter表的第一條、第二條,將使用默認(rèn)的filter表;

# iptables -I INPUT -p udp -j ACCEPT
# iptables -I INPUT 2 -p icmp -j ACCEPT
查看規(guī)則列表
查看防火墻規(guī)則時(shí),需使用管理選項(xiàng)-L并結(jié)合--line-numbers選項(xiàng)顯示各條規(guī)則在鏈內(nèi)的順序號(hào);

查看filter 表 INPUT 鏈中的所有規(guī)則,并顯示規(guī)則序號(hào);

# iptables -L INPUT --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination         
1    ACCEPT     udp  --  anywhere             anywhere            
2    ACCEPT     icmp --  anywhere             anywhere            
3    ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
4    ACCEPT     icmp --  anywhere             anywhere            
5    ACCEPT     all  --  anywhere             anywhere            
6    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
7    REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited
8    ACCEPT     tcp  --  anywhere             anywhere            
防火墻規(guī)則多時(shí),可以以數(shù)字形式顯示地址和端口信息,減少地址解析的過程,加快命令的執(zhí)行速度。

以數(shù)字形式查看默認(rèn)表INPUT 鏈中的所有規(guī)則,可結(jié)合參數(shù)-nL或者拆分-n -L的方式來操作;

# iptables -nL INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED
ACCEPT     icmp --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22
REJECT     all  --  0.0.0.0/0            0.0.0.0/0           reject-with icmp-host-prohibited
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           
刪除、清空規(guī)則
刪除filter 表 INPUT 鏈中的第三條規(guī)則,可使用管理選項(xiàng)-D來刪除一條防火墻規(guī)則;

# iptables -D INPUT 3
# iptables -n -L INPUT
清空指定鏈或表中的所有防火墻規(guī)則,可使用管理選項(xiàng)-F;

# iptables -F INPUT
# iptables -n -L INPUT
Chain INPUT (policy ACCEPT)
target     prot opt source               destination  
省略鏈名而清空指定表所有鏈的規(guī)則,可使用管理選項(xiàng)-F;

# iptables -F
# iptables -t nat -F
# iptables -t mangle -F
設(shè)置默認(rèn)策略
默認(rèn)策略的控制類型分為:accept、drop兩種。

將filter 表中的FORWARD 鏈的默認(rèn)策略設(shè)置為:丟棄,OUTPUT 鏈的默認(rèn)策略設(shè)置為:允許;

# iptables -t filter -P FROWARD DROP
# iptables -P OUTPUT ACCEPT
5.規(guī)則的匹配條件
通用匹配:稱為常規(guī)匹配,可獨(dú)立使用,不依賴于其他條件或擴(kuò)展模塊。

協(xié)議匹配



編寫規(guī)則時(shí)使用-p 協(xié)議名的形式指定;



用來檢查數(shù)據(jù)包所使用的網(wǎng)絡(luò)協(xié)議,可用的協(xié)議類型文件位于:/etc/procotols中。



# iptables -I INPUT -p icmp -j DROP
# iptables -A FORWARD ! -p icmp -j ACCEPT


地址匹配
編寫iptables規(guī)則時(shí)使用-s 源地址或-d 目標(biāo)地址的形式指定;

用來檢查數(shù)據(jù)包的源地址或目標(biāo)地址。(IP地址、網(wǎng)段地址)

不建議使用主機(jī)名、域名地址;
比方說:若要拒絕轉(zhuǎn)發(fā)源地址為 192.168.123.123 的數(shù)據(jù),但允許轉(zhuǎn)發(fā)源地址位于 192.168.1.0/24 網(wǎng)段的數(shù)據(jù);

# iptables -A FORWARD -s 192.168.123.123 -j REJECT
# iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT
比方說:若要檢測(cè)到來自某個(gè)網(wǎng)站的頻繁掃描、登錄時(shí),可添加防火墻規(guī)則進(jìn)行封鎖;

# iptables -I INPUT -s 192.168.123.0/24 -j DROP
# iptables -I FORWARD -s 192.168.123.0/24 -j DROP
網(wǎng)絡(luò)接口匹配
編寫iptables規(guī)則時(shí)使用-i 接口名和-o 接口名的形式指定;

用來檢查數(shù)據(jù)包從防火墻的哪一個(gè)接口進(jìn)或出的,并且分別對(duì)應(yīng)入站/出站網(wǎng)卡;

比方說:若要丟棄從外網(wǎng)接口訪問防火墻本機(jī)且源地址為私有地址的數(shù)據(jù)包;

# iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP
# iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP
# iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP
隱含匹配:以指定的協(xié)議匹配作為前提條件,對(duì)應(yīng)的功能由iptables在需要時(shí)自動(dòng)隱含載入內(nèi)核。

常見的隱含匹配:端口匹配、TCP匹配、ICMP匹配;

端口匹配
編寫iptables規(guī)則時(shí)使用--sport 源端口或者--dport 目標(biāo)端口的形式指定;

針對(duì)的協(xié)議類型為:TCP、UDP

用來檢查數(shù)據(jù)包的源端口或目標(biāo)端口。

單個(gè)端口號(hào)或者以冒號(hào):分隔的端口范圍是可以接受的,但不連續(xù)的多個(gè)端口是不可以采用的。

比方說:允許為網(wǎng)段 192.168.123.0/24 轉(zhuǎn)發(fā) http 查詢數(shù)據(jù)包;

# iptables -A FORWARD -s 192.168.123.0/24 -p udp --dport 80 -j ACCEPT
# iptables -A FORWARD -d 192.168.123.0/24 -p udp --dport 80 -j ACCEPT
比方說:搭建 ftp 服務(wù)時(shí),開放 20、21 端口,以及用于被動(dòng)模式的端口范圍為 24 100~25 200;

# iptables -A INPUT -p tcp --dport 20:21 -j ACCEPT
# iptables -A INPUT -p tcp --dport 24100:25200 -j ACCEPT
ICMP 匹配
編寫iptables規(guī)則時(shí)使用--icmp-type ICMP 類型的形式指定;

針對(duì)的協(xié)議:ICMP,用來檢查 ICMP 數(shù)據(jù)包的類型。

ICMP 類型使用字符串或數(shù)字顯示

echo-request:8(ICMP 協(xié)議請(qǐng)求)

echo-reply:0(ICMP 協(xié)議回顯)

destination-unreachable:3(ICMP 協(xié)議目標(biāo)不可達(dá))

比方說:若要禁止從其他主機(jī) ping 本機(jī),但是允許本機(jī) ping 其他主機(jī)。

# iptables -A INPUT -p icmp --icmp-type 8 -j DROP
# iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
# iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
# iptables -A INPUT -p icmp -j DROP
更多可用的 ICMP 協(xié)議類型,可執(zhí)行iptables -p icmp -h進(jìn)行查看;

顯示匹配
該匹配方式需要有額外的內(nèi)核模塊提供支持,以-m 模塊名稱的形式調(diào)用相應(yīng)的模塊,然后設(shè)置匹配條件。

常見的顯示匹配:多端口匹配、IP 范圍匹配、MAC 地址匹配、狀態(tài)匹配;

多端口匹配
編寫iptables規(guī)則時(shí)使用-m multiport --dports 端口列表、-m multiport --sports 端口列表的形式指定;

用來檢查數(shù)據(jù)包的源端口、目標(biāo)端口、多個(gè)端口之間以逗號(hào)進(jìn)行分隔;

比方說:若要允許本機(jī)開放端口:80、443、110 等等,提供相關(guān)服務(wù);

# iptables -A INPUT -p tcp -m multiport --dport 80,443,110 -j ACCEPT
IP 范圍匹配
編寫iptables規(guī)則時(shí)使用-m iprange --src-range IP 范圍、-m iprange --dst-range IP 范圍的形式指定;

用來檢查數(shù)據(jù)包的源地址、目標(biāo)地址;

IP 范圍:起始地址-結(jié)束地址的形式表示;

比方說:要禁止轉(zhuǎn)發(fā)源 IP 地址位于 192.168.8.100 與 192.168.8.123 之間的 TCP 數(shù)據(jù)包;

# iptables -A FORWARD -p tcp -m iprange --src-range 192.168.8.100-192.168.8.123 -j ACCEPT
MAC 地址匹配
編寫iptables規(guī)則時(shí)使用-m mac --mac-source MAC 地址的形式指定;

用來檢查數(shù)據(jù)包的源 MAC 地址,只適用于內(nèi)部網(wǎng)絡(luò);

比方說:要根據(jù) MAC 地址封鎖主機(jī),禁止其訪問本機(jī)的任何應(yīng)用;

# iptables -A INPUT -m mac --mac-source MAC 地址 xxx -j DROP
狀態(tài)匹配
編寫iptables規(guī)則時(shí)使用-m state --state 連接狀態(tài)的形式指定;

基于iptables的狀態(tài)跟蹤機(jī)制用來檢查數(shù)據(jù)包的連接狀態(tài);

常見的連接狀態(tài)包括:new(與任何連接無關(guān))、established(響應(yīng)請(qǐng)求或已建立連接)、related(與有連接相關(guān)性的);

比方說:要禁止轉(zhuǎn)發(fā)與正常 TCP 連接無關(guān)的非 --syn 請(qǐng)求數(shù)據(jù)包;

# iptables -A FORWARD -m state --state NEW -p tcp ! --syn -j DROP
只開放本機(jī)的 WEB 服務(wù),但對(duì)發(fā)給本機(jī)的 TCP 數(shù)據(jù)包進(jìn)行放行,其他入數(shù)據(jù)包丟棄;

# iptables -I INPUT -p tcp -m multiport --dport 80 -j ACCEPT
# iptables -I INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
# iptables -P INPUT DROP



作者:JackTian

歡迎關(guān)注微信公眾號(hào) :釋然IT雜談