iptables從入門到精通
本文主要圍繞以下七點進行闡述:
一、防火墻簡介
二、Iptables簡介
三、Iptables的四張表及五條鏈
四、Iptables的filter應用詳解
五、Iptables的nat應用詳解
一、防火墻簡介:
在網絡中,所謂的防火墻是指一種將內部網絡和公眾訪問網分開的方法,它實際上一種隔離技術。
防火墻分硬件防火墻和軟件防火墻,無論在哪個網絡中,防火墻均工作在網絡的邊緣,我們的任務就是需要定義防火墻在網絡中如何進行工作,這就是防火墻的工作策略,規則,以達到讓它對出入網絡的IP、數據進行檢測。
對于TCP/IP的模型來講,網絡層的防火墻會在網絡層對原地址和目標地址進行檢測,但對于七層的防火墻,不管你源端口或者目標端口,都將會對所有的東西進行檢查。所以,對于設計原理來講,七層防火墻更加安全,但是這卻帶來了更低的效率。所以目前市面一般采用三層和七層相結合的防火墻方案。
二、iptables簡介
Iptables是Linux系統中的防火墻,用于實現Linux下訪問控制的功能,第一版前身是ipfirewall(內核1.x時代),可以將所有規則都需要放在內核中對數據包進行檢測的一款簡易訪問控制工具。第二版更名為ipchains,它可以定義多條規則,將他們串起來,共同發揮作用,現在,他叫做iptables,可以將規則組成一個列表,實現絕對詳細的訪問控制列表。
Iptables定義的規則,可以讓在內核空間中的netfilter來讀取,并且實現讓防火墻工作。而放入內核的地方必須要是特定的位置,必須是tcp/ip的協議棧經過的地方。而這個tcp/ip協議棧必須經過的地方,可以實現讀取規則的地方就叫做netfilter(網絡過濾器)。
三、iptables的四張表及五條鏈
Netfilter:功能
Netfilter所規定的五個鏈規則,任何一個數據包,只要經過本機,必將會經過這五個鏈中的其中一鏈。
Filter:input forward output
//定義一般的過濾功能
Nat:prerouting output postrouting
//用于nat功能(端口映射,地址映射)
Mangle:prerouting input forward output postrouting
//用于對特定的數據包進行修改
Raw:prerouting output
//優先級最高,設置raw時一般是為了不再讓iptables做數據包 的鏈接跟蹤處理,提高性能。
優先級(有高至低)
Raw—->managle—->nat—–>filter
五條鏈:這五條鏈也被成為五個鉤子函數(hook functions);
i. PREROUTING //路由前
ii. INPUT //數據包流入入口
iii. FORWARD //轉發管卡
iv. OUTPUT //數據包流出出口
v. POSTROUTING //路由后
Iptables/netfilter是工作在用戶空間的,它可讓規則進行生效的,本身不是一種服務,而且規則是立即生效的。而我們iptables現在被做成了一個服務,可以進行啟動,停止的。啟動,規則將會直接生效,停止,則將規則撤銷。
Iptables支持定義鏈。自定義鏈需要跟某種特定的鏈關聯起來。在一個關卡設定,指定當有數據的時候專門去找某個特定的鏈來處理,當那個鏈處理完之后,在放回。接著在特定的鏈中繼續檢查。
Iptables的規則順序非常關鍵,誰的規則越嚴格,應該放的越靠前,而檢查的規則的時候,是按照從上向下的方式進行。
在五條鏈上添加規則時需要遵守以下規則,以達到對規則有優化
1、實現的功能:英語判定將規則添加至哪個表;
2、報文流經位置:用于判斷將規則添加至哪個鏈;
3、報文的流向:判定規則中何為“源”,何為“目標”;
4、匹配條件:用于編寫正確的匹配規則;
a) 專用于某些應用的同類規則,匹配范圍小的放在前面;
b) 專用于某些應用的不同規則,匹配到的可能性較多的放在前面;同一類別的規則可使用自定義鏈單獨存放;
c) 用于通用目的的規則放在前面;
d) 為了避免本機不能與本機通信一般不采用將默認規則更改為DROP或者REJECT;而在最后添加一條拒絕的策略;如下
Iptables -A INPUT -j DROP
Iptables -A OUTPUT -j DROP
四、iptables的filter用法詳解
iptables [-t table] COMMAND [chain] [PARAMETERS] [-m matchname [per-match-options]] [-j [target-options]]
iptables默認使用filter表:
連管理的主要選項:
-N : –new-chain chain 新建一個自定義的規則鏈;
[root@localhost ~]# iptables -N QQ //新增一個鏈規則
[root@localhost ~]# iptables -vnL
Chain INPUT (policy ACCEPT 153 packets, 49806 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 138 packets, 49290 bytes)
pkts bytes target prot opt in out source destination
Chain QQ (0 references)
pkts bytes target prot opt in out source destination
-X : –delete-chain 刪除用戶自定義的引用計數為0的空鏈;
-F : –flush [chain] 清空指定的規則鏈上的規則;
-E : –rename-chain old-chain new-chain :重命名鏈;
-Z :–zero [chain[rulenum]] :置零計數器;
注意:每個規則都有兩個計數器:
packets:被本規則所匹配到的所有報文的個數 ;
bytes:被本規則所匹配到的所有報文的大小之和;
-P :–policy chain target 定義規則鏈中的默認規則;
規則管理的主要選項:
-A : 追加新規則用于制定鏈的尾部;
-I :插入新規則于指定鏈的指定位置,默認為首部
-R : 替換指定的規則為新的規則
-D : –delete chain rule-specification 根據規則本身刪除規則
-D : –delete chain rulenum 根據規則編號刪除規則
規則顯示:
-L : –list [chain]:列出規則;
-v :–verbose 詳細信息
-vv :更詳細的信息
-n :–numeric 數字格式顯示主機地址和端口號
-x :–exact 顯示計數器的精確值,而非圓整后的數據;
–line-numbers: 列出規則時,顯示其在鏈上的相應編號;
#iptables -vnL //顯示當前iptables的策略
[root@localhost ~]# iptables -vnL
Chain INPUT (policy ACCEPT 3604K packets, 600M bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 3567K packets, 605M bytes)
pkts bytes target prot opt in out source destination
-S : –list-rules [chain] :顯示指定鏈的所有規則
匹配條件:
通用匹配(PARAMETERS):
[!]-s :–source address[/mask][,…]:檢查報文的源ip地址是否符合此處指定的范圍,或者是否等于此處給定的地址;
[!]-d :–destination address[/mask][…]:檢查報文的目標地址是否符合此處指定的范圍,或是否等于此處給定的地址;
[!]-p :–protocol protocol:匹配報文中的協議,可用值tcp,udp,udplite,icmp,icmpv6,esp,ah,actp,mh或者all,也可以使用數字格式指名協議;
-m :–match match :調用制定的擴展匹配模塊來擴展匹配條件檢查機制;
[!]-i :–in-interface name :限定報文僅能夠從指定的接口流入;only for pack-ets entering the INPUT, FORWARD and PREROUTING chains
[!]-o :–out-interface name :限定報文僅能夠從指定的接口流入;for packets entering the FORWARD, OUTPUT and POSTROUTING chains
跳轉目標:
-j targetname [per-target-options]
ACCETP : 允許數據包通過
DROP:直接丟棄數據包,不回應任何信息
REJECT:拒絕數據包通過,會給數據發送端一個響應的信息;
練習~
1、僅允許主機172.16.252.52對172.16.80.72的SSH端口訪問,并設置默認策略是DROP;
iptables -I INPUT -s 172.16.252.52 -d 172.16.80.72 -p tcp –dport 22 -j ACCEPT
iptables -A INPUT -d 172.16.80.72 -j DROP
iptables -I OUTPUT -s 172.16.80.72 -p tcp –sport 22 -j ACCEPT
iptables -A OUTPUT -s 172.16.80.72 -j DROP
2、添加并引用自定義鏈然后再刪,規則如下:
添加自定義鏈名為:NEW_LIAN
NEW_LIAN開放22 80 端口
將NEW_LIAN引用至INPUT,
iptables -I NEW_LIAN -d 172.16.80.72 -p tcp –dport 22 -j ACCEPT
iptables -I NEW_LIAN -d 172.16.80.72 -p tcp –dport 80 -j ACCEPT
iptables -A NEW_LIAN -d 172.16.80.72 -j DROP
iptables -I INPUT -j NEW_LIAN
iptables -D NEW_LIAN 1 //刪除NEW_LIAN的第一條規則,
iptables -D NEW_LIAN 1 //上一條規則刪除后,第二條規則變成第一
iptables -D NEW_LIAN 1
iptables -X NEW_LIAN
擴展匹配條件:
隱式擴展:在使用-p選項指明了特定的協議時,無需使用-m選項指明模塊的擴展機制;
顯示擴展:必須使用-m選項要調用的擴展模塊的擴展機制;
隱式擴展:
-p tcp:可直接使用tcp協議對應的擴展選項;
[!] –source-port,–sport port[:port]:匹配報文中的傳輸層的源端口;可給出多個連接的端口;
[!] –destination-port,–dport port[:port]:匹配報文中的傳輸層的目標端口;可給出多個連接的端口;
[!] –tcp-flags mask comp
SYN,ACK,FIN,RST,URG,PSH;
mask:要檢查的標志位列表,以逗號分隔,例如SYN,ACK,FIN,RST
comp:mask給定的眾標志位中,其值必須為1的標志位列表,余下的必須為0;
–tcp-flags SYN,ACK,FIN,RST SYN
[!] –syn:相當于–tcp-flags SYN,ACK,FIN,RST SYN
-p udp:可直接使用udp協議對應的擴展選項;
[!] –source-port,–sport port[:port]:匹配報文中的傳輸層的源端口;可給出多個連接的端口;
[!] –destination-port,–dport port[:port]:匹配報文中的傳輸層的目標端口;可給出多個連接的端口;
-p icmp:可直接使用cimp協議對應的擴展選項;
[!] –icmp-type {type[/code]|typename}
–icmp-type 0/0:匹配對ping請求的響應報文
–icmp-type 8/0:匹配ping請求報文
顯示擴展:
1、Multiport
以離散或連續的方式定義的多端口匹配條件;
[!] –source-ports,–sports port[,port|,port:port]…:指定多個源端口;
[!] –destination-ports,–dports port[,port|,port:port]…:指定多個目標端口;
[!] –ports port[,port|,port:port]…:匹配此處指定的源或目標端口;
以下規則允許22,80端口訪問;
Iptables -I INPUT -d 172.16.80.72 -p tcp -m multiport –dports 22,80 -j ACCEPT
Iptables -I OUTPUT -s 172.16.80.72 -p tcp -m multiport –sports 22,80 -j ACCETP
Iptables -A INPUT -d 172.16.80.72 -j DROP
Iptables -A OUTPUT -s 172.16.80.72 -j DROP
[root@localhost ~]# iptables -vnL
Chain INPUT (policy ACCEPT 956 packets, 263K bytes)
pkts bytes target prot opt in out source destination
63 6197 ACCEPT tcp — * * 0.0.0.0/0 172.16.80.72 multiport dports 22,80
50 3772 DROP all — * * 0.0.0.0/0 172.16.80.72
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 946 packets, 261K bytes)
pkts bytes target prot opt in out source destination
49 7775 ACCEPT tcp — * * 172.16.80.72 0.0.0.0/0 multiport sports 22,80
100 6472 DROP all — * * 172.16.80.72 0.0.0.0/0
[root@localhost ~]#
2、Iprange
以連續的ip地址范圍指明多地址匹配條件;
[!] –src-range from[-to]
[!] –dst-range from[-to]
3、string
對報文中的應用層數據做字符串匹配檢測;
[!] –string pattern
[!] –hex-string pattern
–algo {bm|kmp}:字符串匹配檢查算法;
–from offset
–to offset
4、time
根據報文到達的時間與指定的時間范圍進行匹配度檢測;
–datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
–datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
–timestart hh:mm[:ss]
–timestop hh:mm[:ss]
[!] –monthdays day[,day…]
[!] –weekdays day[,day…]
5、connlimit
根據每客戶端IP做并發連接數限制,即限制單IP可同時發起連接請求;
–connlimit-upto n:連接數小于等于閾值;
–connlimit-above n:連接數超出閾值;
Iptables -I INPUT -d 172.16.80.72 -p tcp –dport 80 -m connlimit-upto 10 -J AAEPT
lptables -I INPUT -d 10.1.0.6 -p tcp –dport 22 -m connlimit –connlimit-above 2 -j REJECT
6、limit
基于收發報文的速率進行匹配;
–limit rate[/second|/minute|/hour|/day]
–limit-burst number
iptables -A INPUT -d 10.1.0.6 -p icmp –icmp-type 8 -m limit –limit-burst 3 –limit 20/minute -j ACCEPT
//當ping請求到3個的時候沒分鐘20個的速度進行控制;
7、state
狀態檢測:連接追蹤機制(conntrack)
NEW:新連接
ESTABLISHED:已建立的連接
RELATED:相關聯的連接
INVALID:無法識別的連接
UNTRACKED:未被追蹤連接;
相關的內核模塊:
nf_conntrack
nf_conntrack_ipv4
nf_conntrack_ftp
追蹤到的連接:/proc/net/nf_conntrack文件中;
能追蹤的最大連接數量定義在:/proc/sys/net/nf_conntrack_max //默認為65535
建議調整至足夠大;
不同的協議的連接追蹤時長:
/proc/sys/net/netfilter/
[!] –state state
如何開放被動模式的ftp服務:
(1) 裝載追蹤ftp協議的模塊;
# modprobe nf_conntrack_ftp
(2) 放行入站命令連接
# iptables -A INPUT -d SERVER_IP -p tcp –dport 21 -m state –state NEW,ESTABLISHED -j ACCEPT
(3) 放行入站數據連接
# iptables -A INPUT -d SERVER_IP -p tcp -m state –state RELATED,ESTABLISHED -j ACCEPT
(4) 放行出站的ESTABLISHED連接
# iptabls -A OUTPUT -s SERVER_IP -m state –state ESTABLISHED -j ACCEPT
擴展target:
REJECT:
–reject-with type
Icmp-net-unreachable,icmp-host-unreachable,icmp-port-unreachable,
Icmp-proto-unreachable,icmp-net-prohibited,icmp-host-prohibited,or
Icmp-admin-prohibited,默認為icmp-port-unreachable
LOG:
Turn on kernel logging of matching packets.
–log-level level
–log-prefix prefix:日志信息的前導信息;
保存和載入規則
保存:iptables-save > /PATH/TO/SOME_RULE_FILE
重載:iptables-restore < /PATH/FROM/SOME_RULE-file
-n,–noflush:不清除原有規則
-t,–test:僅分析生成規則集,但不予提交;
Centos 6
保存:servicce iptables save
保存規則于:Iptables-save > /path/to/iptables,保存操作會清除文件中原有的內容;
重載:service iptables restart
默認重載/etc/sysconfig/iptables文件中的規則
腳本配置文件 /etc/sysconfig/iptables-config
用于指明要裝載的模塊
Centos 7開機自動生效規則
(1)firewalld服務;
(2)Shell腳本,直接記錄iptables命令;
(3)自定義unit file 或init script;
規則優化的思路:
(1) 優先放行雙方向狀態為ESTABLISHED的報文;
(2) 服務于不同類別的功能的規則,匹配到報文可能性更大的放前面;
(3) 服務于同一類別的功能的規則,匹配條件較為嚴格的放前面;
(4) 設置默認策略:白名單機制
(a) 可使用iptables -P設定默認策略;
(b) 建議在規則鏈的最后定義規則做為默認策略;
練習:基于狀態放行telnet, ftp, ssh, http, samba, icmp等服務;
(1) 對本機的ping請求每分鐘不得超出20個;
(2) 每客戶端對本機的ssh的并發連接數不得超過3個;
(3) 本機的telnet服務僅允許工作時間內訪問;
#iptables -I INPUT -d 172.16.80.72 -p tcp –dport 22 -m connlimit –connlimit-above 3 -j DROP
#iptables -I INPUT -d 172.16.80.72 -p icmp –icmp-type 8 -m limit –limit-burst 20 –limit 20/minute -j ACCEPT
#iptables -I INPUT -d 172.16.80.72 -p tcp -m multiport –dports 20,21,22,45,80 -j ACCEPT
#iptables -I INPUT -d 172.16.80.72 -P tcp –dport 23 -m time –weekdays 1,2,3,4,5 -j ACCEPT
#iptabels -A INPUT -d 172.16.80.82 -j DROP
五nat詳解
iptables/netfilter網絡防火墻:
(1) 網關;
(2) filter表的FORWARD鏈;
要注意的問題:
(1) 請求–響應報文均會經由FORWARD鏈,要注意規則的方向性;
(2) 如果要啟用conntrack機制,建議將雙方向的狀態為ESTABLISHED的報文直接報文;
NAT: Network Address Translation
地址轉換協議
請求報文:由管理員進行定義;
響應報文:由NAT的conntrack機制自動實現;
改源地址:SNAT //源地址轉換
目標地址不變,重新改寫源地址,并在本機建立NAT表項,當數據返回時,根據NAT表將目的地址數據改寫為數據發送出去時候的源地址,并發送給主機
目前大多都是解決內網用戶同一個公網地址上網的情況;
改目標地址:DNAT //目標地址轉換
和SNAT相反,源地址不變,重新修改目標數據,在本機建立NAT表項,當書記返回時,根據NAT表將源地址修改為數據發送過來的目標地址,并發送給遠程主機;
在DNAT的基礎上,可以根據請求數據包的端口做PNAT(端口轉換,也成為端口映射),可以將請求數據包不同的端口改寫不同的目標地址,從而發送給不同的主機;
這在用一個公網地址做不同服務時用的比較多,而且相對來說,用NAT的方式可以隱藏后端服務器的真實地址,更加的安全
Iptables/netfilter:
NAT定義在nat表:
PREROUTING,INPUT,OUTPUT,POSTROUTING;
SNAT:POSTROUTING
DNAT:PREROUTING
在nat模型里,完成nat的實現,要經過prerouting—-forward—–postrouting這三個鏈
分析SNAT的數據流向:
首先進入prerouting,發現不是本網段的地址,而后開始查找路由表(查找路由的過程在prerouting和forward之間),于是經過forward鏈進行轉發,在通過postrouting時進行NAT轉換。
在這個流程中,NAT轉換的步驟在POSTROUTING鏈上實現,之所以不在prerouting上做nat是因為數據包在進來之前,還不知道是本網段地址還是外網地址;
再分析DNAT的數據流向過程
在DNAT中,NAT要在prerouting鏈上做。之前提到過,在數據進入主機后,路由選擇過程是在prerouting和forword之間的,所以應該先做地址轉換之后,再進行路由選擇,而后經過forword,最后從postrouting出去
在做nat之前,需要打開forward
[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
SNAT
添加nat表項
[root@localhost ~]# iptables -t nat -A POSTROUTING -s 172.16.93.0/24 -j SNAT –to-source 10.0.0.1
表示在postrouting鏈上,將源地址為172.16.93.0/24網段的數據包的源地址都轉換為10.0.0.1
iptables -t nat -A POSTROUTING -s 172.16.93.0/24 -o eth1 -j MASQUEREADE //一般用在目標地址不確定
在DNAT中,要把規則定義在PREROUTING鏈中
iptables -t nat -A PREROUTING -d 10.0.0.1 -j DNAT –-to-destination 172.16.93.1
此條規則將請求IP為10.0.0.1的數據包轉發到后端172.16.93.1主機上
原創文章,作者:guo_ruillin,如若轉載,請注明出處:http://www.www58058.com/66625