上次給大家分享過一個(gè)封IP腳本,點(diǎn)這里看。我搞那個(gè)腳本的目的是為了把訪問量太大的IP地址給封掉,然后每隔半小時(shí)解封。其實(shí),它并沒有解決問題。服務(wù)器CPU使用率還是跟之前一樣,非常有規(guī)律。
經(jīng)過幾天的觀察和日志分析,得出一個(gè)結(jié)論,大概率是最近服務(wù)器上來采集數(shù)據(jù)的量比之前大了,畢竟近期AI很熱,好多組織在搞大模型,采集數(shù)據(jù)是根本。
這些人就有點(diǎn)不道德了,又不是不讓你采集,你再把頻率降低一些,分散一些,只要不影響到我們的業(yè)務(wù),就沒人管你,但你現(xiàn)在把我們的服務(wù)器給拖垮了,影響到客戶訪問和使用,這樣誰都不好不是。
分析過程中,也找到了一些規(guī)律,有一些IP是一個(gè)IP段,很分散,所以單個(gè)IP訪問量并不大,但是整個(gè)IP段就非常明顯了。
所以,我想了想,決定把腳本改造一下,針對(duì)IP段來進(jìn)行分析并封IP。思路是:分析過去1小時(shí)的訪問日志,然后把訪問日志中的IP截取出來,取IP的前三個(gè)數(shù)字,只要這三個(gè)數(shù)字一樣的IP都算一個(gè),這樣再計(jì)算總次數(shù)。把總次數(shù)超過1600次的IP段給找出來。此時(shí)可不能直接封IP段,因?yàn)闀?huì)誤傷,所以還需要根據(jù)IP段,再去過濾出中招的IP地址,針對(duì)這些IP地址再去封掉。而解封則每隔2小時(shí)來一次。
腳本如下,關(guān)鍵步驟是有注釋的。
#! /bin/bash ## 把訪問量比較大的IP段封掉,如果2小時(shí)內(nèi)被封的IP沒有請(qǐng)求或者請(qǐng)求很少,需要解封 ## 作者:阿銘 ## 日期:2023-05-27 ## 版本:v1.1 #定義1小時(shí)以前的時(shí)間,用于過濾1小時(shí)以前的日志 t1=`date -d "-1 hour" +%Y:%H:` log=/data/logs/nginx/access.log block_ip() { ##白名單ip/ip段,自己的IP,正經(jīng)蜘蛛的IP w_ip="^66.249.|^220.181.|^116.179." ##截取一小時(shí)以前的日志 egrep"$t1[0-5][0-9]:"$log>/tmp/tmp_last_hour.log ##將所有ip都過濾出來,存到臨時(shí)文件 awk '{print $1}' /tmp/tmp_last_hour.log > /tmp/tmp_last_hour_ip.log ##處理IP,只留前面三位,排序、去重,獲取多于1600次請(qǐng)求的ip段,這個(gè)數(shù)字可以根據(jù)實(shí)際情況來調(diào)整 awk -F '.' '{print $1"."$2"."$3"."}' /tmp/tmp_last_hour_ip.log|sort |uniq -c |sort -n |awk '$1 > 1600 {print $2}' > /tmp/bad_ip_hour.list #當(dāng)ip數(shù)大于0時(shí),才會(huì)用iptables封掉它 ip_n=`wc -l /tmp/bad_ip_hour.list|awk '{print $1}'` if [ ${ip_n} -ne 0 ] then for ip in `cat /tmp/bad_ip_hour.list` do #封ip,不能直接封ip段 for ip2 in `grep "^$ip" /tmp/tmp_last_hour_ip.log|sort -n|uniq` do /usr/sbin/iptables -I INPUT -s $ip2 -j REJECT done done #將這些被封的IP記錄到日志里 echo "`date` 封掉的IP段有:" >> /tmp/block_ip2.log cat /tmp/bad_ip_hour.list >> /tmp/block_ip2.log fi } unblock_ip() { #首先將包個(gè)數(shù)小于5的ip段記錄到一個(gè)臨時(shí)文件里,把它們標(biāo)記為白名單IP /usr/sbin/iptables -nvL INPUT|grep REJECT |awk '$1<5 {print $8}' > /tmp/good_ip2.list n=`wc -l /tmp/good_ip2.list|awk '{print $1}'` if [ $n -ne 0 ] then for ip in `cat /tmp/good_ip2.list` do /usr/sbin/iptables -D INPUT -s $ip -j REJECT done echo "`date` 解封的IP段有:" >> /tmp/unblock_ip2.log cat /tmp/good_ip2.list >> /tmp/unblock_ip2.log fi #當(dāng)解封完白名單IP后,將計(jì)數(shù)器清零,進(jìn)入下一個(gè)計(jì)數(shù)周期 /usr/sbin/iptables -Z } #取當(dāng)前時(shí)間的小時(shí) t=`date +%H` t2=$[$t%2] #每2小時(shí)執(zhí)行解封IP的函數(shù),其他時(shí)間只執(zhí)行封IP的函數(shù) if [ $t2 -eq 0 ] then unblock_ip block_ip else block_ip fi
上完腳本后,觀察了一天,CPU使用率終于降低到可接受范圍了。
審核編輯:劉清
-
cpu
+關(guān)注
關(guān)注
68文章
11045瀏覽量
216099 -
服務(wù)器
+關(guān)注
關(guān)注
13文章
9716瀏覽量
87355
原文標(biāo)題:?jiǎn)栴}終于解決了--封ip腳本的進(jìn)化
文章出處:【微信號(hào):aming_linux,微信公眾號(hào):阿銘linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
評(píng)論