2024年8月

404攻击,就是不存在的文件攻击了。攻击者大量的向服务器请求不存在的每次都不相同的链接,cdn/waf将会将所有的请求回源,因为cdn并没有此请求的cache,也无法验证此请求的合法性。404攻击基本可以穿透所有的cdn,当然,也包括cf。
一个404请求无所谓,但是,如果同一时间几千几万个ip并发过来然后每秒10次8次,源服务器也就被回源崩了。(不要对cf等的rate limit有幻想,它只是限制单ip的频率。) 现在的后端系统,比如各php框架和应用,喜欢将所有请求接管,包括404,而不是使用nginx等直接处理,更上雪上加霜。
基于上面的分析,404是无法在cdn层面用普通方式拦截的,所以,必须在源服务器上进行处理,在源服务器还没有被打死前,发现404攻击,然后做出相应对策。在套用cf的前提下,就是直接启用5秒盾,识别不了,就全拦掉,总比挂了好。
下面的代码可以参考:

main.go

这个一个后台进程,它建立一个本地web服务器, http://127.0.0.1:8080/handle_404,如果应用系统接收到404时,就调用此链接。这个进程,它会判断404的频率,在例子中,10秒内超过了100次404,就会激活5秒盾5分钟。
之所以将其单独出来而不是写入应用逻辑,是为了结构和通用性方面的原因。
比如,如果nginx没有特殊设定, 那么可以在nginx的location中,将404错误重写到此链接,而在本博客的typecho中,当捕获到错误时,只需要修改/usr/themes/default/404.php即可:

$url = "http://172.17.0.1:8080/handle_404";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_exec($ch);
curl_close($ch);
?>

好了,这下基本随便404了,超了100/10就5秒盾挡一会,完事。。 当然,我设置的10秒100次其实限制很紧,稍微大些都不是问题,因为404攻击会远远超过这频率,大一点防止误报更好。

呆了10天回来了。
不出意外的腰子还在,顺便再带回来个酷似腰子的山的照片。 。。这是个老梗了,不过我不是金鱼,伤疤我都喜欢时不时的扒一下防止忘了。

图片_20240811123029.jpg

老婆接到hsbc信用卡中心电话说有一笔有疑问的新加坡的付款,问是否本人刷的。我老婆说不是,hsbc于是说会拒付这笔付款然后信用卡被立即冻结并换新卡。我老婆然后告诉我了这件事,还问我oracle是啥。。。我。。。
前几天开放了新区额度,我申请了新区,然后想弄一点费用出来,这样帐号会更稳些。好吧,现在帐单是有了,但是拒付了,疯了。
赶紧去把付款方式改了并重新提交支付,手里没有可用的信用卡了,只能改成paypal,接下来扣了三次并退款,0,1,100新元,希望能过这一关。

1.jpg
2.jpg
3.jpg

以前用了这个从nodeseek上看到的脚本小改后来使用,结果今天不出意外的出了意外。跨月挂了。
分析了下代码,它的进出流量是取的 interface[0].traffic.total.tx和rx,这个是网卡累计总流量。在第一个月的时候是正确的,统计到的总流量就是当月流量嘛。但第二个月,就把前一个月的也包含进来了。
json里其实是应该取 interface[0].traffic.month[n].tx和rx,上面的下标n就是month里最大的那个,因为是按照时间升序排列的,下标最大的一个即为当前月。
修正后代码如下:

#!/bin/bash

# 设置网卡名称
INTERFACE="eth0"

# 设置流量限制(单位:GB)
LIMIT=195

# 获取当前月份的索引
MONTH_INDEX=$(vnstat -i $INTERFACE --json | jq '.interfaces[0].traffic.month | length - 1')

# 获取当月流量数据(单位:KB)
TX=$(vnstat -i $INTERFACE --json | jq --argjson idx "$MONTH_INDEX" '.interfaces[0].traffic.month[$idx].tx')
RX=$(vnstat -i $INTERFACE --json | jq --argjson idx "$MONTH_INDEX" '.interfaces[0].traffic.month[$idx].rx')

# 计算总流量(单位:GB)
GB1=$(echo "scale=2; $TX / 1024 / 1024 / 1024" | bc)
GB2=$(echo "scale=2; $RX / 1024 / 1024 / 1024" | bc)
GB1=$(printf "%.2f" $GB1)
GB2=$(printf "%.2f" $GB2)
echo "Total traffic out: $GB1 GB"
echo "Total traffic in: $GB2 GB"

# 比较并选择较大的流量值(共享带宽包)
if (( $(echo "$GB2 > $GB1" | bc -l) )); then
  GB=$GB2
else
  GB=$GB1
fi

echo "CBWP traffic: $GB GB"

# 检查是否超过流量限制
if (( $(echo "$GB >= $LIMIT" | bc -l) )); then
  echo "Traffic limit exceeded. Disabling network interface."
  ip link set $INTERFACE down
fi

科普下使用方式,时不时有朋友和我说我说得太简略了。。好吧,我假定0基础。
安装必要软件包 apt install bc jq vnstat
设置vnstat开机启动(奇大怪,正常apt install都会做这个,但vnstat似乎没有) systemctl enable vnstat
nano /usr/local/bin/checkcdt.sh 然后输入上面代码,然后 ctrl-x 存盘退出啦,有YES就YES,有默认值就默认值
chmod +x /usr/local/bin/checkcdt.sh
crontab -e 然后选择1,即 nano,如果第一次用的话。 然后在最后加上一行,

*/1 * * * * /usr/local/bin/checkcdt.sh 

,然后ctrl-x退出。 搞定。
它会每分钟检查一次流量,如果到达了195G时就把网卡断了。不说复杂了,下个月的时候重启下机器就活过来了。