删掉一些二次判定(加快封禁检测,随总请求数量速度增加逐级提高/降低封禁阈值;),以及封禁IP数量统计,去重;好就好在脚本很短,也很好理解;
Cloudflare 下 Nginx 获取用户真实IP 地址
如果你正在使用Cloudflare,则需要对Nginx进行相关设置;
server
{
listen 443 ssl http2;
server_name limbopro.com ;
...
##$server 段 添加如下段落 开始
include /home/ip.blacklist.5minutes.conf; ##黑名单位置;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2c0f:f248::/32;
set_real_ip_from 2a06:98c0::/29;
real_ip_header CF-Connecting-IP;
##$server 段 添加如下段落 结束 #这些都是CF节点IP;
...
index index.html index.htm index.php default.html default.htm default.php;
...
参考 Cloudflare 下 Nginx 获取用户真实IP 地址 ;
新脚本(通俗易懂版本)
2020.12.24日更新,基于新配置的WAF;
Cloudlfare 强大的API:https://api.cloudflare.com/ ;
执行脚本如下:供参考;
#!/bin/bash
maxrequest=1 #最低封禁次数
maxtimes=1 #拉取最近N分钟的请求至临时日志
function define()
{
#引入参数环节
ori_log_path="/home/wwwlogs/limbopro.com/access.log" #原始日志存放位置
rm /home/tnt/access.log.tmp >/dev/null 2>&1; #清除拉取的日志
tmp_log_path="/home/tnt/access.log.tmp" #生成的临时日志存放位置
date_stamp=`date -d "-"$maxtimes"min" +%Y:%H:%M:%S` #引入时间范围参数
day_stamp=`date +%d` #日期
}
function gather()
{
awk -F '[/ "[]' -vnstamp="$date_stamp" -vdstamp="$day_stamp" '$7>=nstamp && $5==dstamp' ${ori_log_path} > ${tmp_log_path}; #根据时间范围从原始日志处读取并写入临时日志
log_num=`cat ${tmp_log_path} | wc -l`; #计算时间范围内的网络请求次数
}
function main()
{
define
gather
}
## 拉取日志结束
main
## 拉黑开始
date=$(env LANG=en_US.UTF-8 date "+%e/%b/%Y/%R")
error_log_path=/home/tnt/access.log.503 #503日志存储位置
> /home/tnt/access.challenge.iplist;
echocf=/home/tnt/access.challenge.iplist #Cloudflare 黑名单收集 会销毁
##从临时日志
##抓取符合503状态的日志并存入
##/home/tnt/access.log.503
rm /home/tnt/access.log.503 >/dev/null 2>&1; #清除生成的日志
# ipv4 grep -oP "(\w{1,3}\.){3}\w{1,3}.*?\s503\s(?!(.*?Googlebot|.*?bot|.*?Bot)).*" ${tmp_log_path} >> ${error_log_path}; # 从临时日志抓取符合503状态的部分日志存入 /home/tnt/access.log.503
grep -oP "((\w{1,3}\.){3}\w{1,3}|(\w{1,4}\:){7}\w{1,4}).*?\s(503|499)\s(?!(.*?Googlebot|.*?bot|.*?Bot)).*" ${tmp_log_path} >> ${error_log_path}; # 从临时日志抓取符合503状态的部分日志存入 /home/tnt/access.log.503
for ip in $(awk '{cnt[$1]++;}END{for(i in cnt){printf("%s\t%s\n", cnt[i], i);}}' ${error_log_path} | awk '{if($1>'$maxrequest') print $2}')
do echo "${ip}" >> $echocf;
done
##提交IP黑名单数据至 Cloudflare
##block, challenge, whitelist, js_challenge
##Cloudflare 配置文件
CFEMAIL="这里填写#邮箱"
CFAPIKEY="#这里填写#CF密钥"
ZONESID="这里填写#ZONESID"
IPADDR=$(</home/tnt/access.challenge.iplist)
cat /home/tnt/access.challenge.iplist;
date=$(env LANG=en_US.UTF-8 date "+%e/%b/%Y/%R")
ip_num=$(grep -c "" /home/tnt/access.challenge.iplist);
echo "$date 本次封禁IP数量为 $ip_num 个"
if [ $ip_num -lt 2 ];
then # 执行小封禁
event="恶意刷新";
blocktimes="300秒";
for IPADDR in ${IPADDR[@]}; do
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONESID/firewall/access_rules/rules" \
-H "X-Auth-Email: $CFEMAIL" \
-H "X-Auth-Key: $CFAPIKEY" \
-H "Content-Type: application/json" \
--data '{"mode":"block","configuration":{"target":"ip","value":"'$IPADDR'"},"notes":"60rates-block"}' >/dev/null 2>&1;
done
else # 否则执行大封禁
event="规模攻击";
blocktimes="每日凌晨解封";
for IPADDR in ${IPADDR[@]}; do
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONESID/firewall/access_rules/rules" \
-H "X-Auth-Email: $CFEMAIL" \
-H "X-Auth-Key: $CFAPIKEY" \
-H "Content-Type: application/json" \
--data '{"mode":"block","configuration":{"target":"ip","value":"'$IPADDR'"},"notes":"Xddos-block"}' >/dev/null 2>&1;
done
fi
提取Nginx.log日志
新建Shell脚本 /home/5minutes.log.sh,内容如下;(脚本存放位置与名字自己看着办)
#!/bin/bash
function define()
{
ori_log_path="/home/wwwlogs/limbopro.com/access.log" #你的 Nginx 日志位置!!
tmp_log_path="/home/5min.access.log" #提取最近5分钟Nginx日志
date_stamp=`date -d "-5min" +%Y:%H:%M:%S` #时间提取(5分钟内)
day_stamp=`date +%d` #日期提取
}
function gather()
{
awk -F '[/ "\[]' -vnstamp="$date_stamp" -vdstamp="$day_stamp" '$7>=nstamp && $5==dstamp' ${ori_log_path} > ${tmp_log_path};
log_num=`cat ${tmp_log_path} | wc -l`;
request_time=`awk '{print $(NF-1)}' ${tmp_log_path} | awk '{sum+=$1}END{print sum}'`;
ave_request_time=`echo | awk "{print ${request_time}/${log_num}}" `;
/home/nginx.ban.5minutes.sh; #执行封禁脚本
> /home/5min.access.log; #清除临时产生的5分钟日志
}
function output()
{
}
function main()
{
define
gather
output
}
main
我的配置参考
#!/bin/bash
function define()
{
ori_log_path="/home/wwwlogs/limbopro.com/access.log"
tmp_log_path="/home/5min_limbopro.com.access.log"
date_stamp=`date -d "-5min" +%Y:%H:%M:%S`
day_stamp=`date +%d`
}
function gather()
{
awk -F '[/ "\[]' -vnstamp="$date_stamp" -vdstamp="$day_stamp" '$7>=nstamp && $5==dstamp' ${ori_log_path} > ${tmp_log_path};
log_num=`cat ${tmp_log_path} | wc -l`;
request_time=`awk '{print $(NF-1)}' ${tmp_log_path} | awk '{sum+=$1}END{print sum}'`;
ave_request_time=`echo | awk "{print ${request_time}/${log_num}}" `;
ipcounts=$(awk '{print $1}' /home/5min_limbopro.com.access.log | sort -n | uniq | wc -l);
date=$(env LANG=en_US.UTF-8 date "+%e/%b/%Y/%R")
echo "${date}" "网站最近5分钟总请求数为 ${log_num}" 次 >> /home/5minutes.log;
echo "${date}" "网站最近5分钟总请求数为 ${ipcounts}" 个"(IP数量)" >> /home/5minutes.log;
echo " " >> /home/5minutes.log;
/home/nginx.ban.5minutes.sh;
> /home/5min_limbopro.com.access.log;
}
function output()
{
date=$(env LANG=en_US.UTF-8 date "+%e/%b/%Y/%R")
max=200000
if [ ${log_num} -gt $max ];
then
cp /home/attackcheck.ddos.sh.bak /home/attackcheck.sh
/home/attackcheck.sh;
else
cp /home/attackcheck.normal.sh.bak /home/attackcheck.sh
/home/attackcheck.sh;
fi
}
function main()
{
define
gather
output
}
main
封禁脚本
新建 Shell脚本 /home/nginx.ban.5minutes.sh,内容如下;(脚本存放位置与名字自己看着办)
#!/bin/bash
blockip=/home/ip.blacklist.5minutes.conf #黑名单位置,请把这个文件添加到 server 段下;
access=/home/5min.access.log
for ip in $(awk '{cnt[$1]++;}END{for(i in cnt){printf("%s\t%s\n", cnt[i], i);}}' ${access} | awk '{if($1>500) print $2}') #五分钟内超过500次请求则拉黑
do
echo "deny ${ip};" >> $blockip
echo "deny ${ip};" >> $ipcount
iptables -I INPUT -s ${ip} -j DROP
done
lnmp nginx reload ## nginx 重新加载配置文件
定时执行
crontab -e #命令行输入
* * * * * /home/5minutes.log.sh ##设置为1分钟执行一次
手动自定义封杀脚本
有时候遇到大规模IP请求?比如1万个代理ip,直接手动封杀即可;
脚本如下:
#!/bin/bash
## 清除缓存日志
#> /home/echo_limbopro.com.access.log
> /home/echo_limbopro.com.access.before.log;
> /home/echo_limbopro.com.access.log;
echo -n "输入需要读取的文档(默认回车):"
read iaccess # 把键盘输入放入变量access
## 赋值到最大日志读取时间并读取日志
echo -n "输入日志最大的读取范围(分钟内):" # 参数-n的作用是不换行,echo默认换行
read imaxtime # 把键盘输入放入变量maxtime
function define()
{
ori_log_path="/home/wwwlogs/limbopro.com/access."${iaccess}"log" #按实际位置进行修改
tmp_log_path="/home/echo_limbopro.com.access.log" #提取的临时日志位置及名字
date_stamp=`date -d "-"${imaxtime}"min" +%Y:%H:%M:%S`
day_stamp=`date +%d`
}
function gather()
{
awk -F '[/ "\[]' -vnstamp="$date_stamp" -vdstamp="$day_stamp" '$7>=nstamp && $5==dstamp' ${ori_log_path} > ${tmp_log_path};
log_num=`cat ${tmp_log_path} | wc -l`;
request_time=`awk '{print $(NF-1)}' ${tmp_log_path} | awk '{sum+=$1}END{print sum}'`;
ave_request_time=`echo | awk "{print ${request_time}/${log_num}}" `;
#ipcounts=$(awk '{print $1}' /home/5min_limbopro.com.access.log | sort -n | uniq | wc -l);
date=$(env LANG=en_US.UTF-8 date "+%e/%b/%Y/%R")
echo "${date}" "网站最近"${imaxtime}"分钟总请求数为 ${log_num}" 次 # >> /home/5minutes.log;
}
function main()
{
define
gather
# output
}
main
## 赋值到最大IP封禁值;
echo -n "输入最低可封杀请求数:"
read max
## 清除上期封禁;
> /home/ip.blacklist.auto.echo.conf #如果不想清除可注释掉
## 新一轮封禁开始;
blockip=/home/ip.blacklist.auto.echo.conf
access=/home/echo_limbopro.com.access.log
for ip in $(awk '{cnt[$1]++;}END{for(i in cnt){printf("%s\t%s\n", cnt[i], i);}}' ${access} | awk '{if($1>'$max') print $2}')
do
echo "deny ${ip};" >> $blockip
echo "deny ${ip};" >> /home/wwwroot/typecho/deny/index.log
done
sleep 1s
## 重启nginx以生效;
lnmp nginx reload
##计算IP封禁数量;
catipblocks=$(nohup wc -l /home/ip.blacklist.auto.echo.conf > /home/ip.blacklist.auto.echo.conf.log);
ipblocks=$(awk '{print $1}' /home/ip.blacklist.auto.echo.conf.log);
> /home/ip.blacklist.auto.echo.conf.log;
echo ""${imaxtime}" 分钟内,符合"${max}"次请求则封禁的 IP 数量为${ipblocks}个;"
echo ""${imaxtime}" 分钟内,符合"${max}"次请求则封禁的 IP 地址如下:"
cat /home/ip.blacklist.auto.echo.conf;
echo ""${imaxtime}" 分钟内,符合"${max}"次请求则封禁的 IP 地址如上:"
echo ""${imaxtime}" 分钟内,符合"${max}"次请求则封禁的 IP 数量为${ipblocks}个;"
## 查看IP访问数量;
ipnumbers=$(awk '{print $1}' ${access} | sort -n | uniq | wc -l)
echo ""${imaxtime}" 分钟内,用户发起请求的 IP 数量为${ipnumbers}个;"
#echo "最受欢迎的3个页面:"
echo -n "查看最受欢迎的页面(输入数字):"
read maxpages;
nohup awk '{print $7}' /home/echo_limbopro.com.access.log | sort |uniq -c | sort -rn | head -n "${maxpages}" >> /home/hotpages.log;
echo ""${imaxtime}" 分钟内,最受欢迎的"${maxpages}"个页面:"
cat /home/hotpages.log
> /home/hotpages.log
## 清楚缓存日志;
#> /home/echo_limbopro.com.access.log
> /home/echo_limbopro.com.access.before.log;
> /home/echo_limbopro.com.access.log;
版权属于:毒奶
联系我们:https://limbopro.com/6.html
毒奶搜索:https://limbopro.com/search.html
毒奶导航:https://limbopro.com/daohang/index.html本文链接:https://limbopro.com/archives/1935.html
本文采用 CC BY-NC-SA 4.0 许可协议,转载或引用本文时请遵守许可协议,注明出处、不得用于商业用途!