原文鏈接:http://blog.51cto.com/tanxw/1389114
前言
iptables其實就是Linux下的一個開源的信息過濾程序,包括地址轉換和信息重定向等功能的,他由四表五鏈組成的,信息過濾功能十分強大,而所謂的硬件防火牆也就是一個Linux核心加頁面操作程序做出來的,可以用於添加、編輯和移除規則。
正文
如果我們的主機上有一塊網卡、當用戶請求到達時、首先會到達我們的硬件設備、而且我們應該知道、能夠在硬件上接收數據並且能夠做后續處理的只有內核、而內核中用於網絡屬性管理的是TCP/IP的協議棧、其實就是TCP/IP的模塊。
一個報文由網卡到達本主機的TCP/IP協議棧之后就要判斷他的目標IP了、所以在TCP/IP協議棧有一個路由表、是由本機的路由模塊實現的、如果他發現目標IP就是本機的IP地址、那就會繼續檢查他的目標端口、如果目標端口被本機上的某個用戶進程注冊使用了、那這個進程就監聽在這個套接字上、所以檢查到的這個端口的確是主機的某處進程在監聽、那這個報文就會通過這個套接字通過用戶空間轉發給對應的進程了、所以這個報文就到達本機的內部去了。
當我們的路由檢查機制發現目標IP不是本機的IP地址、而后就要檢查我們的路由是否允許做網絡間的轉發了、如果允許做向外轉發、那他不會進入用戶空間、直接在內核中直接交給另一塊網卡(假如主機上有兩塊網卡)或另一個IP轉發出去了、在內核中走一圈又出去了。
什么叫內部轉發:如果說我們主機上有兩塊網卡、或者說一塊網卡有兩個地址、一個地址可以接收請求、另一個地址可以把請求發出去、這就是網絡間的轉發機制
然而我們所說的防火牆其實是由iptables和netfilter兩部分組成的,iptables就是負責在netfilter上寫規則的、而netfilter就是我們事先設好的卡哨、五個卡哨所組合起來叫netfilter、而iptables只是負責在卡哨上填充規則的、規則是真正檢查者、卡哨是可以將你的通路都擋掉、而在內核中這些卡哨被稱為勾子函數、所以規則才是真正能起來防護作用的機制、而netfilter只是讓這些規則得以生效的、那對linux來講、這些卡哨都是有名字的、每個勾子函數都有他的名字、根據這些報文的流向定義的名稱、而這些名稱在iptables上被稱為叫鏈,iptables上的鏈有5條,這就是傳說中的5個勾子函數:
INPUT:從本機進來的
OUTPUT:從本機出去的
FORWARD:從本機轉發的、本機內部出去了、無論如何也不會經過FORWARD
POSTROUTING:路由之后
PREROUTING:路由之前
filter就是過濾信息的,那什么叫過濾:就是能夠實現報文篩選的
NAT是什么呢:Network Address Translation 網絡地址轉換,在互聯網上私有地址是不會被路由的、所以發報文時對方可以收到、但是無法響應你的請求、在這種情況下要想訪問互聯網只有做代理或用NAT,所謂在址轉換就是將你請求報文中的源地址或目標地址改為我們所指定的地址這就叫地址轉換:
DNET:源地址轉換
SNET:目標地址轉換
mangle:簡單來講、一個IP報文都有TTL值全稱是"生存時間(Time To Live)"的、每經過一個網官IP首部都會減一的、本來你經過我這里的網官減一、但是我又加上一、像這種即不做過濾、也不做轉換、而是改變了IP/TCP首部的其他信息、那這種機制就叫mangle機制。
raw:有限級最高,設置raw時一般是為了不再讓iptables做數據包的鏈接跟蹤處理,提高性能。
規則是如何對報文進行檢查的:
要寫一條規則、一定是匹配某些報文中的特征、如果這個報文的特征被這條規則的檢查條件所匹配到、那就由后面的指定的處理機制進行處理了、這種處理機制有:源地址轉換、目標地址轉換、允許、拒絕、跳轉。
其實我們做防火牆有兩大策略:
通:所謂通就是做白名單、誰都不許通過、只有在名單中的可能通過。默認為堵
堵:做黑名單、誰都可以過、只是把那些在名單中的堵了。默認為通
通和堵只對filter表有效、也只有filter表才需要做默認策略、通和堵本來就是過濾。
保存規則:service iptables save
被保存到/etc/sysconfig/iptables文件中
而start時會讀取此文件中的內容經設置規則、如果我們不想讓規則保存到默認文件的路徑中、那我們可以指定保存的路徑:
#iptables-save > /path/to/some_rulefile
要注意的是、當服務器啟動后保存到指定文件是不會被讀取的、那如果我們又想讓文件生效怎么做呢、用輸入重定向:
# iptables-restore < /path/to/some_rulefile
iptables/netfilter組合關系:
netfilter:工作在內核空間、讓規則能夠生效的網絡框架
iptables:工作於用戶空間、編寫規則並且發送到netfilter上的
其實iptables在Linux 2.0的時候被叫做ipfwadm,而在Linux2.2的時候通常被叫做ipchains,而到了Linux2.4及其以后的版本就叫做iptables、那至於到以后還叫不叫iptables就不得而知了。
iptables寫規則:
iptables [-t table] -N chain:定義一條自定義的新鏈
iptables [-t table] -X [chain]:刪除一條自定義空的規則鏈
iptables [-t table] -E old-chain-name new-chain-name:為自定義鏈改名的
iptables [-t table] -P chain target:為鏈指定默認策略
iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]:清空鏈中的規則、如果不指定鏈那表中所有的鏈都清空了
-F:清空鏈中的規則、規則有編號、在鏈中自上而下、從1開始
-L:list,列出表中的所有規則
-n:數字格式顯示IP和Port、如果不用-n、ip就會反解為主機名、端口反解成服務名、會很慢
-v:以詳細格式顯示
-vv:更詳細
-vvv:更更詳細
-x:exactly,精確值、不執行單位換算
--line-numbers:顯示各規則的行號
-Z:zero,清零、把規則的計數器清零
iptables [-t table] {-A|-D} chain rule-specification
-A:append,附加一條規則、在規則的后面添加
rule-specification:通常使用匹配條件 -j 處理機制
iptables [-t table] -I chain [rulenum] rule-specification:在指定位置插入規則
iptables [-t table] -R chain rulenum rule-specification:修改指定規則為新定義的
iptables [-t table] -S [chain [rulenum]]:顯示指定鏈上的規則
匹配條件:因為iptables是網絡層的防火牆、他只能匹配協議、IP、TCP、UDP、ICMP、匹配條件肯定是根據底層的IP報文來檢查、或都根據TCP、UDP、ICMP來檢查
這幾種叫通用匹配
-s IP:匹配源IP的、可以是IP也可以是網絡地址、可以取反、用!號取么
-d IP:匹配目標地址的、
-p Proctol:匹配協議的[TCP|UDP|ICMP]、三者之一
-i:數據報文流入的接口、數據包從哪個網卡進來呀、通常只用於INPUT、FORWARD、PRERUTING
-o:數據報文流出的接口、OUTPUT、FORWARD、POSTROUTING
隱含擴展:當使用-p指定某一協議之后、那個協議自身所支持的擴展就叫做隱含擴展、使用[tcp|udp|icmp]指定某特定協議后、自動能對協議進行擴展。
-p tcp、后面可以指定端口
--dport m[-n]:目標端口、m[-n]可以使用一片連續的端口、還可以在前面用!號取反
--sport:源端口、這個跟上面的一樣
--tcp-flags:tcp的標志位匹配的
-p udp、udp只有端口
--dport
--sport
-p icmp (8是ping的請求、0是ping的響應)
--icmp-type
顯式擴展:必須要明確指定的擴展模塊
-m 擴展名稱 --專用選項1 --專用選項2
multiport:多端口匹配、一次指定多個離散端口(一般不超過15個)
--source-ports:源端口
--destination-ports:指定目標商品端口
--ports:指定多個端口、多個端口間用逗號隔開
iprange:ip地址匹配范圍、我們可以匹配指定的IP段
[!] --src-range from[to]:指定源地址范圍
[!] --dst-range from[to]:指定目標地址范圍
time:指定時間范圍
--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:指定開始日期 --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:指定結束日期
--timestart hh:mm[:ss]:指定開始時間不指定日期
--timestop hh:mm[:ss]:只指定結束時間不指定日期
[!] --weekdays day[,day...]:指定周幾的、"!"號取反
string:對字符串的匹配的、包含有指定的字符串時做相應的處理
--algo {bm|kmp}:英文中的字符比較高效的比較
--string "string":要查找的字符串
--hex-string
connlimit:每IP對指定服務器的
[!] --connlimit-above [n]
limit:報文速率控制
--limit[/second|/minute|/hour|/day]每秒、每分、每小時、每天
--limit-burst #:一批最多個數、峰值
state:狀態匹配:
--state:僅放行哪些連接的狀態、也可以做狀態連接追蹤的。
什么是狀態連接追蹤呢:
就是對ip_conntrack,nf_conntrack做連接追蹤的、簡單來講就是我們主機中的netfilter會在內核中建立一張表、對進出本主機的連接或會話進行記錄、把訪問本主機的信息記錄下來、如果這張表中只能容納1000條記錄、而連接追蹤數已經大於1000條、那1000條以上的連接就會被拒絕、雖然我們知道這些連接的相關狀態和相關詳細信息、但他內部默認的空間大小是有限的、而且很小、容易在一個非常繁忙的服務器上打滿、那后續的連接將會被屏蔽、被拒絕、那很明顯我們服務器將拒絕提供服務、所以不到萬不得已時不要使用連接追蹤的功能、啟用時也要調空間的大小。
只說命令請求的本身
NEW:進來的請求為new
ESTABLISHED:已建立的會話連接、響應和后續命令的發送都是established
RELATED:相關聯的、一旦啟用一個數據連接、這個數據連接和命令連接就叫related
INVALID:所有無法識別的連接都叫invalid
iptables是能夠實現狀態檢測機制的防火牆、使得其非常安全的、那狀態檢測機制通常依賴於state模塊來實現、這個模塊基於ip_conntrack、nf_conntrack在自己內存中維護一個會話表、能夠追蹤每一個連接請求、這種追蹤會在內存中記錄一個條目、每個條目都有一個倒記時的記時器、當記時器為零就會被清出去、但當為零之前一直在訪問將重新被刷新、那么任何一個請求在連接前都會去查這張表netfilter、如果表中有這個條目、就叫做ESTABLISHED、如果沒有這個條目就叫做NEW、如果說有條目、但這個條目跟本身連接沒有關系、跟本身連接的別外一個連接有關系就叫做RELATED、無法識別的連接都叫做INVALID、像什么六個標志位都為1或都為零。
法則:
1、對於進入狀態為ESTABLISHED都應該放行
2、對於出去的狀態為ESTABLISHED都應該放行
3、嚴格檢查進入的狀態為NEW的連接
4、所有狀態為INVALIED都應該拒絕
1
|
# iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.7 -j ACCEPT
|
1
|
# iptables -t filter -A OUTPUT -s 172.16.100.7 -d 172.16.0.0/16 -j ACCEPT
|
1
|
# iptables -t filter -L -n --line-numbers
|
1
2
|
# iptables -F
# iptables -L -n -v
|
1
|
# iptables -F -t filter
|
1
|
# ifconfig eth0:0 192.168.1.188
|
1
|
# iptables -t filter -A INPUT -i eth0 -d 172.16.251.171 -j ACCEPT
|
1
|
# iptables -t filter -A OUTPUT -o eth0 -s 172.16.251.171 -j ACCEPT
|
1
|
# iptables -t filter -A INPUT -i eth0 -d 172.16.251.171 -p tcp -j ACCEPT
|
1
|
# iptables -t filter -A INPUT -i eth0 -d 172.16.251.171 -p icmp -j REJECT
|
1
|
# iptables -I INPUT -d 172.16.251.171 -p tcp --dport 80 -m connlimit --connlimit-above 3 -j DROP
|
1
2
|
# iptables -A OUTPUT -s 172.16.251.171 -p icmp --icmp-type 8 -j ACCEPT
# iptables -A INPUT -d 172.16.251.171 -p icmp --icmp-ytpe 0 -j ACCEPT
|
1
2
|
# iptables -A INPUT -d 172.16.251.171 -p tcp --dport 901 -m time --weekdays Mon,Tus,Wed,Thu,Fri --timestart 08:00:00 timestop 18:00:00 -j ACCEPT
# iptables -A OUTPUT -s 172.16.251.171 -p tcp --sport 901 -j ACCEPT
|
1
2
|
# iptables -A INPUT -d 172.16.251.171 -p tcp --dport 901 -m time --weekdays Mon,Tus,Wed,Thu,Fri --timestart 08:00:00 timestop 18:00:00 -j ACCEPT
# iptables -A OUTPUT -s 172.16.251.171 -p tcp --sport 901 -j ACCEPT
|
1
|
# iptables -A OUTPUT -s 172.16.251.244 -m state --state ESTABLISHED -j ACCEPT
|
1
2
3
4
5
6
7
|
# iptables -t filter -N clean_in
# iptables -A clean_in -d 172.16.251.244 -p tcp --tcp-flags ALL ALL -j DROP
# iptables -A clean_in -d 172.16.251.244 -p tcp --tcp-flags ALL NONE -j DROP
# iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP
# iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP
# iptables -A clean_in -d 172.16.251.244 -j RETURN 自定義鏈中返回鏈
# iptables -I INPUT -d 172.16.251.244 -j clean_in 在INPUT鏈上調用鏈
|
1
2
|
# iptables -I INPUT -d 172.16.251.171 -p tcp -m multiport --dports 22,80 -j ACCEPT
# iptables -I OUTPUT -s 172.16.251.171 -d 172.16.0.0/16 -p tcp -m multiport --sports 22,80 -j ACCEPT
|
1
2
|
# iptables -A INPUT -d 172.16.251.171 -p tcp --dport 23 -m iprange --src-range 172.16.100.1-172.17.100.100 -j ACCEPT
# iptables -A INPUT -s 172.16.251.171 -p tcp --sport 23 -m iprange --dst-range 172.16.100.1-172.17.100.100 -j ACCEPT
|
1
2
|
# iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.251.171 -p tcp --dport 22 -j ACCEPT
# iptables -t filter -A OUTPUT -s 172.16.251.171 -d 172.16.0.0/16 -p tcp --sport 22 -j ACCEPT
|
1
2
|
# iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.251.171 -p tcp --dport 80 -j ACCEPT
# iptables -t filter -A OUTPUT -s 172.16.251.171 -d 171.16.0.0/16 -p tcp --sport 80 -j ACCEPT
|
1
2
|
# iptables -t filter -A INPUT -i lo -j ACCEPT
# iptables -t filter -A OUTPUT -o lo -j ACCEPT
|
1
2
3
|
# iptables -N mychain
# iptables -A mychain -p --tcp-flags ALL ALL -j DROP 這個表示所有標志位全為1
# iptables -A mychain -p --tcp-flags ALL NONE -j DROP 標志位全為0
|
1
2
3
4
|
# iptables -A INPUT -s 172.16.0.0/16 -d 172.16.251.171 -p udp --dport 53 -j ACCEPT
# iptables -A OUTPUT -s 172.16.251.171 -d 172.16.0.0/16 -p udp --dport 53 -j ACCEPT
# iptables -A OUTPUT -s 172.16.251.171 -p udp --dport 53 -j ACCEPT
# iptables -A INPUT -d 172.16.251.171 -p udp --sport 53 -j ACCEPT
|
1
2
|
# iptables -A INPUT -s 172.16.0.0/16 -d 172.16.251.171 -p udp --dport 69 -j ACCEPT
# iptables -A OUTPUT -s 172.16.251.171 -d 172.16.0.0/16 -p udp --sport 69 -j ACCEPT
|
1
2
|
# iptables -A OUTPUT -s 172.16.251.171 -p icmp --icmp-type 8 -j ACCEPT
# iptables -A INPUT -d 172.16.251.171 -p icmp --icmp-ytpe 0 -j ACCEPT
|
1
|
# iptables -D INPUT 3
|
1
2
|
# iptables -I INPUT -i lo -j ACCEPT 默認插入為第一行
# iptables -I INPUT 2 -i lo -j ACCEPT 插入為第二行
|
1
|
# iptables -t filter -R INPUT 1 -s 172.16.0.0/16 -d 172.16.251.171 -p tcp --dport 22 -i eth0 -j ACCEPT
|