iptables學習記錄(命令篇)

iptables學習記錄(命令篇):
1.查詢命令
iptables -t filter --line-number -vnL INPUT
-t選項:iptables的查看四張表中的一張,默認是filter表,另外還有nat表、mangle表、raw表;
INPUT爲iptables某個chain鏈,總共鏈有五種:PREROUTING、INPUT、FORWARDING、OUTPUT、POSTROUTING
2.清除命令
iptables -t filter -F INPUT  //清除filter表的INPUT鏈

3.添加規則
iptables -t filter -I INPUT -s 172.16.4.248 -j DROP --line-number
-I:insert 
-s:source源
-j:jump跳轉。跳轉到規則匹配上的行爲,即DROP
--line-number:打印出該規則對應的條目num,如下:
[root@localhost mcptt_1]# iptables -t filter -nvL INPUT --line-number
Chain INPUT (policy ACCEPT 5081 packets, 730K bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       86  7224 DROP       all  --  *      *       172.16.4.248         0.0.0.0/0

從172.16.4.248ping172.16.6.231,ping不通報文被丟棄。

再增加一條規則:
iptables -t filter -I INPUT -s 172.16.4.248 -j ACCEPTiptables -t filter -I INPUT -s 172.16.4.248 -j ACCEPT
[root@localhost mcptt_1]# iptables -t filter -nvL INPUT --line-number
Chain INPUT (policy ACCEPT 547 packets, 76514 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     all  --  *      *       172.16.4.248         0.0.0.0/0           
2       86  7224 DROP       all  --  *      *       172.16.4.248         0.0.0.0/0 

發現對同一個過濾規則執行了不同的動作,後增加的順序會插入到之前增加的排列到第一條。即num=1;
此時發現在172.16.4.248上可以ping通172.16.6.231,說明相同的規則不同的執行動作,num排列在前面的先匹配到並執行動作,排列在後面的規則對應的動作執行無效。

4.修改規則
A.-I選項
iptables -t filter -I INPUT 2 -s 172.16.4.248 -j REJECT
-I INPUT 2:數字2表示對num爲2的規則作修改並重新插入,這次修改後,num=2的命令規則立即變成num=1,排列在第一列優先匹配並執行。
            -I INPUT 2,注意:如果使用-I INPUT 1,只會重新插入一條記錄,而原有num=1的記錄變成num=2。
DROP:報文直接丟棄
ACCEPT:報文放行
REJECT:報文拒絕並回應
B.-R選項(replace)
  使用-R選項只能修改執行的動作,而且都要把num號和匹配規則寫全了,不能默認。
  iptables -t filter -R INPUT 1 -s 172.16.4.248 -j DROP
  
5.刪除規則
A.根據num來刪除
iptables -t filter -D INPUT 6
-D:刪除num=6的條目,filter表中INPUT鏈第6個條目

B.根據匹配項來刪除
iptables -t filter -D INPUT -s 172.16.4.248 -j REJECT

C.刪除所有
iptables -t filter -F INPUT

6.修改默認行爲
iptables -t filter -I INPUT -j ACCEPT
修改表filter 的INPUT鏈默認行爲爲ACCEPT

7.多個規則用","隔開
iptables -t filter -I INPUT 2 -i eth0 -s 172.16.4.248,172.16.5.246 -d 172.16.6.231 -p tcp -j REJECT
-i:表示入以太網卡,因爲-I是判斷從哪個網卡流入匹配項的,所以只能使用在PREROUTING\INPUT\FORWARDING狀態,不能使用在OUTPUT/POSTROUTING狀態,個人理解:因爲OUTPUT和POSTROUTING階段入口處理流程已經結束了,所以沒有知道入網口。
    請查閱iptables數據流圖
-O:表示出以太網卡,因爲在PREROUTING\INPUT\FORWARD階段處理的是入數據,還不知道出口數據流程,譬如目的地址下一條查找之類的,下一跳數據封裝等都沒有進行,所以沒法處理出以太網卡匹配。
總結:FORWARD階段都可以使用-I  -O 入出以太網卡匹配,是因爲FORWARD階段即處理了入口數據又替換封裝了出口數據過程。

8.擴展屬性:端口號過濾
  iptables -t filter -I INPUT -s 172.16.4.248 -d 172.16.5.246 -p tcp -m tcp --dport 22 --sport 5059 -j ACCEPT
  端口號過濾:必須制定協議屬性,如:-p tcp
              -m tcp:-m表示是tcp的擴展屬性
              --sport
              --dport:表示端口匹配規則
 -p tcp和-m tcp並不衝突,-p tcp表示協議類型爲tcp,-m tcp表示擴展模塊的名稱爲tcp,該tcp模塊中的端口號爲22和5059過濾規則。
 問題:
 iptables -t filter -I INPUT -p tcp -m tcp --dport 2323 -j DROP
 A.如果刪除-p tcp該匹配會生效嗎?
 iptables -t filter -I INPUT -m tcp --dport 2323 -j DROP
 刪除-p tcp後該命令執行提示格式錯誤!
 B.如何刪除-m tcp端口號能生效嗎?
iptables -t filter -I INPUT -p tcp --dport 2323 -j DROP 
刪除-m tcp後命令執行成功,且能成功匹配到規則且DROP生效。該-m tcp命令且不是多餘的嗎?(遺留問題)

8.1指定多個連續端口
 iptables -t filter -I INPUT -p tcp -m tcp --dport 2323:2400 -j DROP
 2323:2400指定端口範圍
 iptables -t filter -I INPUT -p tcp -m tcp --dport 2323: -j DROP
2323: 表示2323端口以上的範圍
 iptables -t filter -I INPUT -p tcp -m tcp --dport :2323 -j DROP
 :2323 表示0到2323端口的範圍
 
8.2指定多個離散不連續端口
iptables -t filter -I INPUT -p tcp -m multiport --dport 1000,2000:2323 -j DROP
1000,2000:2323 指定1000端口號以及2000:2323範圍內的端口

8.3 ip range擴展模塊
iptables -t filter -I INPUT -p tcp -m iprange --src-range 172.16.4.240-172.16.5.246 --dst-range 172.16.4.240-172.16.5.246 -m multiport --dport 1000,2000:2323 -j DROP
-m iprange:多個IP匹配範圍
--src-range:源IP匹配範圍
--dst-range:目的IP匹配範圍

8.4 string擴展匹配報文內容字符串
iptables -t filter -I INPUT -m string --algo bm --string "hello world" -j DROP
-m string:擴展屬性爲字符串
--algo bm:選擇算法,算法內容爲bm
--string "hello world":表示匹配字符串內容爲"hello world"

8.5 time擴展模塊
ptables -t filter -I INPUT -s 172.16.5.246 -d 172.16.5.246 -m time --timestart 02:00:00 --timestop 22:00:00 -j DROP
在測試機器上發現不生效,172.16.5.246自己ping自己還是可以ping通,後來發現linux本身的系統時間不是24小時格式的,修改命令如下:
iptables -t filter -I INPUT -s 172.16.5.246 -d 172.16.5.246 -m time --timestart 02:00:00 --timestop 09:00:00 -j DROP,命令生效.
iptables -t filter -I INPUT -s 172.16.5.246 -d 172.16.5.246 -m time --weekdays 5 -j DROP
iptables -t filter -I INPUT -s 172.16.5.246 -d 172.16.5.246 -m time --monthdays 8,9,10,11 -j DROP
iptables -t filter -I INPUT -s 172.16.5.246 -d 172.16.5.246 -m time --datestart 2019-11-5 --datestop 2019-11-10 -j DROP

8.6 connlimit擴展模塊
iptables -t filter -I INPUT -s 172.16.4.239 -d 172.16.5.246 -p tcp --dport 22 -m connlimit --connlimit-above 4 -j DROP
-m commlimit:擴展模塊限制連接數
--connlimit-above 4:上限是4個連接數
//但該測試命令鏈接上限並沒有生效,待進一步查明原因
//該命令表示每個客戶端ssh時查看匹配是否達到上限,之所以沒生效是secureCRT的原因,我們改下命令:
iptables -t filter -I INPUT -s 172.16.4.239 -d 172.16.5.246 -p tcp --dport 22 -m connlimit --connlimit-above 0 -j DROP
//命令限制爲0個,已存在的多少個鏈接無法匹配,但後面新增的鏈接無法ssh,即使使用secureCRT軟件都不行,命令生效!
 之前存在的鏈接在保活時間到以後會給目的主機發送溝通報文,由於匹配到規則連接數最大上限是0,所以secureCRT在發保活報文時保活報文被丟棄,已有的鏈接超時失效。

8.7 limit擴展模塊
iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT//每6秒鐘放行一次
[root@localhost ~]# iptables -t filter --line-number -vnL INPUT                             
Chain INPUT (policy ACCEPT 40 packets, 6402 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            limit: avg 10/min burst 5

首先發現ping包似乎沒生效,因爲該規則是起了一個定時器每6秒鐘到就匹配報文一次,那麼6秒內定時器未超時即不會匹配該規則,那麼其餘的規則都是默認規則,默認規則即是放行ACCEPT,所以感覺是沒生效,
其實應該是每到6秒規則生效了,只不過每次生效同樣是放行5個令牌桶,肉眼分辨不出來。如果修改成默認行爲爲DROP,即能分辨出來。命令修改成:
iptables -t filter -I INPUT -s 172.16.4.248 -d 172.16.5.246 -p icmp -j REJECT //指定特殊源和目的地址的icmp默認行爲爲REJECT
在測試ping包符合預期。
查看命令:
[root@localhost ~]# iptables -t filter --line-number -vnL INPUT
Chain INPUT (policy ACCEPT 45 packets, 4636 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       25  2100 ACCEPT     icmp --  *      *       172.16.4.248         172.16.5.246         limit: avg 10/min burst 5
2      175 14700 REJECT     icmp --  *      *       172.16.4.248         172.16.5.246         reject-with icmp-port-unreachable

同樣的規則爲什麼執行完了1之後又執行2了呢,我們之前講過的,同樣的匹配條件不同的執行動作只會執行排在前面的,排在後面的不會被執行。
其實上面表面上看的是1和2的匹配條件都執行了,其實是執行了其中一個。1中只有6秒定時器到的時候才執行的,所以執行1的時候其實2沒執行,所以報文才能行出去。
而條目2,是在1的6秒定時器執行的,因爲6秒定時器未到,1其實是不匹配報文的。

關於burst 5(限速令牌桶):
這個是限速產生的默認值令牌桶,該桶裏默認5個通行令牌。
由於是隔了6秒鐘,定時器一到,就有5個報文,每個報文拿了一個令牌,總共5個令牌拿光了其他報文就無法通行,所以每次定時器到6秒時正好桶裏有5個令牌,所以只能通過5個報文。
但真正在網絡,並不一定是5個報文通過,因爲令牌被通行的報文取走,只有該通行報文釋放令牌後才能被其他報文獲取。
修改下burst令牌個數:
iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute --limit-burst 1 -j ACCEPT//修改成桶裏只有一個通行令牌

8.8 "--tcp-flags" 匹配tcp頭部flag字段
  iptables -t filter -I INPUT -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH(前六個標識tcp頭部中的所有flag) SYN(該字段表示需要匹配的頭部flag)-j REJECT 
  iptables -t filter -I INPUT -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH(前六個標識tcp頭部中的所有flag) SYN,ACK(該字段表示需要匹配的頭部flag爲SYN,ACK)-j REJECT 
  還可以寫成:
  iptables -t filter -I INPUT -m tcp --dport 22 --tcp-flags ALL(前六個標識tcp頭部中的所有flag) SYN,ACK(該字段表示需要匹配的頭部flag爲SYN,ACK)-j REJECT 
  還可以寫成:
  iptables -t filter -I INPUT -m tcp --dport 22 --syn SYN,ACK(該字段表示需要匹配的頭部flag爲SYN,ACK)-j REJECT 
  
8.9 UDP擴展匹配
 iptables -t filter -I INPUT -p udp -m udp --dport 5000:6000 -j DROP
 
8.10 ICMP擴展匹配
   iptables -t filter -I INPUT -s 172.16.4.248 -p icmp -m icmp --icmp-type 8/0 -j DROP
   --icmp-type 8/0:表示擴展屬性爲icmp,8/0表示icmp類型爲8的請求消息,0表示請求消息的code碼爲0
   
8.11 根據報文狀態來擴展匹配
172.16.5.246上配置:
iptables -t filter -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -I INPUT -m state --state NEW,INVALID,UNTRACKED -j DROP
根據ping包結果,172.16.4.248 ping向5.246無法ping通,但5.246ping向4.248可以ping通。因爲5.246發出去的報文再次收到迴應報文,有過第一次發包,報文爲RELATED狀態,再次收到就是ESTABLISHED狀態。
而4.248ping向5.246之所以ping不通,是因爲4.248ping的第一個包在5.246上就找不到任何狀態,即爲NEW狀態,而該狀態被設置爲DROP。
我們在5.246上修改下命令:
iptables -t filter -I INPUT -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
iptables -t filter -I INPUT -m state --state INVALID,UNTRACKED -j DROP
修改命令後,左右報文都可以ping通。

NEW狀態:可以理解爲第一個包,記錄NEW狀態;
ESTABLISHED狀態:可以理解爲NEW狀態下收到的第二個包,或本地迴應NEW狀態的第一個報文之後達到ESTABLISHED狀態;
RELATED狀態:譬如FTP的數據控制通道(即命令通道)和數據轉發通道(傳輸通道),即可看做RELATED狀態。
INVALID狀態:一個報文沒有辦法被識別
UNTRACKED狀態:表示該報文未被追蹤,該狀態時正常無法找到相關鏈接。


8.12 擴展屬性自定義鏈
自定義鏈一定是通過原有鏈中缺省行爲來調用執行的(譬如原有INPUT\FORWARDING\OUTPUT鏈)
譬如自定義一個鏈名稱爲ZHUWEI_TEST
iptables -t filter -N ZHUWEI_TEST //在filter表中創建一個ZHUWEI_TEST鏈,名稱爲ZHUWEI_TEST
iptables -t filter -I ZHUWEI_TEST -s 172.16.4.248 -d 172.16.5.246 -j DROP //在自定義鏈ZHUWEI_TEST中增加匹配規則和行爲
//此時從4.248ping5.246還是可以ping通,發現雖然定義了自定義鏈ZHUWEI_TEST和鏈中的匹配規則和行爲,但如何讓報文走到自定義鏈中呢。
  需要把ZHUWEI_TEST自定義鏈作爲執行的行爲放入到缺省鏈中來調用。如下:

iptables -t filter -I INPUT -j ZHUWEI_TEST //即把ZHUWEI_TEST作爲行爲放入到INPUT鏈中作爲行爲來調用(此時把ZHUWEI_TEST看做和ACCEPT\REJECT\DROP同等平行的東西)
再次從4.248 ping 5.246發現ping不通,規則生效。
理解爲:
報文過來發現filter表中INPUT鏈沒有任何符合的匹配規則,
該報文走缺省行爲執行動作,在走缺省行爲時發現缺省行爲中還掛着ZHUWEI_TEST鏈,該報文繼續匹配ZHUWEI_TEST鏈中的規則,匹配上後走DROP.
若ZHUWEI_TEST中的規則也匹配不上該報文,該報文繼續執行INPUT中的缺省動作ACCEPT。
報文匹配規則如下:(以filter表INPUT鏈爲例)INPUT鏈中非自定義鏈規則匹配--->缺省行爲中的自定義鏈匹配---->缺省行爲

其他相關命令:
iptables -t filter -E ZHUWEI_TEST ZHUWEI_TEST_RENAME //自定義鏈重命名
刪除三步走:iptables -t filter -D INPUT 1//刪除自定義鏈在INPUT中的引用,方式雷同其他直接匹配規則
            iptables -t filter -F ZHUWEI_TEST_RENAME //刪除自定義鏈中所有匹配項
            iptables -t filter -X ZHUWEI_TEST_RENAME //刪除自定義鏈

其他思考:自定義鏈既然和其他正常的匹配規則一樣存放在INPUT鏈中,那是否排列在INPUT表的最前面就優先匹配呢,動手實驗一下:
iptables -t filter -I INPUT -s 172.16.4.248 -d 172.16.5.246 -p icmp -j ACCEPT//增加一條和ZHUWEI_TEST完全一樣的匹配規則,只是執行結果不一致。
[root@localhost ~]# iptables -t filter -I INPUT -s 172.16.4.248 -d 172.16.5.246 -p icmp -j ACCEPT
[root@localhost ~]# iptables -t filter --line-number -nvL 
Chain INPUT (policy ACCEPT 40 packets, 6356 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        2   168 ACCEPT     icmp --  *      *       172.16.4.248         172.16.5.246        
2     9282 1300K ZHUWEI_TEST_RENAME  all  --  *      *       0.0.0.0/0            0.0.0.0/0  

此時發現報文可以ping通,這個不能說明問題,我們把順序調整一下。
[root@localhost ~]# iptables -t filter -D INPUT 2
[root@localhost ~]# iptables -t filter -I INPUT -j ZHUWEI_TEST_RENAME
[root@localhost ~]# iptables -t filter --line-number -nvL 
Chain INPUT (policy ACCEPT 28 packets, 4428 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       30  4596 ZHUWEI_TEST_RENAME  all  --  *      *       0.0.0.0/0            0.0.0.0/0     //自定義鏈排在第一位,並沒有優先匹配      
2      183 15372 ACCEPT     icmp --  *      *       172.16.4.248         172.16.5.246        

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 19 packets, 3966 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain ZHUWEI (0 references)
num   pkts bytes target     prot opt in     out     source               destination         

Chain ZHUWEI_TEST_RENAME (1 references)
num   pkts bytes target     prot opt in     out     source               destination  
此時報文仍然可以ping通,說明自定義鏈確實是在其他所有非定義鏈規則沒有匹配項目之後纔去考慮匹配的。再次思考下,假如有多個自定義鏈,這些自定義鏈之中的規則是不是遵從順序優先級呢
動手實驗一下:再次增加一個完全匹配的自定義鏈,行爲爲REJECT,且在自定義鏈中順序優先級高,理論上應該先匹配到。(!!!經過實驗不完全是這樣,需要看代碼確認)

綜合:
(以filter表INPUT鏈爲例)INPUT鏈中非自定義鏈規則匹配(按照num從1--->6--->...的順序優先級爲高--->次高--->...--->低進行匹配)--->缺省行爲中的自定義鏈匹配(按照num從1--->6--->...的順序優先級爲高--->次高--->...--->低進行匹配)---->缺省行爲


8.13黑白名單
缺省行爲爲ACCEPT,然後匹配規則裏增加DROP/REJECT的行爲爲黑名單
iptables -t filter -P INPUT ACCEPT
缺省行爲爲DROP/REJECT,然後匹配規則裏增加ACCEPT的行爲爲白名單
iptables -t filter -P INPUT DROP/REJECT
黑白名單綜合應用:
iptables -t filter -P INPUT ACCEPT
iptables -t filter -I INPUT -s 172.16.4.248 -d 172.16.5.246 -j ACCEPT
iptables -t filter A INPUT -j REJECT/DROP //在原有通行報文的基礎上拒絕/丟棄其他所有報文,即在白名單的基礎上應用了黑名單


8.14 iptables作爲防火牆使用
防火牆的作用是過濾和轉發功能,過濾做在filter表,FORWARD階段中存在filter表又具備轉發功能,防火牆坐在這個階段比較合適。
linux默認是關閉轉發功能的,需要先打開轉發(臨時生效):
echo 1 > /proc/sys/net/ipv4/ip_forward
sysctl -w net.ipv4.ip_forward=1
永久生效:
vim /etc/sysctl.conf  
net.ipv4.ip_forward = 1

8.15 iptables動作日誌記錄
自定義日誌文件:
vim /etc/rsyslog.conf 
kern.warning /var/log/iptables.log
重啓log服務

iptables -t filter -I INPUT -s 172.16.4.248 -d 172.16.5.246 -p icmp -j LOG


9.取反操作
iptables -t filter -I INPUT 2 -s !172.16.4.248 -d 172.16.6.231 -p tcp -j REJECT
!:表示非172.16.4.248源地址發往172.16.6.231上的tcp協議報文采用拒絕且迴應的方式,
  注意:規則只定義了非172.16.4.248,但172.16.4.248發往172.16.6.231的報文依然能夠通過,
        因爲匹配時並沒有找到源172.16.4.248發往172.16.5.246的匹配規則,所以只能走默認放行的規則。假如表filter的INPUT鏈默認規則是放行的話。

        
10.匹配規則之常用動作
    ACCEPT\DROP\REJECT\LOG\SNAT\DNAT\MASQUERADE\REDIRECT
    //公網訪問局域網的MYSQL數據庫服務器
    公網區域PC1(eth1:10.42.188.2)---------(公網ETH1:10.42.205.221)PC2(局域網ETH2:172.16.4.250)-----------(ETH1:172.16.4.248)PC3(局域網MYSQL服務器)
    PC2上起iptables功能即充當防火牆
    
    
    iptables -t nat -I PREROUTING -d 10.42.205.221 -p tcp --dport 3306 -j DNAT --to-destination 172.16.4.248:3306
    //公網訪問局域網的數據目的地址和端口號轉換成MYSQL服務器地址和端口號,因爲是目的報文的目的地址要替換所以要做在報文剛進來的PREROUTING階段
    iptables -t nat -I POSTROUTING -s 172.16.4.0/24 -j SNAT --to-source 10.42.205.221
    //即迴應報文需要修改原地址爲防火牆地址,所以要坐在POSTROUTING即出口最後一關卡階段(也可以坐在OUTPUT階段,各位自己試驗)
    
    
    若上訴組網中,PC2局域網採用撥號上網的話,PC2的ETH1公網地址會經常發生變化,這樣使用SNAT或DNAT就很不方便,由此引入MASQUERADE動作
    iptables -t nat -I POSTROUTING -s 172.16.4.0/24 -o ETH1 -j MASQUERADE  //表示每次匹配上以後都會取ETH1上可用的公網IP地址做替換,除了有這種動態IP場景,否則沒必要使用MASQUERADE
    
    
    //使用REDIRECT進行端口重映射,只能坐在PREROUTING\OUTPUT階段
    iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080 //將80端口重新映射成8080端口
    
    
    
        
11.保存配置
service iptables save
文件保存在/etc/sysconfig/iptables文件中,centos7版本中默認使用firewall,需要yum install -y iptables-services

12.總結篇之常用套路

 A.順序的重要性,放在前面的先匹配,全完一致的規則也是前面的匹配到執行對應的動作,後面完全一樣的規則匹配不到。但前面是-j LOG除外。
 B.在沒有強行順序要求的前提下,儘量是匹配報文流量大的放前面,這樣能夠節約性能。譬如每小時匹配到2000的報文放前面,每小時匹配到1000的報文規則在後面。
 

 

 

 

參考資料:來源於互聯網

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章