iptables 是 Linux 管理員用來設(shè)置 IPv4 數(shù)據(jù)包過濾條件和 NAT 的命令行工具。iptables 工具運行在用戶態(tài),主要是設(shè)置各種規(guī)則。而 netfilter 則運行在內(nèi)核態(tài),執(zhí)行那些設(shè)置好的規(guī)則。
查看 iptables 的鏈和規(guī)則
查看規(guī)則的命令格式為:
iptables [-t tables] [-L] [-nv]
-t :后面接 table ,例如 nat 或 filter ,若省略此項目,則使用默認(rèn)的 filter
-L :列出某個 table 的所有鏈或某個鏈的規(guī)則
-n :直接顯示 IP,速度會快很多
-v :列出更多的信息,包括通過該規(guī)則的數(shù)據(jù)包總位數(shù)、相關(guān)的網(wǎng)絡(luò)接口等
列出 filter table INPUT 鏈的規(guī)則:
$ sudo iptables -L INPUT
列出 nat table 三條鏈的規(guī)則:
$ sudo iptables -t nat -L -n
列出 filter table 三條鏈的規(guī)則:
$ sudo iptables -L
紅框中的內(nèi)容為鏈的名稱及其默認(rèn)策略,filter 表中所有鏈的默認(rèn)策略都是 ACCEPT。紅框下面的行代表什么呢?
target:代表進行的動作,ACCEPT 是放行,REJECT 是拒絕,DROP 則是丟棄數(shù)據(jù)包。
port:代表使用的協(xié)議,主要有 tcp、udp 和 icmp 三種。
opt:額外的選項說明。
source:規(guī)則針對的來源 IP。
destination:規(guī)則針對的目標(biāo) IP。
因為默認(rèn)情況下沒有添加自定義的規(guī)則,所以上圖中這些行下面都是空的。
清除本機防火墻規(guī)則
清除規(guī)則的命令格式如下:
iptables [-t tables] [-FXZ]
-F:清除所有已制定的規(guī)則
-X:刪除所有使用者自定義的 chain(其是 tables)
-Z:將所有的 chain 的計數(shù)與流量統(tǒng)計都清零
如果我們要制訂一套防火墻規(guī)則,一般會先清除現(xiàn)有的規(guī)則,然后從頭開始創(chuàng)建新的規(guī)則。下面讓我們清除本機 filter 表中的所有規(guī)則:
$ sudo iptables -F
$ sudo iptables -X
$ sudo iptables -Z
定義默認(rèn)策略(policy)
如果一個數(shù)據(jù)包沒有匹配到一個鏈中的任何一個規(guī)則,那么將對該數(shù)據(jù)包執(zhí)行這個鏈的默認(rèn)策略(default policy),默認(rèn)策略可以是 ACCEPT 或 DROP。
鏈中默認(rèn)策略的存在使得我們在設(shè)計防火墻時可以有兩種選擇:
設(shè)置默認(rèn)策略 DROP 所有的數(shù)據(jù)包,然后添加規(guī)則接受(ACCEPT)來自可信 IP 地址的數(shù)據(jù)包,或訪問我們的服務(wù)監(jiān)聽的端口的數(shù)據(jù)包,比如 bittorrent、FTP 服務(wù)器、Web 服務(wù)器、Samba 文件服務(wù)器等等。
設(shè)置默認(rèn)策略 ACCEPT 所有的數(shù)據(jù)包,然后添加規(guī)則丟棄(DROP)特定的數(shù)據(jù)包。比如來自一些惡意 IP 的數(shù)據(jù)包,或訪問某些端口的數(shù)據(jù)包,在這些端口上我們并沒有提供公開的服務(wù)。
一般情況下,上面的第一個選項用于 INPUT 鏈,因為我們希望對訪問的資源進行權(quán)限控制。而第二個選項常用于 OUTPUT 鏈,因為我們通常信任離開機器的數(shù)據(jù)包(該數(shù)據(jù)包來自本機)。
設(shè)置默認(rèn)策略的命令格式如下:
iptables [-t table] -P [INPUT,OUTPUT,FORWARD] [ACCEPT,DROP]
-P 選項用來定義默認(rèn)策略(Policy)。注意,這是大寫字母 P。ACCEPT 表示接受數(shù)據(jù)包,DROP 表示丟棄數(shù)據(jù)包。
一般情況下,我們會把 filter 表的 INPUT 鏈的默認(rèn)策略制訂的嚴(yán)格一些,比如設(shè)為 DROP。而 FORWARD 和 OUTPUT 可以寬松些,設(shè)為 ACCEPT。比如我們可以通過下面的命令把 filter 表的 INPUT 鏈的默認(rèn)策略設(shè)置為 DROP:
$ sudo iptables -P INPUT DROP
添加規(guī)則
我們可以通過規(guī)則來匹配數(shù)據(jù)包,具體的匹配條件包括 IP、網(wǎng)段、網(wǎng)絡(luò)接口(interface)和傳輸協(xié)議(tcp、udp 等)。
添加規(guī)則的命令格式如下:
iptables [-AI chain] [-io interface] [-p 協(xié)議] [-s 來源 IP] [-d 目標(biāo) IP] -j [ACCEPT,DROP,REJECT,LOG]
-A:針對某個規(guī)則鏈添加一條規(guī)則,新添加的規(guī)則排在現(xiàn)有規(guī)則的后面。
-I:針對某個規(guī)則鏈插入一條規(guī)則,可以為新插入的規(guī)則指定在鏈中的序號。如果不指定序號,則新的規(guī)則會變成第一條規(guī)則。
-i:指定數(shù)據(jù)包進入的那個網(wǎng)絡(luò)接口,比如 eth0、lo 等,需要與 INPUT 鏈配合使用。
-o: 指定傳出數(shù)據(jù)包的那個網(wǎng)絡(luò)接口,需要與 OUTPUT 鏈配合使用。
-p: 指定此規(guī)則適用于那種網(wǎng)絡(luò)協(xié)議(常用的協(xié)議有 tcp、udp、icmp,all 指適用于所有的協(xié)議)。
-s:指定數(shù)據(jù)包的來源 IP/網(wǎng)段,可以指定單個 IP,如 192.168.1.100,也可以指定一個網(wǎng)段,如 192.168.1.0/24。還可以通過 !表示非的意思,如 ! 192.168.1.0/24 表示除了 192.168.1.0/24 之外的數(shù)據(jù)包。
-d:指定數(shù)據(jù)包的目標(biāo) IP/網(wǎng)段,其它與 -s 選項相同。
-j:指定匹配成功后的行為,主要有 ACCEPT、DROP、REJECT 和 LOG。
下面我們來看幾個例子。
放開本機接口 lo:
$ sudo iptables -A INPUT -i lo -j ACCEPT
上面的命令假設(shè) lo 接口是可以信任的設(shè)備,所有進出該接口的數(shù)據(jù)包都會被接受。
注意,上面的命令中并沒有設(shè)置 -s、-d 等參數(shù),其實沒有指定的參數(shù)表示該參數(shù)是任何值都可以被接受。
完全放開某個接口
和 lo 接口類似,如果你完全信任某個接口,可以像設(shè)置 lo 一樣設(shè)置它:
$ sudo iptables -A INPUT -i eth1 -j ACCEPT
只接受來自內(nèi)網(wǎng)中某個網(wǎng)段的數(shù)據(jù)包:
$ sudo iptables -A INPUT -i eth2 -s 192.168.10.0/24 -j ACCEPT
接受/丟棄來自指定 IP 的數(shù)據(jù)包:
$ 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 表的規(guī)則:
$ sudo iptables -L -v
iptables-save 命令提供了另外一種風(fēng)格的輸出:
$ sudo iptables-save
在規(guī)則中使用端口號
在我們添加的規(guī)則中,很多時候需要指定網(wǎng)絡(luò)協(xié)議(tcp、udp 等)及相關(guān)的端口號,其基本命令格式如下:
iptables [-AI chain] [-io interface] [-p tcp,udp] [-s 來源 IP] [--sport 端口范圍] [-d 目標(biāo) IP] [--dport 端口范圍] -j [ACCEPT,DROP,REJECT]
--sport:限制來源的端口號,可以是單個端口,也可以是一個范圍,如 1024:1050
--dport:限制目標(biāo)的端口號。
注意,因為只有 tcp 協(xié)議和 udp 協(xié)議使用了端口號,所以在使用 --sport 和 --dport 時,一定要指定協(xié)議的類型(-p tcp 或 -p udp)。
下面來看幾個例子。
丟棄所有通過 tcp 協(xié)議訪問本機 21 端口的數(shù)據(jù)包:
$ sudo iptables -A INPUT -i eth0 -p tcp --dport 21 -j DROP
丟棄來自 192.168.1.0/24 的 1024:65535 端口的訪問本機 ssh 端口的數(shù)據(jù)包:
$ 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 管理防火墻時,必須針對數(shù)據(jù)包的進、出方向進行控制。
比如要連接到遠程主機的 22 端口時,必須設(shè)置兩條規(guī)則:
本機的 1024:65535 端口到遠程的 22 端口必須放行(OUTPUT chain);
遠程主機 22 端口到本機的 1024:65535 端口必須放行(INPUT chain);
這是很麻煩的,比如你要連接 10 臺遠程主機的 22 端口,即便你本機的 OUTPUT 設(shè)置為 ACCEPT,
你依然需要添加 10 條 INPUT ACCEPT 規(guī)則接受來自這 10 臺遠程主機的 22 端口的數(shù)據(jù)包(INPUT 的默認(rèn)策略為 DROP)。
iptables 則解決了這個問題,它會通過一個狀態(tài)模塊來分析:這個想要進入的數(shù)據(jù)包是不是對自己已發(fā)送請求的響應(yīng)?如果判斷是對自己請求的響應(yīng),就放行這個數(shù)據(jù)包。
使用狀態(tài)模塊的基本命令格式如下:
iptables -A INPUT [-m state] [--state INVALID,ESTABLISHED,NEW,RELATED]
-m:指定 iptables 的插件模塊,常見的模塊有:
state:狀態(tài)模塊
mac:處理網(wǎng)卡硬件地址(hardware address)的模塊
--state:指定數(shù)據(jù)包的狀態(tài),常見的狀態(tài)有:
INVALID:無效的數(shù)據(jù)包狀態(tài)
ESTABLISHED:已經(jīng)連接成功的數(shù)據(jù)包狀態(tài)
NEW:想要新建立連接的數(shù)據(jù)包狀態(tài)
RELATED:這個最常用,它表示該數(shù)據(jù)包與我們主機發(fā)送出去的數(shù)據(jù)包有關(guān)
下面來看幾個例子。
只要是已建立連接或相關(guān)的數(shù)據(jù)包接受:
$ sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
只要是不合法的數(shù)據(jù)包就丟棄:
$ sudo iptables -A INPUT -m state --state INVALID -j DROP
保存 iptables 的配置
注意,我們通過 iptables 命令設(shè)置的規(guī)則都保存在內(nèi)存中,也就是說系統(tǒng)重啟的話所有的配置都會丟失。
我們可以通過 iptables-save 命令把 iptables 的配置保存到文件中:
$ sudo touch /etc/iptables.conf
$ sudo chmod 666 /etc/iptables.conf
$ sudo iptables-save > /etc/iptables.conf
在需要時再通過 iptables-restore 命令把文件中的配置信息導(dǎo)入:
$ sudo iptables-restore < /etc/iptables.conf
總結(jié)
iptables 是一個比較復(fù)雜的命令,本文只是介紹了一些最基本的用法。接下來我們會介紹如何通過 iptables 構(gòu)建基本的防火墻配置以及 NAT 服務(wù)器。
參考:
netfilter/iptables doc
iptables man page
Ubuntu IptablesHowTo
Iptables Tutorial
總結(jié)
以上所述是小編給大家介紹的Linux iptables 命令,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!