Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
unidocs-unicloud-zh
提交
fb3ce2e4
U
unidocs-unicloud-zh
项目概览
DCloud
/
unidocs-unicloud-zh
通知
90
Star
2
Fork
21
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
2
列表
看板
标记
里程碑
合并请求
9
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
unidocs-unicloud-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
2
Issue
2
列表
看板
标记
里程碑
合并请求
9
合并请求
9
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
fb3ce2e4
编写于
5月 13, 2024
作者:
VK1688
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
update: ext-storage\dev.md
上级
cf226f42
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
255 addition
and
1 deletion
+255
-1
docs/ext-storage/dev.md
docs/ext-storage/dev.md
+255
-1
未找到文件。
docs/ext-storage/dev.md
浏览文件 @
fb3ce2e4
...
...
@@ -2199,13 +2199,267 @@ https://web-ext-storage.dcloud.net.cn/unicloud/ext-storage/gogopher.png?qrcode
申请方式:在
[
扩展存储技术交流群
](
https://im.dcloud.net.cn/#/?joinGroup=65436862cc41b0763842cfc9
)
里发送内容,我想申请七牛云CDN额外防御:同一个IP在10分钟内,同一个域名下载文件次数超过200次,封禁该IP 1小时,1小时后自动解封
### CDN流量监控告警(需自己部署,
即将
提供云函数定时任务模板)@cdnsecurewarn
### CDN流量监控告警(需自己部署,
已
提供云函数定时任务模板)@cdnsecurewarn
1.
单个IP 每日流量阈值告警(单位:GB)
2.
单个IP 每日访问次数阈值告警(单位:次)
提示:通过
`getDomains`
和
`getCdnTop`
这两个API,结合云函数定时任务可以自己实现CDN流量监控告警功能,该告警功能的定时任务代码模板预计2024年5月17日之前发布
#### 监控告警云函数模板@cdnsecurewarntemplate
**安装教程**
1.
新建一个云函数(注意选云函数,非云对象),名为:
`ext-storage-cron`
![](
https://web-ext-storage.dcloud.net.cn/unicloud/ext-storage/1715603185670vbsdmt4h2j.png
)
2.
将下方代码复制到新建的云函数中
```
js
'
use strict
'
;
const
uniCloudExtStorage
=
require
(
"
uni-cloud-ext-storage
"
);
const
config
=
{
frequency
:
0
,
// 执行频率,单位:分钟,可选值:0、15、30、60(只能是这4个值的其中一个,设置为0也代表每15分钟执行一次)
traffic
:
10
,
// 单个IP 每日流量阈值(单位:GB)如果设置为0代表不限制
count
:
1000000
,
// 单个IP 每日访问次数阈值(单位:次)如果设置为0代表不限制
sms
:
{
appid
:
"
__UNI__XXXXXXX
"
,
// 修改成你的manifest.json里的appid
phone
:
"
15200000001
"
,
// 修改成你自己的手机号
templateId
:
"
uni_cdn_warn
"
,
// 无需修改,当然也可以改成你自己的短信模板id(uni_cdn_warn为公共短信模板id,无需申请即可使用,发送频率限制为10分钟内最大1次)
},
db
:
{
sendLog
:
"
opendb-open-data
"
,
// 无需修改,当然也可以改成你自己的数据表名称
}
};
/**
* 发送告警信息函数,目前用的是发送短信,你也可以自己更改为发送邮件、微信公众号模板消息等其他方式
* @param {Object} list 告警列表
* @param {Object} requestId 本次定时任务的请求id(方便在云函数那查询日志)
*/
async
function
sendWarn
(
list
,
requestId
)
{
console
.
log
(
"
准备发送告警信息
"
);
for
(
let
i
=
0
;
i
<
list
.
length
;
i
++
)
{
console
.
log
(
`正在发送告警信息,当前进度
${
i
+
1
}
/
${
list
.
length
}
`
);
let
{
type
,
// 告警类型 traffic 流量 count 访问次数
domain
,
// 域名
ip
,
// IP
traffic
,
// 流量(单位:GB)
count
,
// 访问次数(单位:次)
}
=
list
[
i
];
let
logInfo
=
await
getSendLog
({
ip
});
// 同一个IP在24小时内只发送一次告警信息
if
(
logInfo
&&
logInfo
.
value
&&
logInfo
.
value
.
send_time
&&
Date
.
now
()
<
(
logInfo
.
value
.
send_time
+
24
*
3600
*
1000
))
{
console
.
log
(
"
该IP 24小时内已经发送过告警信息,不再发送
"
);
continue
;
}
try
{
let
sendSmsRes
=
await
uniCloud
.
sendSms
({
...
config
.
sms
,
data
:
{}
});
console
.
log
(
'
sendSmsRes:
'
,
sendSmsRes
);
if
(
sendSmsRes
.
errCode
===
0
)
{
// 发送成功,记录该IP的发送时间
await
setSendLog
({
type
,
domain
,
ip
,
traffic
,
count
,
});
}
}
catch
(
err
)
{
// 调用失败
console
.
log
(
"
发送短信失败:
"
,
err
)
}
}
}
// 以上代码可以修改-----------------------------------------------------------
// 以下代码无需修改-----------------------------------------------------------
// 查询发送告警信息的时间
async
function
getSendLog
(
data
)
{
try
{
let
{
ip
,
// IP
}
=
data
;
const
db
=
uniCloud
.
database
();
let
nowTime
=
Date
.
now
();
let
dbRes
=
await
db
.
collection
(
config
.
db
.
sendLog
).
doc
(
`ext-storage-warn:
${
ip
}
`
).
get
();
return
dbRes
.
data
[
0
];
}
catch
(
err
)
{
console
.
error
(
'
err:
'
,
err
)
return
;
}
}
// 记录发送告警信息的时间
async
function
setSendLog
(
data
)
{
try
{
let
{
type
,
// 告警类型 traffic 流量 count 访问次数
domain
,
// 域名
ip
,
// IP
traffic
,
// 流量(单位:GB)
count
,
// 访问次数(单位:次)
}
=
data
;
const
db
=
uniCloud
.
database
();
let
nowTime
=
Date
.
now
();
let
logInfo
=
await
getSendLog
({
ip
});
if
(
!
logInfo
)
{
logInfo
=
{
value
:
{
type
,
domain
,
ip
,
traffic
,
count
,
send_count
:
0
,
},
expired
:
0
}
}
logInfo
.
value
.
send_time
=
nowTime
;
if
(
!
logInfo
.
value
.
send_count
)
logInfo
.
value
.
send_count
=
0
;
logInfo
.
value
.
send_count
++
;
// 记录该IP历史累加发送次数
delete
logInfo
.
_id
;
// 1个IP只会存在一条记录
return
await
db
.
collection
(
config
.
db
.
sendLog
).
doc
(
`ext-storage-warn:
${
ip
}
`
).
set
(
logInfo
);
}
catch
(
err
)
{
console
.
error
(
'
err:
'
,
err
)
return
;
}
}
// 查询今日CDN流量top100
const
extStorageManager
=
uniCloud
.
getExtStorageManager
({
provider
:
"
qiniu
"
,
// 扩展存储供应商
domain
:
"
https://www.domain.com
"
,
// 此处的域名无需更改
});
exports
.
main
=
async
(
event
,
context
)
=>
{
let
res
=
{};
let
nowTime
=
Date
.
now
();
// 获取当前分钟数
let
minute
=
new
Date
(
nowTime
).
getMinutes
();
if
(
!
config
)
{
throw
new
Error
(
`未找到相关配置信息`
);
}
if
(
config
.
frequency
>
0
&&
minute
%
config
.
frequency
!==
0
)
{
console
.
log
(
"
未到执行时间
"
);
return
"
未到执行时间
"
;
}
// 时区8小时
let
offset
=
8
*
3600
*
1000
;
let
startDate
=
new
Date
(
nowTime
+
offset
).
toISOString
().
split
(
"
T
"
)[
0
];
let
endDate
=
new
Date
(
nowTime
+
offset
).
toISOString
().
split
(
"
T
"
)[
0
];
// 获取我绑定的域名列表
let
{
domains
=
[]
}
=
await
extStorageManager
.
getDomains
();
// 循环domains数组,查询每个域名的CDN流量top100
console
.
log
(
`当前查询日期:
${
startDate
}
`
)
let
warnList
=
[];
for
(
let
i
=
0
;
i
<
domains
.
length
;
i
++
)
{
let
domain
=
domains
[
i
];
console
.
log
(
`正在查询域名:
${
domain
}
,当前进度
${
i
+
1
}
/
${
domains
.
length
}
`
);
let
getCdnTopRes
=
await
getCdnTop
({
domain
,
startDate
,
endDate
,
requestId
:
context
.
request_id
});
warnList
=
warnList
.
concat
(
getCdnTopRes
);
}
let
warnListStr
=
warnList
.
map
(
item
=>
`
${
item
.
domain
}
(
${
item
.
ip
}
:
${
item
.
traffic
}
GB :
${
item
.
count
}
次)`
).
join
(
"
、
"
);
let
msg
=
`共查询了
${
domains
.
length
}
个域名,触发告警的IP有
${
warnList
.
length
}
个`
;
if
(
warnList
.
length
>
0
)
{
msg
+=
`,分别是:
${
warnListStr
}
`
;
}
console
.
log
(
'
执行完毕:
'
,
msg
);
res
.
msg
=
msg
;
return
res
;
};
async
function
getCdnTop
(
data
=
{})
{
let
{
domain
,
startDate
,
endDate
,
requestId
}
=
data
;
let
getCdnTopRes
=
await
extStorageManager
.
getCdnTop
({
type
:
2
,
// 1 topURL 2 topIP
domains
:
[
domain
],
startDate
,
endDate
});
let
list
=
getCdnTopRes
.
data
;
//console.log('list: ', list)
let
warnList
=
[];
for
(
let
i
=
0
;
i
<
list
.
length
;
i
++
)
{
let
item
=
list
[
i
];
let
traffic
=
parseFloat
((
item
.
traffic
/
1024
/
1024
/
1024
).
toFixed
(
2
));
// 流量(单位:GB)
let
count
=
item
.
count
;
// 访问次数(单位:次)
if
(
config
.
traffic
>
0
&&
traffic
>=
config
.
traffic
)
{
// 流量告警
console
.
log
(
`域名
${
domain
}
触发流量告警,告警IP为:
${
item
.
ip
}
`
)
warnList
.
push
({
type
:
"
traffic
"
,
domain
,
ip
:
item
.
ip
,
traffic
,
count
})
}
else
if
(
config
.
count
>
0
&&
count
>=
config
.
count
)
{
// 访问次数告警
console
.
log
(
`域名
${
domain
}
触发访问次数告警,告警IP为:
${
item
.
ip
}
`
)
warnList
.
push
({
type
:
"
count
"
,
domain
,
ip
:
item
.
ip
,
traffic
,
count
})
}
}
if
(
warnList
.
length
>
0
)
{
await
sendWarn
(
warnList
,
requestId
);
}
return
warnList
;
}
```
3.
修改上面的配置信息
4.
修改云函数的package.json文件,替换代码如下
```
js
{
"
name
"
:
"
ext-storage-cron
"
,
"
extensions
"
:
{
"
uni-cloud-sms
"
:
{},
"
uni-cloud-ext-storage
"
:
{}
},
"
cloudfunction-config
"
:
{
"
concurrency
"
:
1
,
"
memorySize
"
:
512
,
"
path
"
:
""
,
"
timeout
"
:
600
,
"
triggers
"
:
[
{
"
name
"
:
"
ext-storage-cron
"
,
"
type
"
:
"
timer
"
,
"
config
"
:
"
0 */15 * * * * *
"
}
],
"
runtime
"
:
"
Nodejs16
"
}
}
```
5.
上传云函数
`ext-storage-cron`
,完成
![](
https://web-ext-storage.dcloud.net.cn/unicloud/ext-storage/17156030587837l8qksr5hf.png
)
## 常见问题@question
### 运行报错,当前空间不支持provider:"qiniu"@q1
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录