主理人说

首先先明确下会用到的一些授权,包括你的Cloudflare注册邮箱,key(即API keys),zoneid等;

Cloudflare zoneid.jpg

Cloudflare keys.jpg

大家可以在脚本前面进行赋值;

#!/bin/bash
CFEMAIL="填写你的Cloudflare注册邮箱" #
CFAPIKEY="填写你的API Key" #
ZONEID="填写你的ZONEID" #
...

另外,脚本做好后可以使用 crontab 进行自动化执行脚本;

Security Level API 用法

Security Level.png

可使用该API调整防御等级

Required parameters

Name /type Description /example Constraints
value string Value of the zone setting"medium" default value: mediumvalid values: off, essentially_off, low, medium, high, under_attack

cURL (example) 用法举例

curl -X PATCH "https://api.cloudflare.com/client/v4/zones/${ZONEID}/settings/security_level" \
     -H "X-Auth-Email: ${CFEMAIL}" \
     -H "X-Auth-Key: ${CFAPIKEY}" \
     -H "Content-Type: application/json" \
     --data '{"value":"medium"}'

以上举例即将Cloudflare的防御等级调整至medium;非付费用户不可修改为off,Free 用户支持的防御等级模式包括:

default value: medium
valid values: off, essentially_off, low, medium, high, under_attack

大家按需修改即可,完整脚本示例如下:(开启under_attack防御等级)

#!/bin/bash
CFEMAIL="填写你的Cloudflare注册邮箱"
CFAPIKEY="填写你的API Key"
ZONEID="填写你的ZONEID"

curl -X PATCH "https://api.cloudflare.com/client/v4/zones/${ZONEID}/settings/security_level" \
     -H "X-Auth-Email: ${CFEMAIL}" \
     -H "X-Auth-Key: ${CFAPIKEY}" \
     -H "Content-Type: application/json" \
     --data '{"value":"under_attack"}'

防御思路

这个API的用法在于,网站在遭受攻击的时候可以自动开启相应防御等级,正常情况下使用低验证等级例如essentially_off,可以减少正常用户要过验证码的麻烦;

如何判断网站的负载情况呢?

1.CPU持续负载情况
2.网站的连通状态
3.TCP链接数

1.CPU持续负载情况

#!/bin/bash
function GetSysCPU 
{
CpuIdle=`vmstat 1 5 |sed -n '3,$p' | awk '{x = x + $15} END {print x/5}' | awk -F. '{print $1}'` 
CpuNum=`echo "100-$CpuIdle" | bc` 
echo $CpuNum 
} 
CPU=`GetSysCPU` #将得到的赋值给CPU
CPUMAX=80 #设定最大警报值即触发脚本阈值

if [ ${CPU} -ge $CPUMAX ];
then
脚本A... #如果超出阈值则执行该操作
else
脚本B... #如果未超出阈值则执行该操作
fi

供参考,我的是每分钟进行一次CPU值判定,如果超出阈值则记录到log日志否则丢弃,持续3分钟,如果日志出现两次记录,则触发提前设置好的脚本,将Cloudflare的防御等级调整至最高:under_attack

2.网站的连通状态

$ curl -I -m 10 -o /dev/null -s -w %{http_code} https://limbopro.xyz

该段命令将会返回网站的状态码,正常可连通则会返回响应代码200,如果nginx关闭则会返回响应代码521,如果你php-fpm炸了则会返回响应代码502;关于响应代码是什么可查阅:HTTP 响应代码

完整示例:

