iptables防火牆能夠用於建立過濾(filter)與NAT規則。全部Linux發行版都能使用iptables,所以理解如何配置 iptables將會幫助你更有效地管理Linux防火牆。若是你是第一次接觸iptables,你會以爲它很複雜,可是一旦你理解iptables的工 做原理,你會發現其實它很簡單。
圖: IPTables Table, Chain, and Rule Structure
1、iptables的表與鏈
iptables具備Filter, NAT, Mangle, Raw四種內建表:
1. Filter表
Filter表示iptables的默認表,所以若是你沒有自定義表,那麼就默認使用filter表,它具備如下三種內建鏈:
- INPUT鏈 – 處理來自外部的數據。
- OUTPUT鏈 – 處理向外發送的數據。
- FORWARD鏈 – 將數據轉發到本機的其餘網卡設備上。
2. NAT表
NAT表有三種內建鏈:
- PREROUTING鏈 – 處理剛到達本機並在路由轉發前的數據包。它會轉換數據包中的目標IP地址(destination ip address),一般用於DNAT(destination NAT)。
- POSTROUTING鏈 – 處理即將離開本機的數據包。它會轉換數據包中的源IP地址(source ip address),一般用於SNAT(source NAT)。
- OUTPUT鏈 – 處理本機產生的數據包。
3. Mangle表
Mangle表用於指定如何處理數據包。它能改變TCP頭中的QoS位。Mangle表具備5個內建鏈:
- PREROUTING
- OUTPUT
- FORWARD
- INPUT
- POSTROUTING
4. Raw表
Raw表用於處理異常,它具備2個內建鏈:
- PREROUTING chain
- OUTPUT chain
5.小結
下圖展現了iptables的三個內建表:
圖: IPTables 內建表
2、IPTABLES 規則(Rules)
牢記如下三點式理解iptables規則的關鍵:
- Rules包括一個條件和一個目標(target)
- 若是知足條件,就執行目標(target)中的規則或者特定值。
- 若是不知足條件,就判斷下一條Rules。
目標值(Target Values)
下面是你能夠在target裏指定的特殊值:
- ACCEPT – 容許防火牆接收數據包
- DROP – 防火牆丟棄包
- QUEUE – 防火牆將數據包移交到用戶空間
- RETURN – 防火牆中止執行當前鏈中的後續Rules,並返回到調用鏈(the calling chain)中。
若是你執行iptables –list你將看到防火牆上的可用規則。下例說明當前系統沒有定義防火牆,你能夠看到,它顯示了默認的filter表,以及表內默認的input鏈, forward鏈, output鏈。
# iptables -t filter –list
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination linux
Chain OUTPUT (policy ACCEPT)
target prot opt source destination bash
查看mangle表:
# iptables -t mangle –list
查看NAT表:
# iptables -t nat –list
查看RAW表:
# iptables -t raw –list
!注意:若是不指定
-t選項,就只會顯示默認的
filter表。所以,如下兩種命令形式是一個意思:
# iptables -t filter –list
(or)
# iptables –list
如下例子代表在filter表的input鏈, forward鏈, output鏈中存在規則:
# iptables –list
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 RH-Firewall-1-INPUT all — 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
num target prot opt source destination
1 RH-Firewall-1-INPUT all – 0.0.0.0/0 0.0.0.0/0 服務器
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination 網絡
Chain RH-Firewall-1-INPUT (2 references)
num target prot opt source destination
1 ACCEPT all – 0.0.0.0/0 0.0.0.0/0
2 ACCEPT icmp – 0.0.0.0/0 0.0.0.0/0 icmp type 255
3 ACCEPT esp – 0.0.0.0/0 0.0.0.0/0
4 ACCEPT ah – 0.0.0.0/0 0.0.0.0/0
5 ACCEPT udp – 0.0.0.0/0 224.0.0.251 udp dpt:5353
6 ACCEPT udp – 0.0.0.0/0 0.0.0.0/0 udp dpt:631
7 ACCEPT tcp – 0.0.0.0/0 0.0.0.0/0 tcp dpt:631
8 ACCEPT all – 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
9 ACCEPT tcp – 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
10 REJECT all – 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited ssh
以上輸出包含下列字段:
- num – 指定鏈中的規則編號
target – 前面提到的target的特殊值
prot – 協議:tcp, udp, icmp等
source – 數據包的源IP地址
destination – 數據包的目標IP地址
3、清空全部iptables規則
在配置iptables以前,你一般須要用iptables –list命令或者iptables-save命令查看有無現存規則,由於有時須要刪除現有的iptables規則:
iptables –flush
或者
iptables -F
這兩條命令是等效的。可是並不是執行後就萬事大吉了。你仍然須要檢查規則是否是真的清空了,由於有的linux發行版上這個命令不會清除NAT表中的規則,此時只能手動清除:
iptables -t NAT -F
4、永久生效
當你刪除、添加規則後,這些更改並不能永久生效,這些規則頗有可能在系統重啓後恢復原樣。爲了讓配置永久生效,根據平臺的不一樣,具體操做也不一樣。下面進行簡單介紹:
1.Ubuntu
首先,保存現有的規則:
iptables-save > /etc/iptables.rules
而後新建一個bash腳本,並保存到
/etc/network/if-pre-up.d/目錄下:
#!/bin/bash
iptables-restore < /etc/iptables.rules
這樣,每次系統重啓後iptables規則都會被自動加載。
!注意:不要嘗試在.bashrc或者.profile中執行以上命令,由於用戶一般不是root,並且這隻能在登陸時加載iptables規則。
2.CentOS, RedHat
# 保存iptables規則
service iptables save
# 重啓iptables服務
service iptables stop
service iptables start tcp
查看當前規則:
cat /etc/sysconfig/iptables
5、追加iptables規則
可使用iptables -A命令追加新規則,其中
-A表示
Append。所以,
新的規則將追加到鏈尾。
通常而言,最後一條規則用於丟棄(DROP)全部數據包。若是你已經有這樣的規則了,而且使用
-A參數添加新規則,那麼就是無用功。
1.語法
iptables -A chain firewall-rule
- -A chain – 指定要追加規則的鏈
- firewall-rule – 具體的規則參數
2.描述規則的基本參數
如下這些規則參數用於描述數據包的協議、源地址、目的地址、容許通過的網絡接口,以及如何處理這些數據包。這些描述是對規則的基本描述。
-p 協議(protocol)
- 指定規則的協議,如tcp, udp, icmp等,可使用all來指定全部協議。
- 若是不指定-p參數,則默認是all值。這並不明智,請老是明確指定協議名稱。
- 可使用協議名(如tcp),或者是協議值(好比6表明tcp)來指定協議。映射關係請查看/etc/protocols
- 還可使用–protocol參數代替-p參數
-s 源地址(source)
- 指定數據包的源地址
- 參數可使IP地址、網絡地址、主機名
- 例如:-s 192.168.1.101指定IP地址
- 例如:-s 192.168.1.10/24指定網絡地址
- 若是不指定-s參數,就表明全部地址
- 還可使用–src或者–source
-d 目的地址(destination)
- 指定目的地址
- 參數和-s相同
- 還可使用–dst或者–destination
-j 執行目標(jump to target)
- -j表明」jump to target」
- -j指定了當與規則(Rule)匹配時如何處理數據包
- 可能的值是ACCEPT, DROP, QUEUE, RETURN
- 還能夠指定其餘鏈(Chain)做爲目標
-i 輸入接口(input interface)
- -i表明輸入接口(input interface)
- -i指定了要處理來自哪一個接口的數據包
- 這些數據包即將進入INPUT, FORWARD, PREROUTE鏈
- 例如:-i eth0指定了要處理經由eth0進入的數據包
- 若是不指定-i參數,那麼將處理進入全部接口的數據包
- 若是出現! -i eth0,那麼將處理全部經由eth0之外的接口進入的數據包
- 若是出現-i eth+,那麼將處理全部經由eth開頭的接口進入的數據包
- 還可使用–in-interface參數
-o 輸出(out interface)
- -o表明」output interface」
- -o指定了數據包由哪一個接口輸出
- 這些數據包即將進入FORWARD, OUTPUT, POSTROUTING鏈
- 若是不指定-o選項,那麼系統上的全部接口均可以做爲輸出接口
- 若是出現! -o eth0,那麼將從eth0之外的接口輸出
- 若是出現-i eth+,那麼將僅從eth開頭的接口輸出
- 還可使用–out-interface參數
3.描述規則的擴展參數
對規則有了一個基本描述以後,有時候咱們還但願指定端口、TCP標誌、ICMP類型等內容。
–sport 源端口(source port)針對 -p tcp 或者 -p udp
- 缺省狀況下,將匹配全部端口
- 能夠指定端口號或者端口名稱,例如」–sport 22″與」–sport ssh」。
- /etc/services文件描述了上述映射關係。
- 從性能上講,使用端口號更好
- 使用冒號能夠匹配端口範圍,如」–sport 22:100″
- 還可使用」–source-port」
–-dport 目的端口(destination port)針對-p tcp 或者 -p udp
- 參數和–sport相似
- 還可使用」–destination-port」
-–tcp-flags TCP標誌 針對-p tcp
- 能夠指定由逗號分隔的多個參數
- 有效值能夠是:SYN, ACK, FIN, RST, URG, PSH
- 可使用ALL或者NONE
-–icmp-type ICMP類型 針對-p icmp
- –icmp-type 0 表示Echo Reply
- –icmp-type 8 表示Echo
4.追加規則的完整實例:僅容許SSH服務
本例實現的規則將僅容許SSH數據包經過本地計算機,其餘一切鏈接(包括ping)都將被拒絕。
# 1.清空全部iptables規則
iptables -F
# 2.接收目標端口爲22的數據包
iptables -A INPUT -i eth0 -p tcp –dport 22 -j ACCEPT 性能
# 3.拒絕全部其餘數據包
iptables -A INPUT -j DROP 測試
6、更改默認策略
上例的例子僅對接收的數據包過濾,而對於要發送出去的數據包卻沒有任何限制。本節主要介紹如何更改鏈策略,以改變鏈的行爲。
1. 默認鏈策略
/!\警告:請勿在遠程鏈接的服務器、虛擬機上測試!
當咱們使用-L選項驗證當前規則是發現,全部的鏈旁邊都有
policy ACCEPT標註,這代表當前鏈的默認策略爲ACCEPT:
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp – anywhere anywhere tcp dpt:ssh
DROP all – anywhere anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination spa
Chain OUTPUT (policy ACCEPT)
target prot opt source destination rest
這種狀況下,若是沒有明確添加DROP規則,那麼默認狀況下將採用ACCEPT策略進行過濾。除非:
a)爲以上三個鏈單獨添加DROP規則:
iptables -A INPUT -j DROP
iptables -A OUTPUT -j DROP
iptables -A FORWARD -j DROP
b)更改默認策略:
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
糟糕!!若是你嚴格按照上一節的例子配置了iptables,而且如今使用的是SSH進行鏈接的,那麼會話恐怕已經被迫終止了!
爲何呢?由於咱們已經把OUTPUT鏈策略更改成DROP了。此時雖然服務器能接收數據,可是沒法發送數據:
# iptables -L
Chain INPUT
(policy DROP)
target prot opt source destination
ACCEPT tcp – anywhere anywhere tcp dpt:ssh
DROP all – anywhere anywhere
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy DROP)
target prot opt source destination
7、配置應用程序規則
儘管5.4節已經介紹瞭如何初步限制除SSH之外的其餘鏈接,可是那是在鏈默認策略爲ACCEPT的狀況下實現的,而且沒有對輸出數據包進行限 制。本節在上一節基礎上,以SSH和HTTP所使用的端口爲例,教你們如何在默認鏈策略爲DROP的狀況下,進行防火牆設置。在這裏,咱們將引進一種新的 參數-m state,並檢查數據包的狀態字段。
1.SSH
# 1.容許接收遠程主機的SSH請求
iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT
# 2.容許發送本地主機的SSH響應
iptables -A OUTPUT -o eth0 -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT
- -m state: 啓用狀態匹配模塊(state matching module)
- –-state: 狀態匹配模塊的參數。當SSH客戶端第一個數據包到達服務器時,狀態字段爲NEW;創建鏈接後數據包的狀態字段都是ESTABLISHED
- –sport 22: sshd監聽22端口,同時也經過該端口和客戶端創建鏈接、傳送數據。所以對於SSH服務器而言,源端口就是22
- –dport 22: ssh客戶端程序能夠從本機的隨機端口與SSH服務器的22端口創建鏈接。所以對於SSH客戶端而言,目的端口就是22
若是服務器也須要使用SSH鏈接其餘遠程主機,則還須要增長如下配置:
# 1.送出的數據包目的端口爲22
iptables -A OUTPUT -o eth0 -p tcp –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT
# 2.接收的數據包源端口爲22
iptables -A INPUT -i eth0 -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT
2.HTTP
HTTP的配置與SSH相似:
# 1.容許接收遠程主機的HTTP請求
iptables -A INPUT -i eth0 -p tcp –dport 80 -m state –state NEW,ESTABLISHED -j ACCEPT
# 1.容許發送本地主機的HTTP響應
iptables -A OUTPUT -o eth0 -p tcp –sport 80 -m state –state ESTABLISHED -j ACCEPT
3.完整的配置
# 1.刪除現有規則
iptables -F
# 2.配置默認鏈策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# 3.容許遠程主機進行SSH鏈接
iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT
# 4.容許本地主機進行SSH鏈接
iptables -A OUTPUT -o eth0 -p tcp –dport 22 -m state –state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp –sport 22 -m state –state ESTABLISHED -j ACCEPT
# 5.容許HTTP請求
iptables -A INPUT -i eth0 -p tcp –dport 80 -m state –state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp –sport 80 -m state –state ESTABLISHED -j ACCEPT
References
[6] man 8 iptables