一、概念
iptables只是Linux防火墻的管理工具而已。真正實現防火墻功能的是netfilter,它是Linux內核中實現包過濾的內部結構。
1. 鏈
鏈是一些按順序排列的規則的列表。
默認情況下,任何鏈中都沒有規則。可以向鏈中添加自己想用的規則。鏈的默認規則通常設置為 ACCEPT,如果想確保任何包都不能通過規則集,那么可以重置為 DROP。
默認的規則總是在一條鏈的最后生效,所以在默認規則生效前數據包需要通過所有存在的規則。
- 5種鏈說明如下:
PREROUTING鏈——對數據包作路由選擇前應用此鏈中的規則(所有的數據包進來的時侯都先由這個鏈處理)
INPUT鏈——進來的數據包應用此規則鏈中的策略
OUTPUT鏈——外出的數據包應用此規則鏈中的策略
FORWARD鏈——轉發數據包時應用此規則鏈中的策略
POSTROUTING鏈——對數據包作路由選擇后應用此鏈中的規則(所有的數據包出來的時侯都先由這個鏈處理)
2. 表
表由一組預先定義的鏈組成。
filter表——用于存放所有與防火墻相關操作的默認表。通常用于過濾數據包。
nat表——用于網絡地址轉換
mangle表——用于處理數據包
raw表——用于配置數據包,raw 中的數據包不會被系統跟蹤。
3. 鏈和表的關系及順序
PREROUTING: raw -> mangle -> nat
INPUT: mangle -> filter
FORWARD: mangle -> filter
OUTPUT: raw -> mangle -> nat -> filter
POSTROUTING: mangle -> nat
4. 實際使用中是從表作為操作入口;表和鏈的關系
raw 表:PREROUTING,OUTPUT
mangle表:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
nat 表:PREROUTING,OUTPUT,POSTROUTING
filter 表:INPUT,FORWARD,OUTPUT
5. target
ACCEPT: 允許數據包通過
DROP:直接丟棄數據包,不給任何回應信息
REJECT:拒絕數據包通過,需要時會給數據發送端一個相應信息
SNAT:原地址轉換,解決內網用戶用同一個公網地址上網的問題
MASQUERADE:是 SNAT 的一種特殊形式,適用于動態的、臨時會變的 ip 上
DNAT:目標地址轉換
REDIRECT:在本機做端口映射
LOG:在/var/log/messages 文件中記錄日志信息。然后將數據包傳遞給下一條規則。也就是只記錄不做任何操作。
- REJECT 其他參數
--reject-with
:可以設置提示信息,拒絕時的提示信息
icmp-net-unreachable
icmp-host-unreachable
icmp-port-unreachable,
icmp-proto-unreachable
icmp-net-prohibited
icmp-host-pro-hibited
icmp-admin-prohibited
當不設置任何值時,默認值為icmp-port-unreachable。
用法:
# iptables -t filter -I INPUT 2 -j REJECT --reject-with icmp-host-unreachable
- LOG
只記錄匹配到的報文信息。
在配置文件 /etc/rsyslog.conf 中加入下面一行。重啟服務即可。
kern.warning /var/log/iptables.log
# service rsyslog restart
- LOG 參數
--log-level
選項可以指定記錄日志的日志級別,可用級別有emerg,alert,crit,error,warning,notice,info,debug。
--log-prefix
選項可以給記錄到的相關信息添加"標簽"之類的信息,以便區分各種記錄到的報文信息,方便在分析時進行過濾。
示例:
比如,我想要將主動連接22號端口的報文的相關信息都記錄到日志中,并且把這類記錄命名為"want-in-from-port-22",則可以使用如下命令
# iptables -t filter -I INPUT -p tcp -m state --state NEW -j LOG --log-prefix "want-in-from-port-22"
- SNAT
配置SNAT,可以隱藏網內主機的IP地址,也可以共享公網IP,如果只是共享IP的話,只配置如下SNAT規則即可。
示例:
# iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -j SNAT --to-source 123.43.11.2
如果公網IP是動態獲取的,不是固定的,則可以使用MASQUERADE進行動態的SNAT操作。
# iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERADE
6. 數據通過防火墻流程
二、表相關操作
1. 表查看
查看表中規則 iptables -t table_name -L [chain_name]
示例:
root@kvm:~# iptables -t filter -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
上面示例可以看到有哪些鏈是支持過濾的
在不指定表時默認查詢 filter 表 iptables -L [chain_name]
(注意大小寫)
示例:
root@kvm:~# iptables -L INPUT
Chain INPUT (policy ACCEPT)
target prot opt source destination
2. 其他參數說明
參數 | 說明 | 示例 |
---|---|---|
-L |
列出規則 | 如下 |
--table -t
|
要操作哪個表(不寫-t, 默認表:filter) | iptables -t raw -L |
--verbose -v
|
查看鏈詳細信息;詳細信息中字段對應的意思:pkts : 對應規則匹配到的報文個數;bytes : 對應匹配到的報文包的大小總和;target :規則對應的target,表示規則對應的『動作』,即規則匹配成功后要采取的措施;prot :表示規則對應的協議,是否針對某些協議應用此規則;opt :表示規則對應的選項;in :表示數據包由哪個接口(網卡)流入,可以設置通過哪塊網卡流入的報文需要匹配當前規則;out :表示數據包由哪個接口(網卡)流出,可以設置通過哪塊網卡流出的報文需要匹配當前規則;source :表示規則對應的源頭地址,可以是一個 IP,也可以是一個網段;destination :表示規則對應的目標地址。可以是一個 IP,也可以是一個網段;第一行信息意思: policy : 表示當前默認策略,如:polict ACCEPT ;類似黑白名單的東西,默認是所有都可以通過;packets :表示當前鏈默認策略匹配到的包的數量,0 packets 表示默認策略匹配了0個;bytes :表示當前鏈默認策略匹配到的所有包的大小總和; |
iptables -vL INPUT |
--exact -x
|
顯示上面packets 和bytes 的詳細大小 |
iptables -nvxL |
--numeric -n
|
不對 IP 地址進行名稱反解析,直接顯示 IP | iptables -nvL |
--line-numbers --line
|
查看的數據前面加上序號 | iptables --line-numbers -vL INPUT |
3. 表的增刪改查
* 在表的開頭添加規則 iptables -t table_name -I chain_name -s address/mask -j target
示例:
root@kvm:~# iptables -t filter -I INPUT -s 192.168.55.132 -j DROP
root@kvm:~# iptables -nvL INPUT
Chain INPUT (policy ACCEPT 34 packets, 2706 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 192.168.55.132 0.0.0.0/0
* 在表的尾部追加一條數據 iptables -f table_name -A chain_name -s address/mask -j target
root@kvm:~# iptables -A INPUT -s 192.168.55.132 -j ACCEPT
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 52 packets, 3722 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 192.168.55.132 0.0.0.0/0
0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
這個時候在192.168.55.132這個主機上 ping 測試機是不通的。此時在表的首部在添加一個允許的操作
root@kvm:~# iptables -t filter -I INPUT -s 192.168.55.132 -j ACCEPT
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 17 packets, 1738 bytes)
pkts bytes target prot opt in out source destination
2 168 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
11 924 DROP all -- * * 192.168.55.132 0.0.0.0/0
0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
這個時候在192.168.55.132這個主機上 ping 測試機發現可以 ping 通
所以規則的順序很重要
* 在指定位置插入規則 iptables -t table_name -I chain place_num -s address/mask -j target
示例:
root@kvm:~# iptables --line -vnL INPUT
Chain INPUT (policy ACCEPT 65 packets, 5684 bytes)
num pkts bytes target prot opt in out source destination
1 2 168 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
2 11 924 DROP all -- * * 192.168.55.132 0.0.0.0/0
3 0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
root@kvm:~# iptables -t filter -I INPUT 2 -s 10.0.0.1 -j ACCEPT
root@kvm:~# iptables --line -vnL INPUT
Chain INPUT (policy ACCEPT 7 packets, 488 bytes)
num pkts bytes target prot opt in out source destination
1 2 168 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
2 0 0 ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
3 11 924 DROP all -- * * 192.168.55.132 0.0.0.0/0
4 0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
* 刪除規則 iptables -t table_name -D chain_name line_number/rule
- 根據參數
--line-numbers
獲取的序號刪除
root@kvm:~# iptables --line-numbers -vnL INPUT
Chain INPUT (policy ACCEPT 1045 packets, 123K bytes)
num pkts bytes target prot opt in out source destination
1 2 168 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
2 0 0 ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
3 11 924 DROP all -- * * 192.168.55.132 0.0.0.0/0
4 0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
- 刪除指定編號的規則
root@kvm:~# iptables -t filter -D INPUT 3
root@kvm:~# iptables --line-numbers -vnL INPUT
Chain INPUT (policy ACCEPT 7 packets, 488 bytes)
num pkts bytes target prot opt in out source destination
1 2 168 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
2 0 0 ACCEPT all -- * * 10.0.0.1 0.0.0.0/0
3 0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
- 也可以根據規則匹配刪除對應的規則
root@kvm:~# iptables -t filter -D INPUT -s 192.168.55.132 -j ACCEPT
- 刪除鏈中所有規則
root@kvm:~# iptables -t filter -F
* 規則的修改iptables -t table_name -R INPUT chain_name rule_num rule
示例:
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 61 packets, 5450 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 192.168.55.132 0.0.0.0/0
root@kvm:~# iptables -t filter -R INPUT 1 -j ACCEPT
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 7 packets, 488 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- * * 192.168.55.132 0.0.0.0/0
關于鏈默認規則說明
???????當鏈的默認規則為 ACCEPT 時,設置的規則應該是
DROP
或REJECT
。因為不管報文是否被匹配到都會匹配ACCEPT,所以就是去了意義。
???????因此當鏈的默認規則是 ACCEPT 時,鏈中規則應該使用DROP
或REJECT
,表示只有匹配到規則的報文會被拒絕,沒有匹配到的默認是放行的。也就是“黑名單”機制。
???????反之,當鏈的默認規則為 DROP 時,鏈中規則應該使用ACCEPT
,表示只有匹配到規則的才會放行,沒有匹配到的將被禁用。也就是“白名單”機制。謹慎將鏈的規則改為 DROP,如果鏈內沒有規則所有請求都將被拒絕
不能省略 -s
如果省略效果如下
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 61 packets, 5450 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 192.168.55.132 0.0.0.0/0
root@kvm:~# iptables -t filter -R INPUT 1 -j ACCEPT
root@kvm:~# iptables -vnL INPUT
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
9 738 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0
source 變為0.0.0.0/0 表示所有網段都被 ACCEPT
* 修改鏈的默認規則 iptables -t table_name -P chain_name target
示例
root@kvm:~# iptables -vnL FORWARD
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
root@kvm:~# iptables -t filter -P FORWARD DROP
root@kvm:~# iptables -vnL FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
* 保存規則
默認情況下添加的規則都是臨時的,當重啟 iptables 或者重啟系統時規則將丟失
ubuntu系統保存 iptables
iptables-save
centos 系統保存 iptables
service iptables save
;centos6需要提前安裝iptables-services
* 自定義鏈 iptables -t table -N customize_chain_name
示例:
root@kvm:~# iptables -t filter -N TEXT
root@kvm:~# iptables -t filter -vnL
Chain INPUT (policy ACCEPT 9 packets, 738 bytes)
pkts bytes target prot opt in out source destination
20 1680 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 10/min burst 5
32 2688 REJECT icmp -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 6 packets, 524 bytes)
pkts bytes target prot opt in out source destination
Chain TEXT (0 references)
pkts bytes target prot opt in out source destination
- 重新命名自定義鏈
iptables -E TEXT TEST
- 在其他鏈中引用自定義鏈
iptables -t filter -I INPUT -p tcp --dport 80 -j TEXT
- 刪除自定義鏈
iptables -t filter -E TEST
;前提是沒有引用自定義鏈且自定義鏈中規則為0 - 向自定義鏈中添加規則和默認相同;
* 參數說明
參數 | 說明 | 示例 |
---|---|---|
--flush -F chain |
刪除某個鏈或所有鏈的規則 | iptables -F INPUT |
--inster -I chain [rulenum] |
插入規則(表第一行插入) | iptables -t filter -I INPUT -s 192.1.68.12.23 -j DROP |
--source -s address[/mask] |
指定條件(例中 -s 指定的是源 ip 地址) | iptables -t filter -I INPUT -s 192.1.68.12.23 -j DROP |
--jump -j target |
當-s 條件滿足時要做的動作;常用動作如下;ACCEPT : 允許數據包通過;DROP :直接丟棄數據包,不給任何回應信息;REJECT :拒絕數據包通過,需要時會給數據發送端一個相應信息 |
iptables -t filter -I INPUT -s 192.1.68.12.23 -j DROP |
--append -A chain |
添加一條規則(在表的尾部) | iptables -A INPUT -s 192.1.68.12.23 -j DROP |
--delete -D chain rulenum |
刪除規則 | iptables -t filter -D INPUT 3 |
--flush -F [chain] |
刪除鏈中所有規則 | iptables -f filter -F INPUT |
--replace -R chain rulenum |
修改規則 | iptables -t filter -R INPUT 1 -j ACCEPT |
--policy -P chain target |
修改鏈的默認規則 | iptables -t filter -P INPUT DROP |
--destination -d address[/mask] |
指定目標ip或端口等規則 | iptables -t filter -I INPUT -s 10.1.1.1 -d 10.1.2.2 -j ACCEPT |
--protocol -p proto |
指定協議(示例,拒絕 tcp)默認所有協議均可使用 | iptables iptables -t filter -I INPUT -s 10.1.1.1 -d 10.1.1.2 -p tcp -j REJECT |
--in-interface -i input name |
定制網卡接口 | iptables -t filter -I INPUT -i eth2 -p icmp -j DROP |
--match -m match |
指定模塊 | |
--new -N chain |
自定義鏈 | iptables -t filter -N TEST |
--delete-chain -X chain |
刪除自定義鏈,前提沒有引用且自定義鏈中規則為0 | iptables -t filter -X TEST |
--rename-chain -E old-chain new-chain |
修改鏈名 | iptables -t filter -E TEXT TEST |