#!/bin/bash
correct=200
status=$(curl -I -m 10 -o /dev/null -s -w %{http_code} https://limbopro.xyz)
if [ ${status} -eq ${status} ]; #如果响应代码为200
then #则执行
脚本A
else #否则执行
脚本B
重启lnmp服务
fi

3.TCP链接数

$ netstat -na|grep ESTABLISHED|wc -l

该脚本可以查看当前外部IP与服务器的链接数(连接状态为ESTABLISHED的连接数量,即已建立连接的状态),其他状态还有TIME_WAIT等等,可查阅:服务端端口状态解释

完整示例:

clientstatus=$(netstat -na|grep ESTABLISHED|wc -l)
max=500
if [ $clientstatus -gt $max ]; #如果连接数大于500
then #则执行
脚本A
else #否则执行
脚本B
fi

按日常的访问量来算,这个max的值可以设置的为正常值的2-5倍;
关于netstat的使用方法,大家也可进行深入了解一下:netstat命令丨服务器使用知识储备

以上。

User-level Firewall Access Rule

User-level Firewall Access Rule .jpg

该API可以说是个宝藏了,可以对指定IP/ASN/IP段/国家/进行相应操作:Block/Challenge/JavaScript/Whitelist;
相应操作的解释如下:

Block: Ensures that an IP address will never be allowed to access your website
Challenge: Specified IP addresses will be shown a CAPTCHA before being allowed to access your website
JavaScript Challenge: The JavaScript challenge page requires the visitor to wait 5 seconds while Cloudflare determines if the visitor is coming from a real browser. The challenge requires the visitor's browser to answer a math problem which takes a bit of time to compute. Once successfully answered, the browser will be remembered and won't be challenged again.
Whitelist: Ensures that an IP address will never be blocked from accessing your website. The IP may still be mitigated if part of a DDoS attack. Only use for verified IPs that you trust!

可以说很秀了,例如可以直接设定某个国家的所有IP,Block;不可访问本站;

如上图,官方很小气,该API并没有在Dash中Firewall模块中显示;参考官方文档:User-level Firewall Access Rule

以下,是官方文档:

Name /type Description /example Constraints
mode string The action to apply to a matched request"challenge" valid values: block, challenge, whitelist, js_challenge
notes string A personal note about the rule. Typically used as a reminder or explanation for the rule."This rule is on because of an event that occured on date X"

cURL (example) 用法举例

curl -X PATCH "https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules/92f17202ed8bd63d69a66b86a49a8f6b" \
     -H "X-Auth-Email: [email protected]" \
     -H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \
     -H "Content-Type: application/json" \
     --data '{"mode":"challenge","notes":"This rule is on because of an event that occured on date X"}'

完整示例:(for 循环脚本,批量提交异常IP表,在此感谢原脚本作者:https://www.9sep.org/

#!/bin/bash
PADDR=$(</home/cf.conf) #cf.conf 里面每行一个IP地址
for IPADDR in ${IPADDR[@]}; do
echo $IPADDR

url -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":"limbo-auto-block"}'
done

防御思路

1.从nginx日志中提取异常IP并存入指定文本
2.利用该脚本批量提交异常IP

Firewall Rules API

Firewall Rules.jpg

参考官方文档;该API可以干嘛?

Control incoming traffic to your zone by filtering requests based on location, IP address, user agent, URI, and more. 

控制进站流量,基于IP地址/用户代理还有更多过滤请求;User-Agent 是什么可参考:User-Agent,目前我有设置两条防火墙规则:

1.允许机器人访问本站,毕竟要做SEO;
2.路径保护以及请求方法保护(默认情况下关闭);参与:HTTP 请求方法,包括但不限于get/head/post...

一般我们拉取网站页面资源用到的是get,如果你有查看过nginx日志,则会看到该请求方法以及发文章的时候看到post;

获取当前防火墙规则:(如果你设置了防火墙规则,可使用curl方法)

curl -X GET "https://api.cloudflare.com/client/v4/zones/${ZONESID}/firewall/rules" \
     -H "X-Auth-Email: ${CFEMAIL}" \
     -H "X-Auth-Key: ${CFAPIKEY}" \
     -H "Content-Type: application/json"

返回值

...
{
"id": "kks26bf85cc64113b76d2c0d8716c7dy", #防火墙规则ID
"paused": true, #该防火墙规则暂停状态为TRUE,即该防火墙暂停使用
"description": "Path Protect", #该防火墙名字
"action": "block", #执行动作为 block 
"filter": {
"id": "c7af9dbbeb6950ba9cg0e4bc432b2ae7", #匹配条件ID
"expression": "(http.request.method ne \"GET\")", #匹配条件,这里是指请求方法非get的请求均block
"paused": false #使用中
}
...

防御思路

我们可以提前设置好防火墙规则,在遭遇DDoS时开启;如何判定是否遭遇DDoS攻击可以参考本文前文;

完整示例:

#!/bin/bash
CFEMAIL="填写你的Cloudflare注册邮箱"
CFAPIKEY="填写你的API Key"
ZONEID="填写你的ZONEID"

#激活防火墙规则

curl -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONESID}/firewall/rules" \
     -H "X-Auth-Email: ${CFEMAIL}" \
     -H "X-Auth-Key: ${CFAPIKEY}" \
     -H "Content-Type: application/json" \
     --data '[{"id":"kks26bf85cc64113b76d2c0d8716c7dy","filter":{"id":"c7af9dbbeb6950ba9cg0e4bc432b2ae7","expression": "(http.request.method ne \"GET\")","paused":false},"action":"block","paused":false,"description":"Path Protect"}]'

以上。

最后修改:2020 年 03 月 19 日 08 : 07 PM