iptables 是 Linux 管理員用來設置 IPv4 數據包過濾條件和 NAT 的命令行工具。iptables 工具運行在用戶態,主要是設置各類規則。而 netfilter 則運行在內核態,執行那些設置好的規則。linux
查看規則的命令格式爲:
iptables [-t tables] [-L] [-nv]服務器
-t :後面接 table ,例如 nat 或 filter ,若省略此項目,則使用默認的 filter
-L :列出某個 table 的全部鏈或某個鏈的規則
-n :直接顯示 IP,速度會快不少
-v :列出更多的信息,包括經過該規則的數據包總位數、相關的網絡接口等網絡
列出 filter table INPUT 鏈的規則:ssh
$ sudo iptables -L INPUT
列出 nat table 三條鏈的規則:tcp
$ sudo iptables -t nat -L -n
列出 filter table 三條鏈的規則:工具
$ sudo iptables -L
紅框中的內容爲鏈的名稱及其默認策略,filter 表中全部鏈的默認策略都是 ACCEPT。紅框下面的行表明什麼呢?
target:表明進行的動做,ACCEPT 是放行,REJECT 是拒絕,DROP 則是丟棄數據包。
port:表明使用的協議,主要有 tcp、udp 和 icmp 三種。
opt:額外的選項說明。
source:規則針對的來源 IP。
destination:規則針對的目標 IP。
由於默認狀況下沒有添加自定義的規則,因此上圖中這些行下面都是空的。插件
清除規則的命令格式以下:
iptables [-t tables] [-FXZ]命令行
-F:清除全部已制定的規則
-X:刪除全部使用者自定義的 chain(其是 tables)
-Z:將全部的 chain 的計數與流量統計都清零設計
若是咱們要制訂一套防火牆規則,通常會先清除現有的規則,而後從頭開始建立新的規則。下面讓咱們清除本機 filter 表中的全部規則:rest
$ sudo iptables -F $ sudo iptables -X $ sudo iptables -Z
若是一個數據包沒有匹配到一個鏈中的任何一個規則,那麼將對該數據包執行這個鏈的默認策略(default policy),默認策略能夠是 ACCEPT 或 DROP。
鏈中默認策略的存在使得咱們在設計防火牆時能夠有兩種選擇:
通常狀況下,上面的第一個選項用於 INPUT 鏈,由於咱們但願對訪問的資源進行權限控制。而第二個選項經常使用於 OUTPUT 鏈,由於咱們一般信任離開機器的數據包(該數據包來自本機)。
設置默認策略的命令格式以下:
iptables [-t table] -P [INPUT,OUTPUT,FORWARD] [ACCEPT,DROP]
-P 選項用來定義默認策略(Policy)。注意,這是大寫字母 P。ACCEPT 表示接受數據包,DROP 表示丟棄數據包。
通常狀況下,咱們會把 filter 表的 INPUT 鏈的默認策略制訂的嚴格一些,好比設爲 DROP。而 FORWARD 和 OUTPUT 能夠寬鬆些,設爲 ACCEPT。好比咱們能夠經過下面的命令把 filter 表的 INPUT 鏈的默認策略設置爲 DROP:
$ sudo iptables -P INPUT DROP
咱們能夠經過規則來匹配數據包,具體的匹配條件包括 IP、網段、網絡接口(interface)和傳輸協議(tcp、udp 等)。
添加規則的命令格式以下:
iptables [-AI chain] [-io interface] [-p 協議] [-s 來源 IP] [-d 目標 IP] -j [ACCEPT,DROP,REJECT,LOG]
-A:針對某個規則鏈添加一條規則,新添加的規則排在現有規則的後面。
-I:針對某個規則鏈插入一條規則,能夠爲新插入的規則指定在鏈中的序號。若是不指定序號,則新的規則會變成第一條規則。
-i:指定數據包進入的那個網絡接口,好比 eth0、lo 等,須要與 INPUT 鏈配合使用。
-o: 指定傳出數據包的那個網絡接口,須要與 OUTPUT 鏈配合使用。
-p: 指定此規則適用於那種網絡協議(經常使用的協議有 tcp、udp、icmp,all 指適用於全部的協議)。
-s:指定數據包的來源 IP/網段,能夠指定單個 IP,如 192.168.1.100,也能夠指定一個網段,如 192.168.1.0/24。還能夠經過 !表示非的意思,如 ! 192.168.1.0/24 表示除了 192.168.1.0/24 以外的數據包。
-d:指定數據包的目標 IP/網段,其它與 -s 選項相同。
-j:指定匹配成功後的行爲,主要有 ACCEPT、DROP、REJECT 和 LOG。
下面咱們來看幾個例子。
放開本機接口 lo:
$ sudo iptables -A INPUT -i lo -j ACCEPT
上面的命令假設 lo 接口是能夠信任的設備,全部進出該接口的數據包都會被接受。
注意,上面的命令中並無設置 -s、-d 等參數,其實沒有指定的參數表示該參數是任何值均可以被接受。
徹底放開某個接口
和 lo 接口相似,若是你徹底信任某個接口,能夠像設置 lo 同樣設置它:
$ sudo iptables -A INPUT -i eth1 -j ACCEPT
只接受來自內網中某個網段的數據包:
$ sudo iptables -A INPUT -i eth2 -s 192.168.10.0/24 -j ACCEPT
接受/丟棄來自指定 IP 的數據包:
$ sudo iptables -A INPUT -i eth3 -s 192.168.100.5 -j ACCEPT $ sudo iptables -A INPUT -i eth3 -s 192.168.100.6 -j DROP
而後看看 filter 表的規則:
$ sudo iptables -L -v
iptables-save 命令提供了另一種風格的輸出:
$ sudo iptables-save
在咱們添加的規則中,不少時候須要指定網絡協議(tcp、udp 等)及相關的端口號,其基本命令格式以下:
iptables [-AI chain] [-io interface] [-p tcp,udp] [-s 來源 IP] [--sport 端口範圍] [-d 目標 IP] [--dport 端口範圍] -j [ACCEPT,DROP,REJECT]
--sport:限制來源的端口號,能夠是單個端口,也能夠是一個範圍,如 1024:1050
--dport:限制目標的端口號。
注意,由於只有 tcp 協議和 udp 協議使用了端口號,因此在使用 --sport 和 --dport 時,必定要指定協議的類型(-p tcp 或 -p udp)。
下面來看幾個例子。
丟棄全部經過 tcp 協議訪問本機 21 端口的數據包:
$ sudo iptables -A INPUT -i eth0 -p tcp --dport 21 -j DROP
丟棄來自 192.168.1.0/24 的 1024:65535 端口的訪問本機 ssh 端口的數據包:
$ sudo iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24 --sport 1024:65535 --dport ssh -j DROP
在 linux kernel 2.2 之前使用 ipchains 管理防火牆時,必須針對數據包的進、出方向進行控制。
好比要鏈接到遠程主機的 22 端口時,必須設置兩條規則:
這是很麻煩的,好比你要鏈接 10 臺遠程主機的 22 端口,即使你本機的 OUTPUT 設置爲 ACCEPT,
你依然須要添加 10 條 INPUT ACCEPT 規則接受來自這 10 臺遠程主機的 22 端口的數據包(INPUT 的默認策略爲 DROP)。
iptables 則解決了這個問題,它會經過一個狀態模塊來分析:這個想要進入的數據包是否是對本身已發送請求的響應?若是判斷是對本身請求的響應,就放行這個數據包。
使用狀態模塊的基本命令格式以下:
iptables -A INPUT [-m state] [--state INVALID,ESTABLISHED,NEW,RELATED]
-m:指定 iptables 的插件模塊,常見的模塊有:
state:狀態模塊
mac:處理網卡硬件地址(hardware address)的模塊
--state:指定數據包的狀態,常見的狀態有:
INVALID:無效的數據包狀態
ESTABLISHED:已經鏈接成功的數據包狀態
NEW:想要新創建鏈接的數據包狀態
RELATED:這個最經常使用,它表示該數據包與咱們主機發送出去的數據包有關
下面來看幾個例子。
只要是已創建鏈接或相關的數據包接受:
$ sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
只要是不合法的數據包就丟棄:
$ sudo iptables -A INPUT -m state --state INVALID -j DROP
注意,咱們經過 iptables 命令設置的規則都保存在內存中,也就是說系統重啓的話全部的配置都會丟失。
咱們能夠經過 iptables-save 命令把 iptables 的配置保存到文件中:
$ sudo touch /etc/iptables.conf $ sudo chmod 666 /etc/iptables.conf $ sudo iptables-save > /etc/iptables.conf
在須要時再經過 iptables-restore 命令把文件中的配置信息導入:
$ sudo iptables-restore < /etc/iptables.conf