iptables-ipset模組
利用 ipset 封禁大量 IP
環境:CentOS7.4 自帶6.29 版本(目前全球伺服器廠商普遍使用的CentOS 最高版本為 7.4)
用途:當機器受到網路***時,使用 iptables 封 IP,有時候可能會封禁成千上萬個 IP,如果新增成千上萬條規則,在一臺注重效能的伺服器或者本身效能就很差的裝置上就不在適用了。ipset 就是為了避免這個問題而生的。
基本流程:
ipset create test hash:ip
iptables -I INPUT -m set --match-set test src -j DROP
ipset add test 192.168.80.100
ipset add test 192.168.80.101
ipset add test ...
ipset list test # 檢視 test 集合的內容
第一步:新建ipset 集合
第二歩:新增iptables 規則
第三步:向ipset中新增ip
建立集合
ipset n,create [ SETNAME ] [ TYPENAME ] [ CREATE-OPTIONS ]
SETNAME:即所建立集合的名字
TYPENAME:即型別名字,用型別來儲存ip
CREATE-OPTIONS:即建立選項,
注意:
TYPENAME相關型別有:bitmap link hash
其中bitmap link 的儲存方式的集合大小是固定,hash型別的儲存大小是可變的(後面會解釋的)
CREATE-OPTIONS相關型別有:ip, net, mac, port, iface
即除了ip外,還可以是網路段,埠號(支援指定 TCP/UDP 協議),mac 地址,網路介面名稱,或者多種。
新增iptables 規則
在iptables中可以使用 -m set啟用ipset模組
iptables -I INPUT -m set --match-set test src -j DROP
iptables -I INPUT -m set ! --match-set file src -j DROP
如果源地址(src)屬於 test 這個集合,就進行 DROP 操作。這條命令中,test 是作為黑名單的,如果要把某個集合作為白名單,新增一個 ‘!’ 符號就可以。
向集合中新增記錄
inset add [ SETNAME ] [ ADD-ENTRY ] [ ADD-OPTIONS ]
SETNAME:即所要新增ip的集合名字
ADD-ENTRY:所要新增的ip或含埠號等其他型別
ADD-OPTIONS:新增ip時的其他條件(後面會解釋的)
ipset add test 4.5.6.7
注意:可以同過以下方法找到需要封禁的ip
netstat -ntu | tail -n +3 | awk '{print $5}' | sort | uniq -c | sort -nr
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr
注意:如果建立集合是指定的儲存內容包含 ip, 例如 hash:ip 或 hash:ip,port ,在新增記錄時,可以填 IP 段,但是仍然是以單獨一個個 IP 的方式來儲存的
刪除
刪除集合內的ip
inset del SETNAME DEL-ENTRY
參考新增的解釋
ipset del test 192.168.80.100 # 從 test 集合中刪除內容
刪除集合
ipset destroy test # 刪除 test 集合
ipset destroy # 刪除所有集合
注意:在刪除集合時,如果該集合被iptables規則已經引用,則需先刪除集合所在的規則,在刪除集合,如果集中存在ip並不會影響刪除集合
儲存型別
hash:net
hash:net 指定了可以往file 這個集合裡新增 IP 段或 IP 地址。
ipset create file hash:net
ipset add file 192.168.80.0/24
ipset add file 192.168.80.0/30 nomatch
ipset add file 192.168.80.9
ipset test file 192.168.80.2
第一條命令:建立hash:net集合
第二條命令:新增192.168.80.0/24該ip段的範圍
第三條命令:新增192.168.80.0/30該ip段的範圍,nomatch 是之前提到的[ ADD-OPTIONS ],就是新增某ip的附加條件
作用:是把 192.168.80.0/30 從 192.168.80.0/24 這一範圍相對更大的IP段裡“剝離”出來
也就是說執行完 ipset add file 192.168.80.0/24 之後,192.168.80.0/24 這一段 IP 是屬於file 集合的,接著又執行了 ipset add file 192.168.80.0/30 nomatch 之後,192.168.80.0/24 裡包含著的 192.168.80.0/30 這部分,就不屬於file 集合了。執行 ipset test file 192.168.80.2 就會得到結果 192.168.80.2 is NOT in set file,即表示該ip不屬於file集合了
注意:如下圖所示,即使結果出現了192.168.80.2 is NOT in set file,但還是可以新增到file集合中的,所以在新增IP段的時候,要清楚IP段所表示的範圍
hash:ip,port
ipset create pro hash:ip,port
ipset add pro 192.168.80.106,80
ipset add pro 192.168.80.108,udp:53
ipset add pro 192.168.80.104,80-86
第一條:建立 hash:ip,port 集合
第二條:新增 IP 地址為192.168.80.106埠號為80的記錄,沒有註明協議,默為TCP協議
第三條:註明協議為UDP協議
第四條:註明了IP地址和一個埠號範圍,這也是合法的命令
需要注意的是,前面有說過的:如果建立集合是指定的儲存內容包含 ip, 例如 hash:ip 或 hash:ip,port ,在新增記錄時,可以填 IP 段,但是仍然是以單獨一個個 IP 的方式來儲存的
解封
建立
如果一個集合是作為黑名單使用,可以通過timeout引數,實現到期自動從黑名單裡刪除記錄
ipset create time hash:ip timeout 300
ipset add time 192.168.80.103
ipset add time 192.168.80.105 timeout 60
第一條:建立一個含有timeout引數的time集合,預設值為1000s
第二條:在新增IP時不加timeout引數時,預設timeout 時間就時1000s
第三條:向集合新增IP 時指定了不同於預設值的 timeout 數值 100,那麼這一條記錄就會在100s後自動刪除
當我們再次檢視time集合時,可以看到時間在倒計時,標誌著它們在多少秒之後會被刪除
修改
如果要重新為某條記錄指定 timeout 引數,可以使用 -exit 引數
ipset -exist add time 192.168.80.103 timeout 500
這樣192.168.80.103 這一條資料的timeout 值就變成了500
注意:
1. 如果在建立集合時沒有指定timeout,那麼之後新增記錄時不支援timeout 引數,但如果在集合沒有指定timeout時,在新增記錄時使用了timeout引數,會報出錯誤想
2. 如果需要預設記錄不會過期(自動刪除),又需要新增某條記錄時加timeout引數,可以在建立集合時指定timeout的值為0
如下圖所示:
ipset create err hash:ip
ipset add err 192.168.80.107 timeout 100
# 報錯資訊為:ipset v6.29: Kernel error received: Unknown error -1
hash的自增
前面說過:bitmap link 的儲存方式的集合大小是固定,hash型別的儲存大小是可變的
下面介紹下hash的兩個引數
hashsize:指定了建立集合時初始大小
maxelem:指定了集合最大儲存記錄的數量
如下圖所示:
ipset create initia hash:ip,port hashsize 4096 maxelem 1000000
ipset add initia 192.168.80.109
這樣就建立了一個 initia 集合,初始 hash 大小是 2048,如果滿了 hash 會自動擴容為之前的兩倍,最大能儲存的數量是 100000 個
注意:如果沒有指定,則hashsize的預設初始值為1024,maxelem的預設最大值為65536
其他常用命令(包括前面提到的刪除)
ipset del test x.x.x.x # 從 test 集合中刪除內容
ipset list test # 檢視 test 集合內容
ipset list # 檢視所有集合的內容
ipset flush test # 清空 test 集合
ipset flush # 清空所有集合
ipset destroy test # 銷燬 test 集合
ipset destroy # 銷燬所有集合
ipset save test # 輸出 test 集合內容到標準輸出
ipset save # 輸出所有集合內容到標準輸出
ipset restore # 根據輸入內容恢復集合內容