Linux防火牆簡介 – iptables配置策略
Netfilter/iptables簡介
要想真正掌握Linux防火牆體系,首先要搞清楚Netfilter和iptables的關系,Netfilter和iptables包含在Linux2.4以后的內核中,可實現防火牆、NAT和數據包分割的功能。Netfilter采用模塊化設計,具有良好的可擴展性。Netfilter是一個框架,iptables則是我們用戶層的工具,通過iptables我們可以配置很多規則,這些規則加載到Netfilter框架中生效。
Netfilter可以和協議棧很好的契合,如圖1所示;協議棧底層實現機制就是這樣,ABCDE就是我們可以配置規則的點,BD我們可以控制本機的數據包,ACE可以控制經過本網卡轉發的數據包。那么在Netfilter中如何實現?如圖2所示;針對ABCDE五個點,Netfilter定義了五個hook函數;五個鈎子函數對應了五個規則鏈:PREROUTING、INPUT、OUTPUT、FORWARD、POSTROUTING;我們使用iptables配置的規則就在這五個規則鏈中生效。
iptables並不是服務,iptables/natfilter相關的內核模塊,包括以下幾個:iptables_net、iptables_filter、iptables_mangle、iptables_raw,這些模塊我們也可以自己寫腳本讓它們運行,不一定非使用iptables。
圖1. 協議棧底層實現
圖2. Netfilter實現
Iptables簡介
IPtables主要包括四方面的功能:
Filter(過濾功能)可配置在INPUT鏈、OUTPUT鏈、FORWARD鏈
NET(地址轉換功能)可配置在PREROUTING鏈、POSTROUTING鏈、OUTPUT鏈
Mangle(修改報文首部)可配置在五個鏈上
Raw(原始格式)可配置在PREROUTING鏈和OUTPUT鏈
我們主要介紹Filter和NET功能
如果在某一個鏈上配置了多個功能的規則改以什么順序生效呢?如下圖所示:
圖3. 規則生效順序圖
Iptables也可以自定義鏈,但是必須由默認的這五個鏈調用,類似於中斷功能,如果自定義鏈匹配則不必返回,如果自定義鏈不匹配,則返回到主鏈繼續匹配。一般將那些同類的,規則比較多的獨立出來,用戶可以刪除自定義的空鏈。
每個規則鏈都有兩個內置的計數器,一個記錄被匹配的報文個數,一個記錄匹配到的報文大小。
Iptables規則舉例
下面我們以iptables的幾個例子來引入iptables規則的詳細解釋(man iptables可以獲得幫助文檔)。
//允許所有主機訪問本機的web服務
iptables -I INPUT -d 172.16.100.7 -p tcp -dport 80 -j ACCEPT iptables -I OUTPUT -s 172.16.100.7 -p tcp -sport -j ACCEPT
//放行sshd、httpd,並追蹤連接
iptables –A INPUT -d 172.16.100.7 –p tcp --dport 22 –m state --state NEW,ESTABLISHED,-j ACCEPT
iptables –A OUTPUT -s 172.16.100.7 –p tcp --sport 22 –m state --state ESTABLISHED,-j ACCEPT
iptables –A INPUT -d 172.16.100.7 –p tcp --dport 80 –m state --state NEW,ESTABLISHED,-j ACCEPT
iptables –A OUTPUT -s 172.16.100.7 –p tcp --sport 80 –m state --state ESTABLISHED,-j ACCEPT
//允許自己ping別人,別人不能ping自己
iptables -A OUTPUT -s 172.16.100.7 -p icmp --icmp-type 8 -j ACCEPT
iptables -A INPUT -d 172.16.100.7 -p icmp --icmp-type 0 -j ACCEPT
上面的規則中,選項 -I 指的是插入一條規則,后面跟數字的話,代表插入到第幾條。
上面都沒有指定 -t 選項,-t的作用是指定在哪個表操作,如果不指定默認是filter表。
-A選項向鏈中添加規則;-s源地址,-p指定協議,--sport源端口,-m使用擴展模塊,--state指定狀態,-j指定執行的動作。
Iptables命令詳解
在這一章我們主要介紹常用的Iptables選項,具體的選項可以使用man iptables來查詢:也可以通過幾個在線文檔查詢:
https://wiki.archlinux.org/index.php/Iptables_(簡體中文)
https://doc.ubuntu-fr.org/iptables
https://zh.wikipedia.org/wiki/Iptables
官方手冊 (比較晦澀) http://ipset.netfilter.org/iptables.man.html
https://wsgzao.github.io/post/iptables/
iptables規則大致由“匹配標准”和“處理動作”組成;iptables在寫規則的時候必須指明在哪個鏈上實現什么功能,表可以不用指定。如下:
iptables [-t table] commond chain [num] 匹配標准 -j 處理辦法 |
1)iptables常用命令:
iptables -t [table]:指定表 -A CHAIN :附加一條規則,在鏈的尾部添加。 -I CHAIN [num]:在指定位置添加。 -D CHAIN [num]:刪除指定鏈,第num條規則。 -R CHAIN [num]:替換指定的規則。 -F [CHAIN]: 清空指定鏈的規則,如果省略CHAIN,則清空這個表中的所有鏈的規則。 -P CHAIN:設定指定鏈的默認策略 -N:自定義一個新的空鏈 -X:刪除一個自定義的空鏈 -Z:清空指定鏈中的所有規則計數器 -E:重新命名自定義鏈
-L:顯示指定表中的所有規則
-n:以數字格式顯示主機地址和端口號。
-v:顯示詳細信息;
-vv:顯示更詳細信息。
-x:顯示精確值
--line-numbers:顯示規則號
2)匹配標准:
a)通用匹配;
這類匹配是通用的匹配,可以通過man查詢或者查詢在線文檔獲取更多信息
-s:指定源ip地址,-d:指定目的地址;
-p{tcp|udp|icmp}:指定協議
-i eht0:指定數據報文流入的接口
-o eth0:指定數據報文流出的接口
b)擴展匹配; 擴展匹配需要依賴於模塊才能完成檢查;如果使用-p選項,則不用特別指定使用哪個模塊完成檢查;
隱含擴展:
-p tcp
--sport PORT[-PORT]
--dport PORT[-PORT]
--tcp-flags MASK COMP: 檢查tcp標志位;
eg:--tcp-flags SYN,FIN,ACK,RST SYN,ACK 檢查四個標志位中的兩個是否為1.
--syn:專門匹配三次握手中的第一次
-p icmp
--icmp-type
匹配ICMP協議的ICMP TYPECODE,其中TYPE為8代表ping請求,TYPE為0代表平響應。
搜一下"ICMP TYPECODE對應表"即可找到。
-p udp
--sport
--dport
顯示擴展:(增加額外的匹配機制,每個擴展都有自己獨有的功能)
-m EXTESTION --spe-opt
state擴展:
結合ip_conntrack追蹤當前會話所處的狀態,NEW、ESTABLISHED、INVALID、RELATED
eg:只要是下面兩種狀態的都放行
-m state --state NEW,ESTABLISHED -j ACCEPT
multiport擴展:離散多端口擴展
--source-ports
--destination-ports
--ports
eg:-m multiport --destination-ports 21,22,80
iprange擴展:指定地址范圍
-m iprange
--src-range ip-ip
--dst-range ip-ip
eg: 源地址不在 172.16.100.3-172.16.100.100范圍內的訪問
iptables -A INPUT -p tcp -m iprange ! --src-range 172.16.100.3-172.16.100.100 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
connlimit擴展:
-m connlimit
--connlimit-above n
eg: 如果沒有達到連接上限我們就允許
iptables -A INPUT -d 172.16.100.7 -p tcp --dport -m connlimit ! --connlimit-above 2 -j ACCEPT
limit擴展:
-m limit 不控制最大上限,只控制單位時間內最大上限和一次蜂擁而至的上限
--limit rate
--limit-burst
eg:限制ping請求
iptables -R INPUT 3 -d 172.16.100.7 -p icmp --icmp-type 8 -m limit --limit 1/minute -j ACCEPT
**string擴展**
-m string
--algo bm|kmp
--from offset
--to offset
--string pattern
eg: 如果請求串中含有hello world就拒絕,如果響應內容中含有hello就拒絕。
iptables -I INPUT -d 172.16.100.7 -m string --algo kmp --string "hello world" -j REJECT
iptables -I OUTPUT -s 172.16.100.7 -m string --algo kmp --string "hello" -j REJECT
time擴展:
-m time
--timestart --timestop
--datestart --datestop
eg:
iptables -A FORWARD -s 192.168.10.0/24 -m time --timestart 09:10:00 --timestop 12:00:00 -j DROP
recent擴展:
-m recent
--set 記錄
--name 制定記錄的協議名
--update
--seconds
--hitcount
eg:利用recent模塊和state模塊限制單ip在300s內只能與本機建立3個新鏈接,被限制5分鍾后恢復訪問
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SS
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
第二句是指SSH記錄中的IP,300s內發起超過3次連接則拒絕此IP的連接。
--update 是指每次建立連接都更新列表;
--seconds必須與--rcheck或者--update同時使用
--hitcount必須與--rcheck或者--update同時使用
//記錄日志
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"
3)處理辦法:
ACCEPT :允許通過
DROP :拒絕
REJECT :拒絕的更徹底
DNAT :目標地址轉換
SNAT :源地址轉換
REDIRECT :端口重定向
MASQUERAND :地址偽裝
LOG :記錄日志
MARK
-j LOG: 記錄日志
--log-level
--log-prefix
--log-tcp-sequence
--log-uid
--log-ip-options:記錄ip選項信息
eg:記錄哪一刻,誰發起了ping請求
iptables -I INPUT 4 -d 172.16.100.7 -p icmp --icmp-type 8 -j LOG --log-prefix "----firewall log for icmp----"
//將保存在 /var/log/messages
NAT地址轉換
如何打開轉發功能?
echo 1 > /proc/sys/net/ipv4/ip_forward
要想永久有效:
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
網關打開轉發功能之后,兩個網段的主機便可通信,但是為什么還要NAT地址轉換呢?主要是接入外網的時候,雖然報文能發出去,但是如果不做地址轉換,響應報文回不來,不像這里的兩個網段這么簡單,報文能回來是因為路由的原因。
-j SNAT
--to-source A->B->C A是內網,A訪問外網C,則在B這里要進行源地址轉換,源地址轉換應該在POSTROUTING鏈上;
eg:
iptables –t nat –A POSTROUTING –s 192.168.10.0/24 –j SNAT –to-source 172.168.100.7
-j MASQUEREAD
在外網地址是動態獲取的時候才使用,自動查找一個能上網的地址。
-j DNAT
--to-destination 目標地址轉換必須指定針對什么服務進行轉換的:
eg:
iptables -t nat -A PREROUTING -d 172.16.100.7 -p tcp -dport 80 -j DNAT --to-destination 192.168.10.22
//指定轉發到哪個端口
iptables -t nat -A PREROUTING -d 172.16.100.7 -p tcp -dport 80 -j DNAT --to-destination 192.168.10.22:8080
如何在NAT上進行過濾
iptables -A FORWARD -m string --algo kmp --string "hello" -j DROP
Iptables其他知識點
lsmod | grep ip 可以查看跟ip相關的模塊是否啟動起來。
service iptables stop:停止iptables服務
iptables -L -n :顯示所有規則
iptables -P INPUT DROP:改默認策略為堵策略
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
ip_contrack內核模塊能夠實現鏈接追蹤功能,為了能夠實時追蹤和查詢,需要保存當前每一個客戶端和當前主機所建立的鏈接關系。
這個文件可以保存多少個追蹤條目?
iptables -t 顯示當前鏈接的個數
ls /proc/sys/net/ipv4/netfilter/
可以改每個鏈接的失效時間
保存規則:
# Service iptables save
保存到: /etc/sysconfig/iptables
# iptables-save > /etc/sysconfig/iptables.201703
# iptables-restore < /etc/sysconfig/iptables.201703
/etc/sysconfig/iptables
iptables在啟動的時候會重新加載配置信息,因此要把寫的規則保存到
cat /etc/sysconfig/iptables下面
使用iptables命令可以保存規則到這個文件下面
DNS服務器要寫4條規則才能真正生效:因為DNS服務器即做服務器又做客戶端。TCP、UDP都監聽的話需要8條規則。
自定義鏈:
iptables –N clean_in
iptables –A clean_in –d 255.255.255.255 –p icmp –j DROP
iptables –A clean_in –d 172.255.255.255 –p icmp –j DROP
iptables –A clearn_in –p tcp ! –syn –m state --state NEW –j DROP
iptables –A clearn_in –d 172.16.100.7 –j RETURN #返回主鏈
iptables –I INPUT –j clearn_in #被主鏈調用
刪除自定義鏈,首先要清空自定義鏈,然后再用語句刪除。
Iptables規則練習
1. 放行FTP
要想放行FTP協議,首先要裝載ip_conntrack_ftp和ip_nat_ftp模塊,Vim /etc/sysconfig/iptables-config 下找到IPTABLES_MODULES,在這個地方指明要加載的模塊。IPTABLES_MODULES=”ip_nat_ftp ip_conntrack_ftp”。
iptables –A INPUT –d 172.16.100.7 –p tcp –m state –-state RELATED,ESTABLISHED –j ACCEPT
iptables –I INPUT 2 –d 172.16.100.7 –p tcp –m multiport –destination-ports 21,22 –m state --state NEW –j ACCEPT
放行回話需要些兩天規則:
iptables -t filter -A INPUT -s 172.16.0.0/16 –d 172.16.100.7 –p tcp –dport 22 –j ACCEPT
iptables –t filter –A OUTPUT –s 172.16.100.7 –d 172.16.0.0/16 –p tcp –sport 22 –j ACCEPT
2、追蹤鏈接放行sshd、httpd
iptables –A INPUT -d 172.16.100.7 –p tcp --dport 22 –m state --state NEW,ESTABLISHED,-j ACCEPT
iptables –A OUTPUT -s 172.16.100.7 –p tcp --sport 22 –m state --state ESTABLISHED,-j ACCEPT
iptables –A INPUT -d 172.16.100.7 –p tcp --dport 80 –m state --state NEW,ESTABLISHED,-j ACCEPT
iptables –A OUTPUT -s 172.16.100.7 –p tcp --sport 80 –m state --state ESTABLISHED,-j ACCEPT
修改追蹤數值:
sysctl –w net.ipv4.ip_conntrack_max=65536
這種改法不會永久有效,要想永久有效,要寫在
/etc/sysctl.conf
3、只要是本機響應的都可以放行
iptables –I OUTPUT –s 172.16.100.7 –m state –state ESTABLISHED –j ACCEPT
再放行數據包的時候,一定要清楚協議運行的流程,出入包順序。
Layer7 Filter
L7-filter可以過濾應用層協議,是一個開源項目:官方網址:http://l7-filter.sourceforge.net/
涉及到編譯內核等問題,如果有需要可查閱官方文檔,或者有心人發布的博客介紹。
L7所支持的協議:
用法:
iptables –A FORWARD –s 192.168.10.0/24 –m layer7 –l7proto qq –j REJECT
參考資料:
洞悉linux下的Netfilter&iptables:什么是Netfilter?
http://blog.chinaunix.net/uid-23069658-id-3160506.html
Google搜索 Iptables得到的網站,挑了幾個講解比較全的:
https://wiki.archlinux.org/index.php/Iptables_(簡體中文)
https://doc.ubuntu-fr.org/iptables
https://zh.wikipedia.org/wiki/Iptables
官方手冊 (比較晦澀) http://ipset.netfilter.org/iptables.man.html
https://wsgzao.github.io/post/iptables/
馬哥Linux運維教程208講是本篇文章的主要參考資料